refactor: table.extend() method
This commit is contained in:
		
							parent
							
								
									b9f74197d3
								
							
						
					
					
						commit
						e51ee7d1e6
					
				@ -8,6 +8,7 @@
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "bcrypt": "^5.0.0",
 | 
			
		||||
    "deepmerge": "^4.2.2",
 | 
			
		||||
    "glob": "^7.1.6",
 | 
			
		||||
    "sequelize": "^6.3.3"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -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', () => {
 | 
			
		||||
 | 
			
		||||
@ -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()];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user