refactor: optimze view

This commit is contained in:
aaaaaajie 2025-04-11 09:45:44 +08:00
parent 11d0ddcd14
commit 376d411918
7 changed files with 66 additions and 33 deletions

View File

@ -343,6 +343,14 @@ export class Database extends EventEmitter implements AsyncEmitter {
return this._instanceId;
}
get dialectClass() {
return Database.getDialect(this.options.dialect);
}
get schema() {
return this.options.schema || this.dialectClass.getQueryInterface(this).defaultSchemaName;
}
/**
* @internal
*/

View File

@ -290,7 +290,7 @@ export class EagerLoadingTree {
}
// find all ids
const ids = (await node.model.findAll()).map((row) => {
const ids = (await node.model.findAll(options)).map((row) => {
return { row, pk: row[primaryKeyField] };
});

View File

@ -15,7 +15,7 @@ import { ModelStatic, Transaction } from 'sequelize';
export default class PostgresQueryInterface extends QueryInterface {
constructor(db) {
super(db);
super(db, { defaultSchemaName: 'public' });
}
async setAutoIncrementVal(options: {

View File

@ -11,6 +11,7 @@ import {
ColumnDescription,
ModelStatic,
QueryInterfaceDropTableOptions,
QueryInterfaceOptions,
QueryInterface as SequelizeQueryInterface,
TableName,
Transaction,
@ -56,6 +57,7 @@ export type ChangeColumnAction = (typeof ChangeColumnAction)[keyof typeof Change
type QueryInterfaceConfig = {
changeColumnMode?: 'default' | 'sequelize';
defaultSchemaName?: string;
};
export interface RemoveColumnOptions {
@ -74,7 +76,7 @@ export default abstract class QueryInterface {
config?: QueryInterfaceConfig,
) {
this.sequelizeQueryInterface = db.sequelize.getQueryInterface();
this.config = config || { changeColumnMode: 'default' };
this.config = { changeColumnMode: 'default', ...(config || {}) };
}
abstract collectionTableExists(collection: Collection, options?: Transactionable): Promise<boolean>;
@ -101,6 +103,10 @@ export default abstract class QueryInterface {
abstract afterRemoveColumn(options: RemoveColumnOptions): Promise<void>;
get defaultSchemaName() {
return this.config.defaultSchemaName;
}
async dropAll(options) {
if (options.drop !== true) return;

View File

@ -252,7 +252,7 @@ describe('collections repository', () => {
expect(response1.body.data.length).toBe(2);
});
it.only('case 7', async () => {
it('case 7', async () => {
const response = await agent.resource('posts').create({
values: {
tags: [

View File

@ -43,18 +43,26 @@ describe('view collection', () => {
SELECT CAST(1 AS INTEGER)
UNION ALL
SELECT CAST(1 + n AS INTEGER) FROM numbers WHERE n < 20
)
SELECT * FROM numbers;
`;
}
)
SELECT * FROM numbers;
`;
} else if (app.db.inDialect('mssql')) {
return `CREATE VIEW ${testViewName} AS WITH numbers(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 20
)
SELECT * FROM numbers;
`;
} else {
return `CREATE VIEW ${testViewName} AS WITH RECURSIVE numbers(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 20
)
SELECT * FROM numbers;
`;
)
SELECT * FROM numbers;
`;
}
})();
await app.db.sequelize.query(viewSQL);
});
@ -63,6 +71,15 @@ SELECT * FROM numbers;
await app.destroy();
});
function getSchema() {
if (app.db.options.dialect === 'mssql') {
return 'dbo';
}
if (app.db.options.dialect === 'postgres') {
return 'public';
}
}
it('should support preview field with getter', async () => {
class TestField extends Field {
constructor(options: any, context: any) {
@ -139,7 +156,7 @@ SELECT * FROM numbers;
values: {
name: testViewName,
view: true,
schema: app.db.inDialect('postgres') ? 'public' : undefined,
schema: getSchema(),
fields: [
{
name: 'numbers',
@ -168,7 +185,7 @@ SELECT * FROM numbers;
it('should list views fields', async () => {
const response = await agent.resource('dbViews').get({
filterByTk: testViewName,
schema: 'public',
schema: getSchema(),
});
expect(response.status).toBe(200);
@ -196,6 +213,10 @@ SELECT * FROM numbers;
if (app.db.inDialect('postgres')) {
return `CREATE VIEW ${jsonViewName} AS SELECT '{"a": 1}'::json as json_field`;
}
if (app.db.inDialect('mssql')) {
return `CREATE VIEW ${jsonViewName} AS
SELECT (SELECT 1 AS key1, 'abc' AS key2 FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) as json_field`;
}
return `CREATE VIEW ${jsonViewName} AS SELECT JSON_OBJECT('key1', 1, 'key2', 'abc') as json_field`;
})();
@ -203,14 +224,14 @@ SELECT * FROM numbers;
const response = await agent.resource('dbViews').get({
filterByTk: jsonViewName,
schema: app.db.inDialect('postgres') ? 'public' : undefined,
schema: getSchema(),
});
expect(response.status).toBe(200);
const data = response.body.data;
const jsonField = data.fields.find((field) => field.name === 'json_field');
expect(jsonField.type).toBe('json');
expect(jsonField.type).toBe(app.db.options.dialect === 'mssql' ? 'string' : 'json');
expect(jsonField.possibleTypes).toBeTruthy();
});
@ -250,7 +271,7 @@ SELECT * FROM numbers;
values: {
name: viewName,
view: true,
schema: app.db.inDialect('postgres') ? 'public' : undefined,
schema: getSchema(),
fields: [
{
name: 'name',
@ -291,7 +312,7 @@ SELECT * FROM numbers;
expect(response2.statusCode).toBe(200);
});
it('should list collections fields with source interface', async () => {
it.only('should list collections fields with source interface', async () => {
await app.db.getRepository('collections').create({
values: {
name: 'users',
@ -327,7 +348,7 @@ SELECT * FROM numbers;
values: {
name: viewName,
view: true,
schema: app.db.inDialect('postgres') ? 'public' : undefined,
schema: getSchema(),
fields: [
{
name: 'name',
@ -440,7 +461,7 @@ SELECT * FROM numbers;
values: {
name: viewName,
view: true,
schema: app.db.inDialect('postgres') ? 'public' : undefined,
schema: getSchema(),
fields: [
{
name: 'id',

View File

@ -78,16 +78,14 @@ export default {
},
async query(ctx, next) {
const { filterByTk, fieldTypes, schema = 'public', page = 1, pageSize = 10 } = ctx.action.params;
const { filterByTk, fieldTypes, page = 1, pageSize = 10 } = ctx.action.params;
const schema = ctx.action.params.schema || ctx.app.db.options.schema || (ctx.app.db as Database).schema;
const offset = (page - 1) * pageSize;
const limit = 1 * pageSize;
const table = schema ? ctx.app.db.utils.addSchema(filterByTk, schema) : filterByTk;
const sql = `SELECT * FROM ${ctx.app.db.utils.quoteTable(table)}`;
const sql = `SELECT *
FROM ${ctx.app.db.utils.quoteTable(ctx.app.db.utils.addSchema(filterByTk, schema))} LIMIT ${limit}
OFFSET ${offset}`;
const rawValues = await ctx.app.db.sequelize.query(sql, { type: 'SELECT' });
const rawValues = await ctx.app.db.sequelize.query(sql, { type: 'SELECT', limit, offset });
if (fieldTypes) {
for (const raw of rawValues) {