From ddbb62ed49b035b5320847dc2063c2cb9b0ff909 Mon Sep 17 00:00:00 2001 From: Junyi Date: Wed, 12 Mar 2025 12:51:21 +0800 Subject: [PATCH] fix(plugin-workflow-manual): fix migration (#6425) * fix(plugin-workflow-manual): fix migration * test(plugin-workflow-manual): add test cases for migrations * fix(plugin-workflow-manual): fix test cases * fix(plugin-workflow-manual): add case for new table existing --- .../20250312100512-change-table-name.test.ts | 82 +++++++++++++++++++ .../20250225175712-change-table-name.ts | 48 ----------- .../20250312100512-change-table-name.ts | 79 ++++++++++++++++++ 3 files changed, 161 insertions(+), 48 deletions(-) create mode 100644 packages/plugins/@nocobase/plugin-workflow-manual/src/server/__tests__/migrations/20250312100512-change-table-name.test.ts delete mode 100644 packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250225175712-change-table-name.ts create mode 100644 packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250312100512-change-table-name.ts diff --git a/packages/plugins/@nocobase/plugin-workflow-manual/src/server/__tests__/migrations/20250312100512-change-table-name.test.ts b/packages/plugins/@nocobase/plugin-workflow-manual/src/server/__tests__/migrations/20250312100512-change-table-name.test.ts new file mode 100644 index 0000000000..88f9ea4b17 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow-manual/src/server/__tests__/migrations/20250312100512-change-table-name.test.ts @@ -0,0 +1,82 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { createMockServer, MockServer } from '@nocobase/test'; +import { describe, test } from 'vitest'; +import workflowManualTasks from '../../collections/workflowManualTasks'; +import Migration from '../../migrations/20250312100512-change-table-name'; + +const pgOnly = (schema) => (schema && process.env.DB_DIALECT == 'postgres' ? it : it.skip); + +const matrix: [string, string][] = [ + // schema, tablePrefix + [undefined, undefined], + ['ss', undefined], + [undefined, 'tt_'], + ['ss', 'tt_'], +]; + +function matrixTest() { + for (const [schema, tablePrefix] of matrix) { + pgOnly(schema)(`schema: ${schema}, tablePrefix: ${tablePrefix}`, async () => { + const app = await createMockServer({ + database: { + schema, + tablePrefix, + }, + }); + await app.version.update('1.5.0'); + const oldCollection = app.db.collection({ + ...workflowManualTasks, + name: 'users_jobs', + }); + await app.db.sync(); + const r1 = await oldCollection.repository.create({}); + const migration = new Migration({ db: app.db, app } as any); + await migration.up(); + + const newCollection = app.db.collection({ + ...workflowManualTasks, + }); + const r2 = await newCollection.repository.findOne({ + filterByTk: r1.id, + }); + expect(r2).toBeTruthy(); + + await app.destroy(); + }); + } +} + +describe('20250225175712-change-table-name.test', () => { + matrixTest(); + + test(`new table exists`, async () => { + const app = await createMockServer(); + await app.version.update('1.5.0'); + const oldCollection = app.db.collection({ + ...workflowManualTasks, + name: 'users_jobs', + }); + const newCollection = app.db.collection({ + ...workflowManualTasks, + }); + await app.db.sync(); + const r1 = await oldCollection.repository.create({}); + const migration = new Migration({ db: app.db, app } as any); + await migration.up(); + + const r2 = await newCollection.repository.findOne({ + filterByTk: r1.id, + }); + expect(r2).toBeTruthy(); + + await app.destroy(); + }); +}); diff --git a/packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250225175712-change-table-name.ts b/packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250225175712-change-table-name.ts deleted file mode 100644 index 8d0e6112c1..0000000000 --- a/packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250225175712-change-table-name.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This file is part of the NocoBase (R) project. - * Copyright (c) 2020-2024 NocoBase Co., Ltd. - * Authors: NocoBase Team. - * - * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. - * For more information, please refer to: https://www.nocobase.com/agreement. - */ - -import { Migration } from '@nocobase/server'; - -export default class extends Migration { - appVersion = '<1.6.0'; - on = 'beforeLoad'; - async up() { - const { db } = this.context; - const queryInterface = db.sequelize.getQueryInterface(); - await db.sequelize.transaction(async (transaction) => { - const exists = await queryInterface.tableExists('users_jobs', { transaction }); - if (exists) { - const newTableName = db.options.underscored ? 'workflow_manual_tasks' : 'workflowManualTasks'; - - await queryInterface.renameTable('users_jobs', newTableName, { transaction }); - - const indexes: any = await queryInterface.showIndex(newTableName, { transaction }); - - for (const item of indexes) { - if (item.name.startsWith('users_jobs')) { - if (this.db.isPostgresCompatibleDialect()) { - await db.sequelize.query( - `ALTER INDEX "${item.name}" RENAME TO "${item.name.replace('users_jobs', 'workflow_manual_tasks')}";`, - { transaction }, - ); - } else if (this.db.isMySQLCompatibleDialect()) { - await db.sequelize.query( - `ALTER TABLE ${newTableName} RENAME INDEX ${item.name} TO ${item.name.replace( - 'users_jobs', - 'workflow_manual_tasks', - )};`, - { transaction }, - ); - } - } - } - } - }); - } -} diff --git a/packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250312100512-change-table-name.ts b/packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250312100512-change-table-name.ts new file mode 100644 index 0000000000..47146ab10e --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow-manual/src/server/migrations/20250312100512-change-table-name.ts @@ -0,0 +1,79 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { Migration } from '@nocobase/server'; + +export default class extends Migration { + appVersion = '<1.6.2'; + on = 'beforeLoad'; + async up() { + const { db } = this.context; + const queryInterface = db.sequelize.getQueryInterface(); + const usersJobsCollection = db.collection({ + name: 'users_jobs', + fields: [{ name: 'id', type: 'bigInt' }], + }); + const workflowManualTasksCollection = db.collection({ + name: 'workflowManualTasks', + fields: [{ name: 'id', type: 'bigInt' }], + }); + const oldTableName = usersJobsCollection.getTableNameWithSchema(); + const oldTableNameWithQuotes = usersJobsCollection.getRealTableName(true); + const newTableName = workflowManualTasksCollection.getTableNameWithSchema(); + const newTableNameWithQuotes = workflowManualTasksCollection.getRealTableName(true); + await db.sequelize.transaction(async (transaction) => { + const exists = await queryInterface.tableExists(oldTableName, { transaction }); + if (exists) { + const newExists = await queryInterface.tableExists(newTableName, { transaction }); + if (newExists) { + await queryInterface.dropTable(newTableName, { transaction }); + } + if (this.db.isPostgresCompatibleDialect()) { + await db.sequelize.query( + `ALTER TABLE ${oldTableNameWithQuotes} RENAME TO "${db.options.tablePrefix || ''}${ + db.options.underscored ? 'workflow_manual_tasks' : 'workflowManualTasks' + }";`, + { + transaction, + }, + ); + } else { + await queryInterface.renameTable(oldTableName, newTableName, { transaction }); + } + + const indexes: any = await queryInterface.showIndex(newTableName, { transaction }); + + const oldIndexPrefix = `${db.options.tablePrefix || ''}users_jobs`; + const newIndexPrefix = `${db.options.tablePrefix || ''}workflow_manual_tasks`; + for (const item of indexes) { + if (item.name.startsWith(oldIndexPrefix)) { + if (this.db.isPostgresCompatibleDialect()) { + await db.sequelize.query( + `ALTER INDEX ${db.options.schema ? `"${db.options.schema}".` : ''}"${ + item.name + }" RENAME TO "${item.name.replace(oldIndexPrefix, newIndexPrefix)}";`, + { transaction }, + ); + } else if (this.db.isMySQLCompatibleDialect()) { + await db.sequelize.query( + `ALTER TABLE ${newTableNameWithQuotes} RENAME INDEX ${item.name} TO ${item.name.replace( + oldIndexPrefix, + newIndexPrefix, + )};`, + { transaction }, + ); + } + } + } + } + }); + db.removeCollection('users_jobs'); + db.removeCollection('workflowManualTasks'); + } +}