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 inheritedCollection = model.collection as InheritedCollection;
const db = inheritedCollection.context.database; const db = inheritedCollection.context.database;
const schemaName = db.options.schema || 'public';
const dialect = db.sequelize.getDialect(); const dialect = db.sequelize.getDialect();
const queryInterface = db.sequelize.getQueryInterface(); const queryInterface = db.sequelize.getQueryInterface();
@ -27,7 +29,7 @@ export class SyncRunner {
const parentTables = parents.map((parent) => parent.model.tableName); const parentTables = parents.map((parent) => parent.model.tableName);
const tableName = model.getTableName(); const tableName = model.tableName;
const attributes = model.tableAttributes; const attributes = model.tableAttributes;
@ -44,6 +46,7 @@ export class SyncRunner {
`SELECT column_default `SELECT column_default
FROM information_schema.columns FROM information_schema.columns
WHERE table_name = '${parent}' WHERE table_name = '${parent}'
and table_schema = '${schemaName}'
and "column_name" = 'id';`, and "column_name" = 'id';`,
{ {
transaction, transaction,
@ -60,7 +63,7 @@ export class SyncRunner {
throw new Error(`Can't find sequence name of ${parent}`); 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 match = regex.exec(columnDefault);
const sequenceName = match[1]; 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) { if (maxSequenceName) {
const parentsDeep = Array.from(db.inheritanceMap.getParents(inheritedCollection.name)).map( const parentsDeep = Array.from(db.inheritanceMap.getParents(inheritedCollection.name)).map(
(parent) => db.getCollection(parent).model.tableName, (parent) => db.getCollection(parent).model.tableName,
); );
const sequenceTables = [...parentsDeep, tableName]; const sequenceTables = [...parentsDeep, tableName.toString()];
for (const sequenceTable of sequenceTables) { 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( const idColumnQuery = await queryInterface.sequelize.query(
` `
SELECT true SELECT column_name
FROM pg_attribute FROM information_schema.columns
WHERE attrelid = '${queryName}'::regclass -- cast to a registered class (table) WHERE table_name='${queryName}' and column_name='id' and table_schema = '${schemaName}';
AND attname = 'id'
AND NOT attisdropped
`, `,
{ {
transaction, transaction,
@ -112,7 +114,7 @@ AND NOT attisdropped
} }
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`alter table "${sequenceTable}" `alter table "${schemaName}"."${sequenceTable}"
alter column id set default nextval('${maxSequenceName}')`, alter column id set default nextval('${maxSequenceName}')`,
{ {
transaction, 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 = ''; let sql = '';
options = { ...options }; options = { ...options };
@ -157,7 +161,7 @@ AND NOT attisdropped
sql = `${queryGenerator.createTableQuery(tableName, attributes, options)}`.replace( 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); return await model.sequelize.query(sql, options);

View File

@ -3,6 +3,56 @@ import Application from '@nocobase/server';
import { createApp } from '..'; import { createApp } from '..';
import { pgOnly } from '@nocobase/test'; 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', () => { pgOnly()('Inherited Collection', () => {
let db: Database; let db: Database;
let app: Application; let app: Application;