diff --git a/packages/core/database/src/sync-runner.ts b/packages/core/database/src/sync-runner.ts index a856eeba9e..fb0f1faab9 100644 --- a/packages/core/database/src/sync-runner.ts +++ b/packages/core/database/src/sync-runner.ts @@ -76,7 +76,6 @@ export class SyncRunner { try { const beforeColumns = await this.queryInterface.describeTable(this.tableName, options); - await this.checkAutoIncrementField(beforeColumns, options); await this.handlePrimaryKeyBeforeSync(beforeColumns, options); await this.handleUniqueFieldBeforeSync(beforeColumns, options); } catch (e) { @@ -95,20 +94,6 @@ export class SyncRunner { return syncResult; } - async checkAutoIncrementField(beforeColumns, options) { - // if there is auto increment field, throw error - if (!this.database.isMySQLCompatibleDialect()) { - return; - } - const autoIncrFields = Object.keys(this.rawAttributes).filter((key) => { - return this.rawAttributes[key].autoIncrement; - }); - - if (autoIncrFields.length > 1) { - throw new Error(`Auto increment field can't be more than one: ${autoIncrFields.join(', ')}`); - } - } - async handleUniqueFieldBeforeSync(beforeColumns, options) { if (!this.database.inDialect('sqlite')) { return; diff --git a/packages/plugins/@nocobase/plugin-data-source-main/src/server/hooks/beforeCreateCheckFieldInMySQL.ts b/packages/plugins/@nocobase/plugin-data-source-main/src/server/hooks/beforeCreateCheckFieldInMySQL.ts new file mode 100644 index 0000000000..0c0fd512da --- /dev/null +++ b/packages/plugins/@nocobase/plugin-data-source-main/src/server/hooks/beforeCreateCheckFieldInMySQL.ts @@ -0,0 +1,44 @@ +/** + * 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. + */ + +export function beforeCreateCheckFieldInMySQL(db) { + return async (model, { transaction }) => { + if (!db.isMySQLCompatibleDialect()) { + return; + } + + const fieldOptions = model.get(); + if (fieldOptions.autoIncrement) { + const collection = db.getCollection(fieldOptions.collectionName); + + if (!collection) { + return; + } + + const rawAttributes = collection.model.rawAttributes; + + const fields = Object.keys(rawAttributes); + + for (const key of fields) { + if (key === fieldOptions.name) { + continue; + } + + const field = rawAttributes[key]; + if (field.autoIncrement) { + throw new Error( + `Can not add field ${ + fieldOptions.name + }, autoIncrement field ${key} is already in a table ${collection.getTableNameWithSchemaAsString()}`, + ); + } + } + } + }; +} diff --git a/packages/plugins/@nocobase/plugin-data-source-main/src/server/server.ts b/packages/plugins/@nocobase/plugin-data-source-main/src/server/server.ts index ab3a0f6d17..bcd7320ab2 100644 --- a/packages/plugins/@nocobase/plugin-data-source-main/src/server/server.ts +++ b/packages/plugins/@nocobase/plugin-data-source-main/src/server/server.ts @@ -30,6 +30,7 @@ import viewResourcer from './resourcers/views'; import { FieldNameExistsError } from './errors/field-name-exists-error'; import { beforeDestoryField } from './hooks/beforeDestoryField'; import { FieldIsDependedOnByOtherError } from './errors/field-is-depended-on-by-other'; +import { beforeCreateCheckFieldInMySQL } from './hooks/beforeCreateCheckFieldInMySQL'; export class PluginDataSourceMainServer extends Plugin { public schema: string; @@ -115,6 +116,8 @@ export class PluginDataSourceMainServer extends Plugin { }); // 要在 beforeInitOptions 之前处理 + this.app.db.on('fields.beforeCreate', beforeCreateCheckFieldInMySQL(this.app.db)); + this.app.db.on('fields.beforeCreate', beforeCreateForReverseField(this.app.db)); this.app.db.on('fields.beforeCreate', async (model, options) => {