feat: load database table dynamically

This commit is contained in:
chenos 2020-12-08 09:59:41 +08:00
parent 524103f6b3
commit a3155f687f
2 changed files with 61 additions and 7 deletions

View File

@ -1,7 +1,7 @@
import _ from 'lodash';
import BaseModel from './base';
import { TableOptions } from '@nocobase/database';
import { SaveOptions } from 'sequelize';
import { SaveOptions, Op } from 'sequelize';
/**
*
@ -19,6 +19,16 @@ export function generateCollectionName(title?: string): string {
return `t_${Date.now().toString(36)}_${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`;
}
export interface LoadOptions {
reset?: boolean;
where?: any;
[key: string]: any;
}
export interface MigrateOptions {
[key: string]: any;
}
export class CollectionModel extends BaseModel {
generateName() {
@ -40,18 +50,44 @@ export class CollectionModel extends BaseModel {
return this.findOne({ where: { name } });
}
async loadTableOptions() {
/**
* DOTO
* - database.table
* -
*
* @param opts
*/
async loadTableOptions(opts: any = {}) {
const options = await this.getOptions();
const prevTable = this.database.getTable(this.get('name'));
const prevOptions = prevTable ? prevTable.getOptions() : {};
// table 是初始化和重新初始化
return this.database.table({...prevOptions, ...options});
const table = this.database.table({...prevOptions, ...options});
// 如果关系表未加载,一起处理
const associationTableNames = [];
for (const [key, association] of table.getAssociations()) {
// TODO是否需要考虑重载的情况暂时是跳过处理
if (!this.database.isDefined(association.options.target)) {
continue;
}
associationTableNames.push(association.options.target);
}
if (associationTableNames.length) {
await CollectionModel.load({
where: {
name: {
[Op.in]: associationTableNames,
}
}
});
}
return table;
}
/**
*
*/
async migrate() {
async migrate(options: MigrateOptions = {}) {
const table = await this.loadTableOptions();
return await table.sync({
force: false,
@ -79,10 +115,20 @@ export class CollectionModel extends BaseModel {
};
}
static async load() {
const collections = await this.findAll();
/**
* TODO
*
* @param options
*/
static async load(options: LoadOptions = {}) {
const { reset = false, where = {} } = options;
const collections = await this.findAll({
where,
});
for (const collection of collections) {
await collection.loadTableOptions();
await collection.loadTableOptions({
reset,
});
}
}

View File

@ -39,6 +39,14 @@ export function middleware(options: MiddlewareOptions = {}) {
if (!resourcer.isDefined(resourceName)) {
const names = resourceName.split('.');
const tableName = names.shift();
const Collection = database.getModel('collections');
if (!database.isDefined(tableName) && Collection) {
await Collection.load({
where: {
name: tableName,
},
});
}
if (database.isDefined(tableName)) {
const table = database.getTable(tableName);
const field = table.getField(names[0]) as BelongsTo | HasMany | BelongsToMany | HasOne;