From 4b3d07d51c80b310c6a11803e34c1319511222fb Mon Sep 17 00:00:00 2001 From: chenos Date: Wed, 23 Dec 2020 20:29:11 +0800 Subject: [PATCH] fix: improves collections load --- .../src/hooks/fields-after-create.ts | 9 +--- .../src/hooks/fields-after-update.ts | 7 --- .../src/models/collection.ts | 43 +++++++++++-------- .../plugin-collections/src/models/field.ts | 40 +++++++++-------- packages/plugin-collections/src/server.ts | 17 +++++--- packages/plugin-pages/src/server.ts | 3 +- 6 files changed, 59 insertions(+), 60 deletions(-) diff --git a/packages/plugin-collections/src/hooks/fields-after-create.ts b/packages/plugin-collections/src/hooks/fields-after-create.ts index 877f9fdc5..6267766bb 100644 --- a/packages/plugin-collections/src/hooks/fields-after-create.ts +++ b/packages/plugin-collections/src/hooks/fields-after-create.ts @@ -5,7 +5,7 @@ export default async function (model: FieldModel, options: any = {}) { const Collection = model.database.getModel('collections'); if (model.get('interface') === 'subTable') { const target = model.get('target'); - if (target) { + if (target && !model.database.isDefined(target)) { await Collection.import({ name: target, internal: true, @@ -16,11 +16,4 @@ export default async function (model: FieldModel, options: any = {}) { if (migrate) { await model.migrate(options); } - // if (model.get('collection_name') && model.get('parent_id')) { - // const parent = await model.getParent({ - // ...options, - // }); - // const Collection = model.database.getModel('collections'); - // await Collection.load({...options, where: {name: parent.get('collection_name')}}); - // } } diff --git a/packages/plugin-collections/src/hooks/fields-after-update.ts b/packages/plugin-collections/src/hooks/fields-after-update.ts index 5b1be9a0a..9c4dfb44f 100644 --- a/packages/plugin-collections/src/hooks/fields-after-update.ts +++ b/packages/plugin-collections/src/hooks/fields-after-update.ts @@ -5,11 +5,4 @@ export default async function (model: FieldModel, options: any = {}) { if (migrate) { await model.migrate(options); } - // if (model.get('collection_name') && model.get('parent_id')) { - // const parent = await model.getParent({ - // ...options, - // }); - // const Collection = model.database.getModel('collections'); - // await Collection.load({...options, where: {name: parent.get('collection_name')}}); - // } } diff --git a/packages/plugin-collections/src/models/collection.ts b/packages/plugin-collections/src/models/collection.ts index c652fa289..c1cbe4707 100644 --- a/packages/plugin-collections/src/models/collection.ts +++ b/packages/plugin-collections/src/models/collection.ts @@ -23,6 +23,7 @@ export function generateCollectionName(title?: string): string { export interface LoadOptions { reset?: boolean; where?: any; + skipExisting?: boolean; [key: string]: any; } @@ -59,24 +60,25 @@ export class CollectionModel extends BaseModel { // table 是初始化和重新初始化 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({ - ...opts, - where: { - name: { - [Op.in]: associationTableNames, - } - } - }); - } + // const associationTableNames = []; + // for (const [key, association] of table.getAssociations()) { + // // TODO:是否需要考虑重载的情况?(暂时是跳过处理) + // if (!this.database.isDefined(association.options.target)) { + // continue; + // } + // associationTableNames.push(association.options.target); + // } + // console.log({associationTableNames}); + // if (associationTableNames.length) { + // await CollectionModel.load({ + // ...opts, + // where: { + // name: { + // [Op.in]: associationTableNames, + // } + // } + // }); + // } return table; } @@ -115,12 +117,15 @@ export class CollectionModel extends BaseModel { * @param options */ static async load(options: LoadOptions = {}) { - const { reset = false, where = {}, transaction } = options; + const { skipExisting = false, reset = false, where = {}, transaction } = options; const collections = await this.findAll({ transaction, where, }); for (const collection of collections) { + if (skipExisting && this.database.isDefined(collection.get('name'))) { + continue; + } await collection.loadTableOptions({ transaction, reset, diff --git a/packages/plugin-collections/src/models/field.ts b/packages/plugin-collections/src/models/field.ts index aefb2e81d..ddff5359d 100644 --- a/packages/plugin-collections/src/models/field.ts +++ b/packages/plugin-collections/src/models/field.ts @@ -31,12 +31,34 @@ export class FieldModel extends BaseModel { // @ts-ignore data = merge(...args); if (['hasOne', 'hasMany', 'belongsTo', 'belongsToMany'].includes(data.type)) { + // 关系字段如果没有 name,相关参数都随机生成 if (!data.name) { data.name = generateFieldName(); + // 通用,关系表 if (!data.target) { data.target = generateCollectionName(); } + // 通用,外键 + if (!data.foreignKey) { + data.foreignKey = generateFieldName(); + } + if (data.type !== 'belongsTo' && !data.sourceKey) { + data.sourceKey = 'id'; + } + if (['belongsTo', 'belongsToMany'].includes(data.type) && !data.targetKey) { + data.targetKey = 'id'; + } + // 多对多关联 + if (data.type === 'belongsToMany') { + if (!data.through) { + data.through = generateCollectionName(); + } + if (!data.otherKey) { + data.otherKey = generateFieldName(); + } + } } + // 有 name,但是没有 target if (!data.target) { data.target = ['hasOne', 'belongsTo'].includes(data.type) ? Utils.pluralize(data.name) : data.name; } @@ -77,24 +99,8 @@ export class FieldModel extends BaseModel { if (!collectionName) { return false; } - const Collection = this.database.getModel('collections'); - if (this.get('interface') === 'linkTo') { - // afterCreate 时 target 表不知道为什么丢失了,需要重新加载 - const target = this.get('target'); - if (!this.database.isDefined(target)) { - await Collection.load({ - ...options, - where: { - name: target, - } - }); - } - // const table = this.getTable(target); - // console.log(model.get('target'), typeof table); - } - // 如果 database 未定义,load 出来 if (!this.database.isDefined(collectionName)) { - await Collection.load({where: {name: collectionName}}); + throw new Error(`${collectionName} is not defined`); } const table = this.database.getTable(collectionName); table.addField(await this.getOptions()); diff --git a/packages/plugin-collections/src/server.ts b/packages/plugin-collections/src/server.ts index 041b564ea..877c8c7e7 100644 --- a/packages/plugin-collections/src/server.ts +++ b/packages/plugin-collections/src/server.ts @@ -33,11 +33,14 @@ export default async function (this: Application, options = {}) { Model.addHook(hookKey, hooks[modelName][hookKey]); }); }); - try { - // 加载数据库表 collections 中已经保存的表配置 - // 如果未 sync 可能报错 - // TODO collections sync - // await database.getModel('collections').load(); - } catch (error) { - } + + let initialized = false; + + this.use(async (ctx, next) => { + if (!initialized) { + await database.getModel('collections').load({skipExisting: true}); + initialized = true; + } + await next(); + }); } diff --git a/packages/plugin-pages/src/server.ts b/packages/plugin-pages/src/server.ts index b64318a2d..afa8cd425 100644 --- a/packages/plugin-pages/src/server.ts +++ b/packages/plugin-pages/src/server.ts @@ -68,7 +68,7 @@ export default async function (options = {}) { Collection.addHook('afterUpdate', createCollectionPage); Collection.addHook('afterDestroy', async (model, options) => { const { transaction } = options; - console.log('afterDestroy', model); + // console.log('afterDestroy', model); await Page.destroy({ transaction, where: { @@ -127,7 +127,6 @@ export default async function (options = {}) { await transaction.commit(); } View.addHook('beforeValidate', (model) => { - console.log('beforeValidate'); if (model.get('default')) { model.set('showInDataMenu', true); }