nocobase/packages/core/database/src/collection-group-manager.ts
ChengLei Shao 0832a56868
feat: multiple apps (#1540)
* chore: skip yarn install in pm command

* feat: dump sub app by sub app name

* feat: dump & restore by sub app

* chore: enable application name to edit

* chore: field belongsTo uiSchema

* test: drop schema

* feat: uiSchema migrator

* fix: test

* fix: remove uiSchema

* fix: rerun migration

* chore: migrate fieldsHistory uiSchema

* fix: set uiSchema options

* chore: transaction params

* fix: sql error in mysql

* fix: sql compatibility

* feat: collection group api

* chore: restore & dump action template

* chore: tmp commit

* chore: collectionGroupAction

* feat: dumpableCollection api

* refactor: dump command

* fix: remove uiSchemaUid

* chore: get uiSchemaUid from tmp field

* feat: return dumped file url in dumper.dump

* feat: dump api

* refactor: collection groyoup

* chore: comment

* feat: restore command force option

* feat: dump with collection groups

* refactor: restore command

* feat: restore http api

* fix: test

* fix: test

* fix: restore test

* chore: volta pin

* fix: sub app load collection options

* fix: stop sub app

* feat: add stopped status to application to prevent duplicate application stop

* chore: tmp commit

* test: upgrade

* feat: pass upgrade event to sub app

* fix: app manager client

* fix: remove stopped status

* fix: emit beforeStop event

* feat: support dump & restore subApp through api

* chore: dumpable collections api

* refactor: getTableNameWithSchema

* fix: schema name

* feat:  cname

* refactor: collection 同步实现方式

* refactor: move collection group manager to database

* fix: test

* fix: remove uiSchema

* fix: uiSchema

* fix: remove settings

* chore: plugin enable & disable event

* feat: modal warning

* fix: users_jobs namespace

* fix: rolesUischemas namespace

* fix: am snippet

* feat: beforeSubAppInstall event

* fix: improve NOCOBASE_LOCALE_KEY & NOCOBASE_ROLE_KEY

---------

Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-10 19:16:00 +08:00

95 lines
2.2 KiB
TypeScript

import Database from './database';
import { isString, castArray } from 'lodash';
export interface CollectionGroup {
namespace: string;
collections: string[];
function: string;
dumpable: 'required' | 'optional' | 'skip';
delayRestore?: any;
}
export class CollectionGroupManager {
constructor(public db: Database) {}
getGroups() {
const collections = [...this.db.collections.values()];
const groups = new Map<string, CollectionGroup>();
const skipped = [];
for (const collection of collections) {
const groupKey = collection.options.namespace;
if (!groupKey) {
continue;
}
const [namespace, groupFunc] = groupKey.split('.');
if (!groupFunc) {
skipped.push({
name: collection.name,
reason: 'no-group-function',
});
continue;
}
if (!groups.has(groupKey)) {
const dumpable = (() => {
if (!collection.options.duplicator) {
return undefined;
}
if (isString(collection.options.duplicator)) {
return {
dumpable: collection.options.duplicator,
};
}
return collection.options.duplicator;
})();
if (!dumpable) {
skipped.push({
name: collection.name,
reason: 'no-dumpable',
});
continue;
}
const group: CollectionGroup = {
namespace,
function: groupFunc,
collections: dumpable.with ? castArray(dumpable.with) : [],
dumpable: dumpable.dumpable,
};
if (dumpable.delayRestore) {
group.delayRestore = dumpable.delayRestore;
}
groups.set(groupKey, group);
}
const group = groups.get(groupKey);
group.collections.push(collection.name);
}
const results = [...groups.values()];
const groupCollections = results.map((i) => i.collections).flat();
for (const skipItem of skipped) {
if (groupCollections.includes(skipItem.name)) {
continue;
}
this.db.logger.warn(`collection ${skipItem.name} is not in any collection group, reason: ${skipItem.reason}.`);
}
return results;
}
}