|
|
|
@ -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 = [ |
|
|
|
|