From b3e6d2ded0e78e6b76c7fbbdc2d3f9fdd1312df4 Mon Sep 17 00:00:00 2001 From: mertmit Date: Thu, 27 Jun 2024 14:13:21 +0300 Subject: [PATCH] fix: replace long base ids with new ones before migration Signed-off-by: mertmit --- .../migrations/v2/nc_050_tenant_isolation.ts | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/packages/nocodb/src/meta/migrations/v2/nc_050_tenant_isolation.ts b/packages/nocodb/src/meta/migrations/v2/nc_050_tenant_isolation.ts index 270bfe174e..0aa0e85c81 100644 --- a/packages/nocodb/src/meta/migrations/v2/nc_050_tenant_isolation.ts +++ b/packages/nocodb/src/meta/migrations/v2/nc_050_tenant_isolation.ts @@ -1,3 +1,4 @@ +import { customAlphabet } from 'nanoid'; import type { Knex } from 'knex'; import { MetaTable } from '~/utils/globals'; @@ -178,9 +179,121 @@ const listIndexesOnColumn = async ( } }; +// Replace long base_id with new unique base_id + +const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14); + +const generateUniqueBaseId = async (knex: Knex) => { + const baseId = `p${nanoidv2()}`; + + const base = await knex(MetaTable.PROJECT).where('id', baseId).first(); + + if (base) { + return generateUniqueBaseId(knex); + } + + return baseId; +}; + +const listBasesWithLongIds = async (knex: Knex) => { + const sourceType = knex.client.driverName; + + switch (sourceType) { + case 'pg': { + const bases = await knex.raw( + `SELECT id FROM ?? WHERE LENGTH(id) > 20`, + MetaTable.PROJECT, + ); + + return bases.rows.map((row: any) => row.id); + } + case 'mysql': + case 'mysql2': { + const bases = await knex.raw( + `SELECT id FROM ?? WHERE CHAR_LENGTH(id) > 20`, + MetaTable.PROJECT, + ); + + return bases[0].map((row: any) => row.id); + } + case 'sqlite3': { + const bases = await knex.raw( + `SELECT id FROM ?? WHERE LENGTH(id) > 20`, + MetaTable.PROJECT, + ); + + return bases.map((row: any) => row.id); + } + case 'mssql': { + const bases = await knex.raw( + `SELECT id FROM ?? WHERE LEN(id) > 20`, + MetaTable.PROJECT, + ); + + return bases.map((row: any) => row.id); + } + + default: + throw new Error(`Unsupported database: ${sourceType}`); + } +}; + const up = async (knex: Knex) => { log('Migration started'); + log('Replacing long base_ids with new unique base_id'); + + const basesWithLongIds = await listBasesWithLongIds(knex); + + for (const baseId of basesWithLongIds) { + const newBaseId = await generateUniqueBaseId(knex); + + if (!baseId || !newBaseId) { + throw new Error('Failed to replace long base_id'); + } + + const tablesToChangeBaseId = [ + MetaTable.API_TOKENS, + MetaTable.AUDIT, + MetaTable.PROJECT_USERS, + MetaTable.CALENDAR_VIEW_COLUMNS, + MetaTable.CALENDAR_VIEW, + MetaTable.COLUMNS, + MetaTable.COMMENTS_REACTIONS, + MetaTable.COMMENTS, + MetaTable.MODEL_ROLE_VISIBILITY, + MetaTable.EXTENSIONS, + MetaTable.FILTER_EXP, + MetaTable.FORM_VIEW_COLUMNS, + MetaTable.FORM_VIEW, + MetaTable.GALLERY_VIEW_COLUMNS, + MetaTable.GALLERY_VIEW, + MetaTable.GRID_VIEW_COLUMNS, + MetaTable.GRID_VIEW, + MetaTable.HOOK_LOGS, + MetaTable.HOOKS, + MetaTable.KANBAN_VIEW_COLUMNS, + MetaTable.KANBAN_VIEW, + MetaTable.MAP_VIEW_COLUMNS, + MetaTable.MAP_VIEW, + MetaTable.MODELS, + MetaTable.SORT, + MetaTable.BASES, + MetaTable.SYNC_LOGS, + MetaTable.SYNC_SOURCE, + MetaTable.USER_COMMENTS_NOTIFICATIONS_PREFERENCE, + MetaTable.VIEWS, + ]; + + log(`Replacing base_id ${baseId} with ${newBaseId}`); + + for (const table of tablesToChangeBaseId) { + await knex(table).where('base_id', baseId).update({ base_id: newBaseId }); + } + + await knex(MetaTable.PROJECT).where('id', baseId).update({ id: newBaseId }); + } + log('Adding missing base_id columns'); const addBaseId = [