fix(plugin-workflow-manaul): fix migration (#6478)

* fix(plugin-workflow-manaul): fix migration

* fix(plugin-workflow-manaul): fix migration
This commit is contained in:
Junyi 2025-03-17 01:05:26 +08:00 committed by GitHub
parent a2b34a1b44
commit ec618b06c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 153 additions and 37 deletions

View File

@ -52,6 +52,11 @@ function matrixTest() {
}); });
expect(r2).toBeTruthy(); expect(r2).toBeTruthy();
const oldTableExists = await app.db.sequelize
.getQueryInterface()
.tableExists(oldCollection.getTableNameWithSchema());
expect(oldTableExists).toBe(false);
await app.destroy(); await app.destroy();
}); });
} }
@ -80,6 +85,11 @@ describe('20250225175712-change-table-name.test', () => {
}); });
expect(r2).toBeTruthy(); expect(r2).toBeTruthy();
const oldTableExists = await app.db.sequelize
.getQueryInterface()
.tableExists(oldCollection.getTableNameWithSchema());
expect(oldTableExists).toBe(false);
await app.destroy(); await app.destroy();
}); });

View File

@ -0,0 +1,66 @@
/**
* 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 } from '@nocobase/test';
import { describe, test } from 'vitest';
import workflowManualTasks from '../../collections/workflowManualTasks';
import Migration from '../../migrations/20250316181621-remove-m2m-fields';
describe('20250225175712-change-table-name.test', () => {
test(`old table and fields should not exist after migrated with fields removed`, async () => {
const app = await createMockServer();
await app.version.update('1.5.0');
const fieldCollection = app.db.collection({
name: 'fields',
fields: [
{
name: 'collectionName',
type: 'string',
},
{
name: 'name',
type: 'string',
},
],
});
const oldCollection = app.db.collection({
...workflowManualTasks,
name: 'users_jobs',
});
await app.db.sync();
const migration = new Migration({ db: app.db, app } as any);
await migration.up();
const oldTableExists = await app.db.sequelize
.getQueryInterface()
.tableExists(oldCollection.getTableNameWithSchema());
expect(oldTableExists).toBe(false);
const f1 = await fieldCollection.repository.find({
filter: {
collectionName: 'users',
name: ['jobs', 'usersJobs'],
},
});
expect(f1.length).toBe(0);
const f2 = await fieldCollection.repository.find({
filter: {
collectionName: 'jobs',
name: ['users', 'usersJobs'],
},
});
expect(f2.length).toBe(0);
await app.destroy();
});
});

View File

@ -24,6 +24,7 @@ export default class extends Migration {
const workflowManualTasksCollection = db.collection({ const workflowManualTasksCollection = db.collection({
...workflowManualTasks, ...workflowManualTasks,
}); });
const oldTableName = usersJobsCollection.getTableNameWithSchema(); const oldTableName = usersJobsCollection.getTableNameWithSchema();
const oldTableNameWithQuotes = usersJobsCollection.getRealTableName(true); const oldTableNameWithQuotes = usersJobsCollection.getRealTableName(true);
const newTableName = workflowManualTasksCollection.getTableNameWithSchema(); const newTableName = workflowManualTasksCollection.getTableNameWithSchema();
@ -33,6 +34,7 @@ export default class extends Migration {
if (!exists) { if (!exists) {
return; return;
} }
const oldColumns = await queryInterface.describeTable(oldTableName);
// @ts-ignore // @ts-ignore
const constraints: any = await queryInterface.showConstraint(oldTableName); const constraints: any = await queryInterface.showConstraint(oldTableName);
// PG: // PG:
@ -64,7 +66,14 @@ export default class extends Migration {
async (transaction) => { async (transaction) => {
const newExists = await queryInterface.tableExists(newTableName, { transaction }); const newExists = await queryInterface.tableExists(newTableName, { transaction });
if (newExists) { if (newExists) {
await queryInterface.dropTable(newTableName, { transaction }); // NOTE: old column status exists means not migrated
if (oldColumns.status) {
await queryInterface.dropTable(newTableName, { transaction });
} else {
// NOTE: means this table was synchronized from collectionManager, and should not exists.
await queryInterface.dropTable(oldTableName, { transaction });
return;
}
} }
if (this.db.isPostgresCompatibleDialect()) { if (this.db.isPostgresCompatibleDialect()) {

View File

@ -1,36 +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.7.0';
on = 'afterLoad';
async up() {
const { db } = this.context;
await db.sequelize.transaction(async (transaction) => {
const FieldRepo = db.getCollection('fields').repository;
await FieldRepo.destroy({
filter: {
collectionName: 'users',
name: 'jobs',
},
transaction,
});
await FieldRepo.destroy({
filter: {
collectionName: 'jobs',
name: 'users',
},
transaction,
});
});
}
}

View File

@ -0,0 +1,67 @@
/**
* 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.7.0';
on = 'beforeLoad';
async up() {
const { db } = this.context;
const usersJobsCollection = db.collection({
name: 'users_jobs',
});
const fieldCollection = db.collection({
name: 'fields',
autoGenId: false,
createdAt: false,
updatedAt: false,
filterTargetKey: ['collectionName', 'name'],
fields: [
{
name: 'collectionName',
type: 'string',
},
{
name: 'name',
type: 'string',
},
],
});
const oldTableExists = await db.sequelize
.getQueryInterface()
.tableExists(usersJobsCollection.getTableNameWithSchema());
await db.sequelize.transaction(async (transaction) => {
await fieldCollection.repository.destroy({
filter: {
collectionName: 'users',
name: ['jobs', 'usersJobs'],
},
transaction,
});
await fieldCollection.repository.destroy({
filter: {
collectionName: 'jobs',
name: ['users', 'usersJobs'],
},
transaction,
});
if (oldTableExists) {
await db.sequelize.getQueryInterface().dropTable(usersJobsCollection.getTableNameWithSchema(), { transaction });
}
});
db.removeCollection('fields');
db.removeCollection('users_jobs');
}
}