chore: load collection with schema (#5541)

* chore: load collection with schema

* chore: load collection with schema

* chore: test

* chore: test

* chore: test

* chore: test

* fix: test

---------

Co-authored-by: CHENGLEI SHAO <Chareice>
This commit is contained in:
ChengLei Shao 2024-11-01 06:46:55 +08:00 committed by GitHub
parent e818195dd1
commit 056d46c680
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 32 additions and 31 deletions

View File

@ -47,11 +47,18 @@ export default class extends Migration {
}, },
], ],
}; };
if (treeCollection.options.schema) {
collectionOptions['schema'] = treeCollection.options.schema; const collectionInstance = this.db.getCollection(treeCollection.name);
const treeCollectionSchema = collectionInstance.collectionSchema();
if (this.app.db.inDialect('postgres') && treeCollectionSchema != this.app.db.options.schema) {
collectionOptions['schema'] = treeCollectionSchema;
} }
this.app.db.collection(collectionOptions); this.app.db.collection(collectionOptions);
const treeExistsInDb = await this.app.db.getCollection(name).existsInDb({ transaction }); const treeExistsInDb = await this.app.db.getCollection(name).existsInDb({ transaction });
if (!treeExistsInDb) { if (!treeExistsInDb) {
await this.app.db.getCollection(name).sync({ transaction } as SyncOptions); await this.app.db.getCollection(name).sync({ transaction } as SyncOptions);
const opts = { const opts = {
@ -63,9 +70,11 @@ export default class extends Migration {
{ type: 'integer', name: 'parentId' }, { type: 'integer', name: 'parentId' },
], ],
}; };
if (treeCollection.options.schema) {
opts['schema'] = treeCollection.options.schema; if (treeCollectionSchema != this.app.db.options.schema) {
opts['schema'] = treeCollectionSchema;
} }
this.app.db.collection(opts); this.app.db.collection(opts);
const chunkSize = 1000; const chunkSize = 1000;
await this.app.db.getRepository(treeCollection.name).chunk({ await this.app.db.getRepository(treeCollection.name).chunk({

View File

@ -7,10 +7,11 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import Database, { CollectionGroupManager, Collection as DBCollection, HasManyRepository } from '@nocobase/database'; import Database, { Collection as DBCollection, CollectionGroupManager, HasManyRepository } from '@nocobase/database';
import Application from '@nocobase/server'; import Application from '@nocobase/server';
import { createApp } from '.'; import { createApp } from '.';
import CollectionManagerPlugin, { CollectionRepository } from '../index'; import { CollectionRepository } from '../index';
import { isPg } from '@nocobase/test';
describe('collections repository', () => { describe('collections repository', () => {
let db: Database; let db: Database;
@ -26,6 +27,7 @@ describe('collections repository', () => {
}); });
afterEach(async () => { afterEach(async () => {
vi.unstubAllEnvs();
await app.destroy(); await app.destroy();
}); });
@ -380,13 +382,8 @@ describe('collections repository', () => {
expect(afterRepository.load).toBeTruthy(); expect(afterRepository.load).toBeTruthy();
}); });
it('should set collection schema from env', async () => { it.runIf(isPg())('should set collection schema from env', async () => {
if (!db.inDialect('postgres')) { vi.stubEnv('COLLECTION_MANAGER_SCHEMA', 'testSchema');
return;
}
const plugin = app.getPlugin<CollectionManagerPlugin>('data-source-main');
plugin.schema = 'testSchema';
await Collection.repository.create({ await Collection.repository.create({
values: { values: {

View File

@ -206,18 +206,20 @@ describe('belongsToMany', () => {
context: {}, context: {},
}); });
const throughCollection = await Collection.repository.findOne({ const throughCollectionRecord = await Collection.repository.findOne({
filter: { filter: {
name: 'post_tags', name: 'post_tags',
}, },
}); });
expect(throughCollection.get('sortable')).toEqual(false); expect(throughCollectionRecord.get('sortable')).toEqual(false);
const collectionManagerSchema = process.env.COLLECTION_MANAGER_SCHEMA; const collectionManagerSchema = process.env.COLLECTION_MANAGER_SCHEMA;
const mainSchema = process.env.DB_SCHEMA || 'public'; const mainSchema = process.env.DB_SCHEMA || 'public';
const throughCollection = db.getCollection('post_tags');
if (collectionManagerSchema && mainSchema != collectionManagerSchema && db.inDialect('postgres')) { if (collectionManagerSchema && mainSchema != collectionManagerSchema && db.inDialect('postgres')) {
expect(throughCollection.get('schema')).toEqual(collectionManagerSchema); expect(throughCollection.options.schema).toEqual(collectionManagerSchema);
const tableName = db.getCollection('post_tags').model.tableName; const tableName = db.getCollection('post_tags').model.tableName;

View File

@ -63,6 +63,10 @@ export class CollectionModel extends MagicAttributeModel {
delete collectionOptions.schema; delete collectionOptions.schema;
} }
if (this.db.inDialect('postgres') && !collectionOptions.schema && collectionOptions.from !== 'db2cm') {
collectionOptions.schema = process.env.COLLECTION_MANAGER_SCHEMA || this.db.options.schema || 'public';
}
if (this.db.hasCollection(name)) { if (this.db.hasCollection(name)) {
collection = this.db.getCollection(name); collection = this.db.getCollection(name);

View File

@ -13,7 +13,6 @@ import { Plugin } from '@nocobase/server';
import { Mutex } from 'async-mutex'; import { Mutex } from 'async-mutex';
import lodash from 'lodash'; import lodash from 'lodash';
import path from 'path'; import path from 'path';
import * as process from 'process';
import { CollectionRepository } from '.'; import { CollectionRepository } from '.';
import { import {
afterCreateForForeignKeyField, afterCreateForForeignKeyField,
@ -33,8 +32,6 @@ import { FieldIsDependedOnByOtherError } from './errors/field-is-depended-on-by-
import { beforeCreateCheckFieldInMySQL } from './hooks/beforeCreateCheckFieldInMySQL'; import { beforeCreateCheckFieldInMySQL } from './hooks/beforeCreateCheckFieldInMySQL';
export class PluginDataSourceMainServer extends Plugin { export class PluginDataSourceMainServer extends Plugin {
public schema: string;
private loadFilter: Filter = {}; private loadFilter: Filter = {};
setLoadFilter(filter: Filter) { setLoadFilter(filter: Filter) {
@ -55,10 +52,6 @@ export class PluginDataSourceMainServer extends Plugin {
} }
async beforeLoad() { async beforeLoad() {
if (this.app.db.inDialect('postgres')) {
this.schema = process.env.COLLECTION_MANAGER_SCHEMA || this.db.options.schema || 'public';
}
this.app.db.registerRepositories({ this.app.db.registerRepositories({
CollectionRepository, CollectionRepository,
}); });
@ -76,12 +69,6 @@ export class PluginDataSourceMainServer extends Plugin {
}, },
}); });
this.app.db.on('collections.beforeCreate', async (model) => {
if (this.app.db.inDialect('postgres') && this.schema && model.get('from') != 'db2cm' && !model.get('schema')) {
model.set('schema', this.schema);
}
});
this.app.db.on('collections.beforeCreate', beforeCreateForViewCollection(this.db)); this.app.db.on('collections.beforeCreate', beforeCreateForViewCollection(this.db));
this.app.db.on( this.app.db.on(

View File

@ -9,7 +9,7 @@
import { BelongsToManyRepository, Database } from '@nocobase/database'; import { BelongsToManyRepository, Database } from '@nocobase/database';
import { AppSupervisor } from '@nocobase/server'; import { AppSupervisor } from '@nocobase/server';
import { MockServer, createMockServer, isPg } from '@nocobase/test'; import { createMockServer, isPg, MockServer } from '@nocobase/test';
import * as process from 'process'; import * as process from 'process';
describe.runIf(isPg())('enable plugin', () => { describe.runIf(isPg())('enable plugin', () => {
@ -491,6 +491,8 @@ describe.runIf(isPg())('collection sync', () => {
context: {}, context: {},
}); });
const mainCollectionInstance = mainDb.getCollection('mainCollection');
await subApp1.runCommand('restart'); await subApp1.runCommand('restart');
const subAppMainCollectionRecord = await subApp1.db.getRepository('collections').findOne({ const subAppMainCollectionRecord = await subApp1.db.getRepository('collections').findOne({
@ -504,7 +506,7 @@ describe.runIf(isPg())('collection sync', () => {
const subAppMainCollection = subApp1.db.getCollection('mainCollection'); const subAppMainCollection = subApp1.db.getCollection('mainCollection');
expect(subAppMainCollection).toBeTruthy(); expect(subAppMainCollection).toBeTruthy();
expect(subAppMainCollection.options.schema).toBe(mainCollection.options.schema || 'public'); expect(subAppMainCollection.options.schema).toBe(mainCollectionInstance.collectionSchema());
await mainApp.db.getRepository('fields').create({ await mainApp.db.getRepository('fields').create({
values: { values: {