mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 08:26:21 +00:00
feat: load database table dynamically
This commit is contained in:
parent
524103f6b3
commit
a3155f687f
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user