fix: view bind associations destory and find bug for mssql

This commit is contained in:
aaaaaajie 2025-04-10 17:00:24 +08:00
parent 03a3d762a8
commit 11d0ddcd14
6 changed files with 36 additions and 15 deletions

View File

@ -887,7 +887,7 @@ export class Collection<
public getTableNameWithSchema() { public getTableNameWithSchema() {
const tableName = this.model.tableName; const tableName = this.model.tableName;
if (this.collectionSchema() && this.db.inDialect('postgres')) { if (this.collectionSchema()) {
return this.db.utils.addSchema(tableName, this.collectionSchema()); return this.db.utils.addSchema(tableName, this.collectionSchema());
} }

View File

@ -14,7 +14,6 @@ export default class DatabaseUtils {
constructor(public db: Database) {} constructor(public db: Database) {}
addSchema(tableName, schema?) { addSchema(tableName, schema?) {
if (!this.db.inDialect('postgres')) return tableName;
if (this.db.options.schema && !schema) { if (this.db.options.schema && !schema) {
schema = this.db.options.schema; schema = this.db.options.schema;
} }

View File

@ -27,6 +27,7 @@ import {
QueryOptions, QueryOptions,
Sequelize, Sequelize,
SyncOptions, SyncOptions,
TableName,
Transactionable, Transactionable,
Utils, Utils,
} from 'sequelize'; } from 'sequelize';
@ -775,18 +776,16 @@ export class Database extends EventEmitter implements AsyncEmitter {
} }
if (this.options.schema) { if (this.options.schema) {
const tableNames = (await this.sequelize.getQueryInterface().showAllTables()).map((table) => { const tableNames = (await this.sequelize.getQueryInterface().showAllTables()) as TableName[];
return `"${this.options.schema}"."${table}"`;
});
const skip = options.skip || []; const skip = options.skip || [];
// @ts-ignore // @ts-ignore
for (const tableName of tableNames) { for (const tableName of tableNames) {
if (skip.includes(tableName)) { if (skip.includes(tableName['tableName'] || tableName)) {
continue; continue;
} }
await this.sequelize.query(`DROP TABLE IF EXISTS ${tableName} CASCADE`); await this.queryInterface.dropTable({ tableName, options: { cascade: true } });
} }
return; return;
} }

View File

@ -64,5 +64,6 @@ export {
ChangeColumnAction, ChangeColumnAction,
ChangeColumnOptions, ChangeColumnOptions,
RemoveColumnOptions, RemoveColumnOptions,
DropTableOptions,
} from './query-interface/query-interface'; } from './query-interface/query-interface';
export { OptionsParser, FieldSortOptions } from './options-parser'; export { OptionsParser, FieldSortOptions } from './options-parser';

View File

@ -10,6 +10,7 @@
import { import {
ColumnDescription, ColumnDescription,
ModelStatic, ModelStatic,
QueryInterfaceDropTableOptions,
QueryInterface as SequelizeQueryInterface, QueryInterface as SequelizeQueryInterface,
TableName, TableName,
Transaction, Transaction,
@ -34,6 +35,11 @@ export interface ChangeColumnOptions {
actions: ChangeColumnAction[]; actions: ChangeColumnAction[];
} }
export interface DropTableOptions {
tableName?: TableName;
options?: QueryInterfaceDropTableOptions;
}
export const ChangeColumnAction = { export const ChangeColumnAction = {
ADD: 'add', ADD: 'add',
DROP: 'drop', DROP: 'drop',
@ -189,4 +195,9 @@ export default abstract class QueryInterface {
await this.db.sequelize.getQueryInterface().removeColumn(tableName, columnName, sequelizeOptions); await this.db.sequelize.getQueryInterface().removeColumn(tableName, columnName, sequelizeOptions);
await this.afterRemoveColumn(options); await this.afterRemoveColumn(options);
} }
public async dropTable(options: DropTableOptions) {
const { tableName, options: sequelizeOptions } = options;
await this.db.sequelize.getQueryInterface().dropTable(tableName, sequelizeOptions);
}
} }

View File

@ -39,6 +39,16 @@ describe('view collection', function () {
await app.destroy(); 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 () => { it('should use id field as only primary key', async () => {
await collectionRepository.create({ await collectionRepository.create({
values: { values: {
@ -73,11 +83,11 @@ describe('view collection', function () {
.quotedTableName()}`; .quotedTableName()}`;
await db.sequelize.query(createSQL); await db.sequelize.query(createSQL);
const viewSchema = getSchemaName();
const inferredFields = await ViewFieldInference.inferFields({ const inferredFields = await ViewFieldInference.inferFields({
db, db,
viewName, viewName,
viewSchema: 'public', viewSchema,
}); });
await collectionRepository.create({ await collectionRepository.create({
@ -89,7 +99,7 @@ describe('view collection', function () {
{ name: 'group_id', type: 'bigInt', primaryKey: true }, { name: 'group_id', type: 'bigInt', primaryKey: true },
{ name: 'name', type: 'string' }, { name: 'name', type: 'string' },
], ],
schema: db.inDialect('postgres') ? 'public' : undefined, schema: viewSchema,
}, },
context: {}, context: {},
}); });
@ -123,8 +133,8 @@ describe('view collection', function () {
const assoc = User.model.associations.group; const assoc = User.model.associations.group;
const foreignKey = assoc.foreignKey; const foreignKey = assoc.foreignKey;
const foreignField = User.model.rawAttributes[foreignKey].field; const foreignField = User.model.rawAttributes[foreignKey].field;
const viewName = `test_view_${uid(6)}`; const viewName = `test_view_${uid(6)}`;
await db.sequelize.query(`DROP VIEW IF EXISTS ${viewName}`); await db.sequelize.query(`DROP VIEW IF EXISTS ${viewName}`);
const createSQL = `CREATE VIEW ${viewName} AS SELECT id, ${foreignField}, name FROM ${db const createSQL = `CREATE VIEW ${viewName} AS SELECT id, ${foreignField}, name FROM ${db
@ -132,11 +142,11 @@ describe('view collection', function () {
.quotedTableName()}`; .quotedTableName()}`;
await db.sequelize.query(createSQL); await db.sequelize.query(createSQL);
const viewSchema = getSchemaName();
const inferredFields = await ViewFieldInference.inferFields({ const inferredFields = await ViewFieldInference.inferFields({
db, db,
viewName, viewName,
viewSchema: 'public', viewSchema,
}); });
if (!db.inDialect('sqlite')) { if (!db.inDialect('sqlite')) {
@ -149,7 +159,7 @@ describe('view collection', function () {
name: viewName, name: viewName,
view: true, view: true,
fields: Object.values(inferredFields), fields: Object.values(inferredFields),
schema: db.inDialect('postgres') ? 'public' : undefined, schema: viewSchema,
}, },
context: {}, context: {},
}); });
@ -222,6 +232,7 @@ describe('view collection', function () {
`; `;
await db.sequelize.query(viewSQL); await db.sequelize.query(viewSQL);
const viewSchema = getSchemaName();
await collectionRepository.create({ await collectionRepository.create({
values: { values: {
@ -239,7 +250,7 @@ describe('view collection', function () {
source: 'posts.user', source: 'posts.user',
}, },
], ],
schema: db.inDialect('postgres') ? 'public' : undefined, schema: viewSchema,
}, },
context: {}, context: {},
}); });