refactor: table.extend() method

This commit is contained in:
chenos 2021-01-13 15:43:41 +08:00
parent b9f74197d3
commit e51ee7d1e6
4 changed files with 97 additions and 31 deletions

View File

@ -8,6 +8,7 @@
"license": "MIT",
"dependencies": {
"bcrypt": "^5.0.0",
"deepmerge": "^4.2.2",
"glob": "^7.1.6",
"sequelize": "^6.3.3"
},

View File

@ -137,7 +137,7 @@ describe('tables', () => {
});
describe('#extend()', () => {
it('should be extend', async () => {
it('extend options', async () => {
db.table({
name: 'baz',
});
@ -151,7 +151,7 @@ describe('tables', () => {
expect(db.getModel('baz').rawAttributes.created).toBeDefined();
expect(db.getModel('baz').rawAttributes.updated).toBeDefined();
});
it('should be extend', async () => {
it('extend fields', async () => {
db.table({
name: 'foos',
});
@ -187,6 +187,60 @@ describe('tables', () => {
// await db.sync({force: true});
// await db.sequelize.close();
});
it('extend array options', async () => {
db.table({
name: 'baz',
actions: [
{
name: 'list',
}
]
});
db.extend({
name: 'baz',
actions: [
{
name: 'get',
}
]
});
expect(db.getTable('baz').getOptions()).toEqual({
name: 'baz',
actions: [ { name: 'get' } ]
});
});
it('extend with customMerge', async () => {
db.table({
name: 'baz',
actions: [
{
name: 'list',
}
]
});
db.extend({
name: 'baz',
actions: [
{
name: 'get',
}
]
}, {
customMerge: (key, options) => {
if (key !== 'actions') {
return;
}
return (source, target) => source.concat(target);
}
});
expect(db.getTable('baz').getOptions()).toEqual({
name: 'baz',
actions: [ { name: 'list' }, { name: 'get' } ]
});
});
});
describe('associations', () => {

View File

@ -4,7 +4,7 @@ import {
SyncOptions as SequelizeSyncOptions,
} from 'sequelize';
import glob from 'glob';
import Table, { TableOptions } from './table';
import Table, { MergeOptions, TableOptions } from './table';
import { Model, ModelCtor } from './model';
import { requireModule } from './utils';
import _ from 'lodash';
@ -76,9 +76,8 @@ export default class Database {
});
const tables = new Map<string, Table>();
files.forEach((file: string) => {
const options = requireModule(file);
const table = this.table(typeof options === 'function' ? options(this) : options);
tables.set(table.getName(), table);
const result = requireModule(file);
this.extend(typeof result === 'function' ? result(this) : result);
});
return tables;
}
@ -107,12 +106,12 @@ export default class Database {
*
* @param options
*/
public extend(options: TableOptions): Table {
public extend(options: TableOptions, mergeOptions?: MergeOptions): Table {
const { name } = options;
let table: Table;
if (this.tables.has(name)) {
table = this.tables.get(name);
table.extend(options);
table.extend(options, mergeOptions);
} else {
table = this.table(options);
this.tables.set(name, table);
@ -146,7 +145,7 @@ export default class Database {
*
* @param names
*/
public getModels(names: string[]): Array<ModelCtor<Model>> {
public getModels(names: string[] = []): Array<ModelCtor<Model>> {
if (names.length === 0) {
return this.sequelize.models as any;
}
@ -171,7 +170,7 @@ export default class Database {
*
* @param names
*/
public getTables(names: string[]): Array<Table> {
public getTables(names: string[] = []): Array<Table> {
if (names.length === 0) {
return [...this.tables.values()];
}

View File

@ -17,6 +17,11 @@ import {
import Database from './database';
import { Model, ModelCtor } from './model';
import _ from 'lodash';
import merge from 'deepmerge';
export interface MergeOptions extends merge.Options {
}
const registeredModels = new Map<string, any>();
@ -136,20 +141,12 @@ export class Table {
const { database } = context;
database.runHooks('beforeTableInit', options);
const {
name,
model,
fields = [],
indexes = [],
model,
...restOptions
} = options;
this.options = options;
this.database = database;
this.modelOptions = {
modelName: name,
tableName: name,
sequelize: database.sequelize,
...restOptions,
};
// 初始化的时候获取
this.defaultModel = getRegisteredModel(model);
this.modelAttributes = {};
@ -204,7 +201,7 @@ export class Table {
}
public getTableName(): string {
return this.modelOptions.tableName;
return this.options.name;
}
public getOptions(): TableOptions {
@ -220,15 +217,22 @@ export class Table {
}
public getModelOptions(): InitOptions {
const { underscored = true } = this.modelOptions;
const {
name,
underscored = true,
...restOptions
} = this.options;
const hooks = _.get(this.getModel(), 'options.hooks') || this.options.hooks || {};
return {
underscored,
modelName: name,
tableName: name,
sequelize: this.database.sequelize,
createdAt: Utils.underscoredIf('createdAt', underscored),
updatedAt: Utils.underscoredIf('updatedAt', underscored),
indexes: Array.from(this.indexes.values()),
// freezeTableName: true,
...this.modelOptions,
..._.omit(restOptions, ['model', 'fields', 'indexes']),
hooks,
};
}
@ -336,7 +340,8 @@ export class Table {
};
}
// @ts-ignore
const index = Utils.nameIndex(options, this.modelOptions.tableName);
const index = Utils.nameIndex(options, this.options.name);
console.log(this.options, { index, options });
this.indexes.set(index.name, {
type: '',
parser: null,
@ -363,14 +368,21 @@ export class Table {
*
* @param options
*/
public extend(options: TableOptions) {
const { fields = [], indexes = [], ...restOptions } = options;
this.modelOptions = {
...this.modelOptions,
...restOptions as any,
};
// @ts-ignore
this.options = Utils.merge(this.options, restOptions);
public extend(options: TableOptions, mergeOptions: MergeOptions = {}) {
const {
fields = [],
indexes = [],
model,
...restOptions
} = options;
if (model) {
this.defaultModel = getRegisteredModel(model);
}
const { arrayMerge = (target: any[], source: any[]) => source } = mergeOptions;
this.options = merge(this.options, restOptions, {
arrayMerge,
...mergeOptions,
});
for (const key in fields) {
this.addField(fields[key], false);
}