fix: pg schema in sync runner

This commit is contained in:
Chareice 2023-02-09 13:01:25 +08:00
parent 7fe70da4fa
commit 4449325489
2 changed files with 67 additions and 13 deletions

View File

@ -7,6 +7,8 @@ export class SyncRunner {
const inheritedCollection = model.collection as InheritedCollection;
const db = inheritedCollection.context.database;
const schemaName = db.options.schema || 'public';
const dialect = db.sequelize.getDialect();
const queryInterface = db.sequelize.getQueryInterface();
@ -27,7 +29,7 @@ export class SyncRunner {
const parentTables = parents.map((parent) => parent.model.tableName);
const tableName = model.getTableName();
const tableName = model.tableName;
const attributes = model.tableAttributes;
@ -44,6 +46,7 @@ export class SyncRunner {
`SELECT column_default
FROM information_schema.columns
WHERE table_name = '${parent}'
and table_schema = '${schemaName}'
and "column_name" = 'id';`,
{
transaction,
@ -60,7 +63,7 @@ export class SyncRunner {
throw new Error(`Can't find sequence name of ${parent}`);
}
const regex = new RegExp(/nextval\('("?\w+"?)\'.*\)/);
const regex = new RegExp(/nextval\('(.*)'::regclass\)/);
const match = regex.exec(columnDefault);
const sequenceName = match[1];
@ -82,25 +85,24 @@ export class SyncRunner {
}
}
await this.createTable(tableName, childAttributes, options, model, parentTables);
await this.createTable(tableName, childAttributes, options, model, parentTables, schemaName);
if (maxSequenceName) {
const parentsDeep = Array.from(db.inheritanceMap.getParents(inheritedCollection.name)).map(
(parent) => db.getCollection(parent).model.tableName,
);
const sequenceTables = [...parentsDeep, tableName];
const sequenceTables = [...parentsDeep, tableName.toString()];
for (const sequenceTable of sequenceTables) {
const queryName = Boolean(sequenceTable.match(/[A-Z]/)) ? `"${sequenceTable}"` : sequenceTable;
const queryName =
Boolean(sequenceTable.match(/[A-Z]/)) && !sequenceTable.includes(`"`) ? `"${sequenceTable}"` : sequenceTable;
const idColumnQuery = await queryInterface.sequelize.query(
`
SELECT true
FROM pg_attribute
WHERE attrelid = '${queryName}'::regclass -- cast to a registered class (table)
AND attname = 'id'
AND NOT attisdropped
SELECT column_name
FROM information_schema.columns
WHERE table_name='${queryName}' and column_name='id' and table_schema = '${schemaName}';
`,
{
transaction,
@ -112,7 +114,7 @@ AND NOT attisdropped
}
await queryInterface.sequelize.query(
`alter table "${sequenceTable}"
`alter table "${schemaName}"."${sequenceTable}"
alter column id set default nextval('${maxSequenceName}')`,
{
transaction,
@ -132,7 +134,9 @@ AND NOT attisdropped
}
}
static async createTable(tableName, attributes, options, model, parentTables) {
static async createTable(tableName, attributes, options, model, parentTables, schema) {
tableName = model.queryGenerator.addSchema({ tableName, _schema: schema, _schemaDelimiter: '' });
let sql = '';
options = { ...options };
@ -157,7 +161,7 @@ AND NOT attisdropped
sql = `${queryGenerator.createTableQuery(tableName, attributes, options)}`.replace(
';',
` INHERITS (${parentTables.map((t) => `"${t}"`).join(', ')});`,
` INHERITS (${parentTables.map((t) => `"${schema}"."${t}"`).join(', ')});`,
);
return await model.sequelize.query(sql, options);

View File

@ -3,6 +3,56 @@ import Application from '@nocobase/server';
import { createApp } from '..';
import { pgOnly } from '@nocobase/test';
pgOnly()('Inherited Collection', () => {
let db: Database;
let app: Application;
let collectionRepository: Repository;
let fieldsRepository: Repository;
beforeEach(async () => {
app = await createApp({
database: {
schema: 'testSchema',
},
});
db = app.db;
collectionRepository = db.getCollection('collections').repository;
fieldsRepository = db.getCollection('fields').repository;
});
afterEach(async () => {
await app.destroy();
});
it('should create inherited collection in difference schema', async () => {
await collectionRepository.create({
values: {
name: 'b',
fields: [
{
name: 'name',
type: 'string',
},
],
},
context: {},
});
await collectionRepository.create({
values: {
name: 'a',
inherits: ['b'],
fields: [{ type: 'string', name: 'bField' }],
},
context: {},
});
});
});
pgOnly()('Inherited Collection', () => {
let db: Database;
let app: Application;