add hooks for database

This commit is contained in:
chenos 2020-12-15 20:16:55 +08:00
parent 8739ea79d2
commit 67e18352b6
3 changed files with 124 additions and 0 deletions

View File

@ -0,0 +1,88 @@
import { getDatabase } from '.';
import Database, { Field } from '../';
import Table from '../table';
let db: Database;
beforeEach(async () => {
db = getDatabase();
});
afterEach(async () => {
await db.close();
});
describe('database.addHook()', () => {
it('beforeTableInit', async () => {
db.addHook('beforeTableInit', (options) => {
options.title = 'abc';
});
const table = db.table({
name: 'testHook',
createdBy: true,
fields: [
{
type: 'json',
name: 'arr',
defaultValue: [],
},
],
});
expect(table.getOptions().title).toBe('abc');
});
it('afterTableInit', async () => {
db.addHook('afterTableInit', (table: Table) => {
table.addField({
type: 'string',
name: 'abc',
});
});
const table = db.table({
name: 'testHook',
createdBy: true,
fields: [
{
type: 'json',
name: 'arr',
defaultValue: [],
},
],
});
expect(table.getField('abc')).toBeTruthy();
});
it('beforeAddField', async () => {
db.addHook('beforeAddField', (options) => {
options.title = 'f1';
});
const table = db.table({
name: 'testHook',
createdBy: true,
fields: [
{
type: 'string',
name: 'name',
},
],
});
expect(table.getField('name').options.title).toBe('f1');
});
it('afterAddField', async () => {
db.addHook('afterAddField', (field: Field, table: Table) => {
if (field.options.name === 'name') {
const options = {...field.options, name: `${field.options.name}123`}
table.addField(options);
}
});
const table = db.table({
name: 'testHook',
createdBy: true,
fields: [
{
type: 'string',
name: 'name',
},
],
});
expect(table.getField('name123')).toBeTruthy();
});
});

View File

@ -7,6 +7,7 @@ import glob from 'glob';
import Table, { TableOptions } from './table';
import { Model, ModelCtor } from './model';
import { requireModule } from './utils';
import _ from 'lodash';
export interface SyncOptions extends SequelizeSyncOptions {
@ -29,6 +30,8 @@ export interface ImportOptions {
extensions?: string[];
}
export type HookType = 'beforeTableInit' | 'afterTableInit' | 'beforeAddField' | 'afterAddField';
export default class Database {
public readonly sequelize: Sequelize;
@ -47,6 +50,8 @@ export default class Database {
protected options: Options;
protected hooks = {};
constructor(options: Options) {
this.options = options;
this.sequelize = new Sequelize(options);
@ -249,4 +254,31 @@ export default class Database {
public async close() {
return this.sequelize.close();
}
/**
* hook
*
* @param hookType
* @param fn
*/
public addHook(hookType: HookType, fn: Function) {
const hooks = this.hooks[hookType] || [];
hooks.push(fn);
this.hooks[hookType] = hooks;
}
/**
* hook
*
* @param hookType
* @param args
*/
public runHooks(hookType: HookType, ...args) {
const hooks = this.hooks[hookType] || [];
for (const hook of hooks) {
if (typeof hook === 'function') {
hook(...args);
}
}
}
}

View File

@ -134,6 +134,7 @@ export class Table {
constructor(options: TableOptions, context: TabelContext) {
const { database } = context;
database.runHooks('beforeTableInit', options);
const {
name,
fields = [],
@ -156,6 +157,7 @@ export class Table {
this.addIndexes(indexes, 'modelOnly');
// this.modelInit('modelOnly');
this.setFields(fields);
database.runHooks('afterTableInit', this);
}
public modelInit(reinitialize: Reinitialize = false) {
@ -280,6 +282,7 @@ export class Table {
* @param reinitialize
*/
public addField(options: FieldOptions, reinitialize: Reinitialize = true) {
this.database.runHooks('beforeAddField', options, this);
const { name, index } = options;
const field = buildField(options, {
sourceTable: this,
@ -315,6 +318,7 @@ export class Table {
this.modelAttributes[name] = field.getAttributeOptions();
}
this.modelInit(reinitialize);
this.database.runHooks('afterAddField', field, this);
return field;
}