From 11d0ddcd1493c1382bd9fd5e7c4b2d75b45791e9 Mon Sep 17 00:00:00 2001 From: aaaaaajie Date: Thu, 10 Apr 2025 17:00:24 +0800 Subject: [PATCH] fix: view bind associations destory and find bug for mssql --- packages/core/database/src/collection.ts | 2 +- .../core/database/src/database-utils/index.ts | 1 - packages/core/database/src/database.ts | 9 +++---- packages/core/database/src/index.ts | 1 + .../src/query-interface/query-interface.ts | 11 ++++++++ .../__tests__/view/view-collection.test.ts | 27 +++++++++++++------ 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/packages/core/database/src/collection.ts b/packages/core/database/src/collection.ts index fbbbe40d4f..9e803d9e3d 100644 --- a/packages/core/database/src/collection.ts +++ b/packages/core/database/src/collection.ts @@ -887,7 +887,7 @@ export class Collection< public getTableNameWithSchema() { const tableName = this.model.tableName; - if (this.collectionSchema() && this.db.inDialect('postgres')) { + if (this.collectionSchema()) { return this.db.utils.addSchema(tableName, this.collectionSchema()); } diff --git a/packages/core/database/src/database-utils/index.ts b/packages/core/database/src/database-utils/index.ts index 6b52a7c0e8..1f98cd500b 100644 --- a/packages/core/database/src/database-utils/index.ts +++ b/packages/core/database/src/database-utils/index.ts @@ -14,7 +14,6 @@ export default class DatabaseUtils { constructor(public db: Database) {} addSchema(tableName, schema?) { - if (!this.db.inDialect('postgres')) return tableName; if (this.db.options.schema && !schema) { schema = this.db.options.schema; } diff --git a/packages/core/database/src/database.ts b/packages/core/database/src/database.ts index 0a6e98013a..7c86e3e6fd 100644 --- a/packages/core/database/src/database.ts +++ b/packages/core/database/src/database.ts @@ -27,6 +27,7 @@ import { QueryOptions, Sequelize, SyncOptions, + TableName, Transactionable, Utils, } from 'sequelize'; @@ -775,18 +776,16 @@ export class Database extends EventEmitter implements AsyncEmitter { } if (this.options.schema) { - const tableNames = (await this.sequelize.getQueryInterface().showAllTables()).map((table) => { - return `"${this.options.schema}"."${table}"`; - }); + const tableNames = (await this.sequelize.getQueryInterface().showAllTables()) as TableName[]; const skip = options.skip || []; // @ts-ignore for (const tableName of tableNames) { - if (skip.includes(tableName)) { + if (skip.includes(tableName['tableName'] || tableName)) { continue; } - await this.sequelize.query(`DROP TABLE IF EXISTS ${tableName} CASCADE`); + await this.queryInterface.dropTable({ tableName, options: { cascade: true } }); } return; } diff --git a/packages/core/database/src/index.ts b/packages/core/database/src/index.ts index c8d502a7d8..21cb67bdc7 100644 --- a/packages/core/database/src/index.ts +++ b/packages/core/database/src/index.ts @@ -64,5 +64,6 @@ export { ChangeColumnAction, ChangeColumnOptions, RemoveColumnOptions, + DropTableOptions, } from './query-interface/query-interface'; export { OptionsParser, FieldSortOptions } from './options-parser'; diff --git a/packages/core/database/src/query-interface/query-interface.ts b/packages/core/database/src/query-interface/query-interface.ts index 47e4837236..646aaa17d7 100644 --- a/packages/core/database/src/query-interface/query-interface.ts +++ b/packages/core/database/src/query-interface/query-interface.ts @@ -10,6 +10,7 @@ import { ColumnDescription, ModelStatic, + QueryInterfaceDropTableOptions, QueryInterface as SequelizeQueryInterface, TableName, Transaction, @@ -34,6 +35,11 @@ export interface ChangeColumnOptions { actions: ChangeColumnAction[]; } +export interface DropTableOptions { + tableName?: TableName; + options?: QueryInterfaceDropTableOptions; +} + export const ChangeColumnAction = { ADD: 'add', DROP: 'drop', @@ -189,4 +195,9 @@ export default abstract class QueryInterface { await this.db.sequelize.getQueryInterface().removeColumn(tableName, columnName, sequelizeOptions); await this.afterRemoveColumn(options); } + + public async dropTable(options: DropTableOptions) { + const { tableName, options: sequelizeOptions } = options; + await this.db.sequelize.getQueryInterface().dropTable(tableName, sequelizeOptions); + } } diff --git a/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts b/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts index b03e0866e2..d6ec150229 100644 --- a/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts +++ b/packages/plugins/@nocobase/plugin-data-source-main/src/server/__tests__/view/view-collection.test.ts @@ -39,6 +39,16 @@ describe('view collection', function () { await app.destroy(); }); + function getSchemaName() { + if (db.inDialect('postgres')) { + return 'public'; + } + if (db.inDialect('mssql')) { + return 'dbo'; + } + return undefined; + } + it('should use id field as only primary key', async () => { await collectionRepository.create({ values: { @@ -73,11 +83,11 @@ describe('view collection', function () { .quotedTableName()}`; await db.sequelize.query(createSQL); - + const viewSchema = getSchemaName(); const inferredFields = await ViewFieldInference.inferFields({ db, viewName, - viewSchema: 'public', + viewSchema, }); await collectionRepository.create({ @@ -89,7 +99,7 @@ describe('view collection', function () { { name: 'group_id', type: 'bigInt', primaryKey: true }, { name: 'name', type: 'string' }, ], - schema: db.inDialect('postgres') ? 'public' : undefined, + schema: viewSchema, }, context: {}, }); @@ -123,8 +133,8 @@ describe('view collection', function () { const assoc = User.model.associations.group; const foreignKey = assoc.foreignKey; const foreignField = User.model.rawAttributes[foreignKey].field; - const viewName = `test_view_${uid(6)}`; + await db.sequelize.query(`DROP VIEW IF EXISTS ${viewName}`); const createSQL = `CREATE VIEW ${viewName} AS SELECT id, ${foreignField}, name FROM ${db @@ -132,11 +142,11 @@ describe('view collection', function () { .quotedTableName()}`; await db.sequelize.query(createSQL); - + const viewSchema = getSchemaName(); const inferredFields = await ViewFieldInference.inferFields({ db, viewName, - viewSchema: 'public', + viewSchema, }); if (!db.inDialect('sqlite')) { @@ -149,7 +159,7 @@ describe('view collection', function () { name: viewName, view: true, fields: Object.values(inferredFields), - schema: db.inDialect('postgres') ? 'public' : undefined, + schema: viewSchema, }, context: {}, }); @@ -222,6 +232,7 @@ describe('view collection', function () { `; await db.sequelize.query(viewSQL); + const viewSchema = getSchemaName(); await collectionRepository.create({ values: { @@ -239,7 +250,7 @@ describe('view collection', function () { source: 'posts.user', }, ], - schema: db.inDialect('postgres') ? 'public' : undefined, + schema: viewSchema, }, context: {}, });