tachybase_todo/packages/database/src/collection.ts

282 lines
6.9 KiB
TypeScript
Raw Normal View History

import merge from 'deepmerge';
2021-09-27 15:28:32 +08:00
import { EventEmitter } from 'events';
import { default as lodash, default as _ } from 'lodash';
import { Model, ModelCtor, ModelOptions } from 'sequelize';
import { SyncOptions } from 'sequelize/types/lib/sequelize';
2021-09-18 00:23:21 +08:00
import { Database } from './database';
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
import { Field, FieldOptions } from './fields';
2021-09-25 23:56:26 +08:00
import { Repository } from './repository';
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
const { hooks } = require('sequelize/lib/hooks');
export type RepositoryType = typeof Repository;
2021-09-18 00:23:21 +08:00
export type CollectionSortable = string | boolean | { name?: string; scopeKey?: string };
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
export interface CollectionOptions extends Omit<ModelOptions, 'name'> {
2021-09-27 15:28:32 +08:00
name: string;
tableName?: string;
filterTargetKey?: string;
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
fields?: FieldOptions[];
model?: string | ModelCtor<Model>;
repository?: string | RepositoryType;
sortable?: CollectionSortable;
2022-01-07 22:06:31 +08:00
/**
* @default true
*/
2021-12-16 10:58:51 +08:00
autoGenId?: boolean;
2022-01-07 22:06:31 +08:00
/**
* @default 'options'
*/
magicAttribute?: string;
2021-12-06 21:23:34 +08:00
[key: string]: any;
2021-09-18 00:23:21 +08:00
}
export interface CollectionContext {
database: Database;
}
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
export class Collection<
TModelAttributes extends {} = any,
TCreationAttributes extends {} = TModelAttributes,
> extends EventEmitter {
2021-09-18 00:23:21 +08:00
options: CollectionOptions;
context: CollectionContext;
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
isThrough?: boolean;
fields: Map<string, any> = new Map<string, any>();
model: ModelCtor<Model<TModelAttributes, TCreationAttributes>>;
repository: Repository<TModelAttributes, TCreationAttributes>;
2021-09-18 00:23:21 +08:00
get filterTargetKey() {
return lodash.get(this.options, 'filterTargetKey', this.model.primaryKeyAttribute);
}
2021-09-18 00:23:21 +08:00
get name() {
return this.options.name;
}
2021-09-27 15:28:32 +08:00
constructor(options: CollectionOptions, context?: CollectionContext) {
super();
2021-09-18 00:23:21 +08:00
this.context = context;
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
this.options = options;
this.bindFieldEventListener();
this.modelInit();
this.setFields(options.fields);
this.setRepository(options.repository);
this.setSortable(options.sortable);
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
}
private sequelizeModelOptions() {
const { name, tableName } = this.options;
return {
..._.omit(this.options, ['name', 'fields', 'model']),
2021-09-18 00:23:21 +08:00
modelName: name,
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
sequelize: this.context.database.sequelize,
2021-09-18 00:23:21 +08:00
tableName: tableName || name,
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
};
}
/**
* TODO
*/
modelInit() {
if (this.model) {
return;
}
2021-12-16 10:58:51 +08:00
const { name, model, autoGenId = true } = this.options;
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
let M = Model;
if (this.context.database.sequelize.isDefined(name)) {
const m = this.context.database.sequelize.model(name);
if ((m as any).isThrough) {
this.model = m;
2021-12-07 15:21:16 +08:00
Object.defineProperty(this.model, 'database', { value: this.context.database });
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
return;
}
}
if (typeof model === 'string') {
M = this.context.database.models.get(model) || Model;
} else if (model) {
M = model;
}
this.model = class extends M {};
this.model.init(null, this.sequelizeModelOptions());
2021-12-16 10:58:51 +08:00
if (!autoGenId) {
this.model.removeAttribute('id');
}
2021-12-07 15:21:16 +08:00
Object.defineProperty(this.model, 'database', { value: this.context.database });
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
}
setRepository(repository?: RepositoryType | string) {
let repo = Repository;
if (typeof repository === 'string') {
repo = this.context.database.repositories.get(repository) || Repository;
}
this.repository = new repo(this);
}
private bindFieldEventListener() {
this.on('field.afterAdd', (field: Field) => {
field.bind();
2021-09-18 00:23:21 +08:00
});
2021-09-27 15:28:32 +08:00
this.on('field.afterRemove', (field) => field.unbind());
2021-09-18 00:23:21 +08:00
}
2021-09-27 15:28:32 +08:00
forEachField(callback: (field: Field) => void) {
return [...this.fields.values()].forEach(callback);
}
findField(callback: (field: Field) => boolean) {
return [...this.fields.values()].find(callback);
}
hasField(name: string) {
return this.fields.has(name);
}
2021-12-06 21:23:34 +08:00
getField<F extends Field>(name: string): F {
2021-09-27 15:28:32 +08:00
return this.fields.get(name);
}
2021-12-06 21:23:34 +08:00
addField(name: string, options: FieldOptions): Field {
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
return this.setField(name, options);
}
2021-12-06 21:23:34 +08:00
setField(name: string, options: FieldOptions): Field {
2021-09-27 15:28:32 +08:00
const { database } = this.context;
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
const field = database.buildField(
{ name, ...options },
{
...this.context,
collection: this,
},
);
2021-09-27 15:28:32 +08:00
this.fields.set(name, field);
this.emit('field.afterAdd', field);
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
return field;
2021-09-27 15:28:32 +08:00
}
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
setFields(fields: FieldOptions[], resetFields = true) {
if (!Array.isArray(fields)) {
return;
2021-09-27 15:28:32 +08:00
}
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
if (resetFields) {
this.resetFields();
2021-09-27 15:28:32 +08:00
}
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
for (const { name, ...options } of fields) {
this.addField(name, options);
}
}
resetFields() {
const fieldNames = this.fields.keys();
for (const fieldName of fieldNames) {
this.removeField(fieldName);
2021-09-27 15:28:32 +08:00
}
}
removeField(name) {
const field = this.fields.get(name);
const bool = this.fields.delete(name);
if (bool) {
this.emit('field.afterRemove', field);
}
return bool;
}
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
/**
* TODO
*/
updateOptions(options: CollectionOptions, mergeOptions?: any) {
let newOptions = lodash.cloneDeep(options);
newOptions = merge(this.options, newOptions, mergeOptions);
this.context.database.emit('beforeUpdateCollection', this, newOptions);
this.setFields(options.fields, false);
this.setRepository(options.repository);
if (newOptions.hooks) {
this.setUpHooks(newOptions.hooks);
}
this.context.database.emit('afterUpdateCollection', this);
return this;
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
}
setUpHooks(bindHooks) {
(<any>this.model)._setupHooks(bindHooks);
2021-09-27 15:28:32 +08:00
}
setSortable(sortable) {
if (!sortable) {
return;
}
if (sortable === true) {
this.setField('sort', {
type: 'sort',
hidden: true,
});
}
if (typeof sortable === 'string') {
this.setField(sortable, {
type: 'sort',
hidden: true,
});
} else if (typeof sortable === 'object') {
const { name, ...opts } = sortable;
this.setField(name || 'sort', { type: 'sort', hidden: true, ...opts });
}
}
feat: database next (#130) * FIX: database test with sqlite * more types * filter test * split filter parser * filter test * filter test: hasMany * define inverse association for belongsTo & hasMany * chore: console.log * repository count method * chore: Collection * repository filter & appends & fields & expect * repository: sort option * chore: test * add: test * find & findAndCount * chore: test * database-next: update guard * database-next: update guard associationKeysToBeUpdate * chore: comment * update-guard OneToOne Association * has one repository * support through table value * belongs to many repository * has many repository * has many repository find * fix: has many find and count * clean code * add count method * chore: multiple relation * chore: single relation * repository find * relation repository builder * repository count * repository count test * fix test * close db afterEach test * sort with associations * repository update * has many repository: destroy * belongs to many repository: destroy * add transaction decorator * belongs to many with transaction * has many with transaction * clean types * clean types * clean types * repository transaction * fix test * single relation repository with transaction * single relation repository with transaction * fix: test * fix: option parser fields append * fix: typo * fix: string type * fix: import * collection field methods * cleanup * collection sync * fix: import * fix: test * collection update field * collection update options * database hook * database test * database event test * update database event * add async emmit mixin * async model event * database import * fix: model hook type * fix: collection event * recall model.init on collection update * skip redefine collection test * skip collection model update * add model hook class * global model event support * chore * chore * change utils import * add field types * database import * more import test * test case * fix: through model init... * bugfix * fix * update database import * collection sync by foreachModel * fix collection model sync * update * add field types * custom operator * sqlite array field * postgresql array field * array query escape * mysql array operators * date operators * array field sqlite fix * association operator * date operator empty & notEmpty * fix: fields import * fix array field nested association * filter parse prepare * fix test * string field empty * add date operator test * field option types * fix typo * fix: operator name conflict * rename function Co-authored-by: Chareice <chareice@live.com>
2021-12-06 21:12:54 +08:00
/**
* TODO
*
* @param name
* @param options
*/
updateField(name: string, options: FieldOptions) {
if (!this.hasField(name)) {
throw new Error(`field ${name} not exists`);
}
if (options.name && options.name !== name) {
this.removeField(name);
}
this.setField(options.name || name, options);
}
async sync(syncOptions?: SyncOptions) {
const modelNames = [this.model.name];
const associations = this.model.associations;
for (const associationKey in associations) {
const association = associations[associationKey];
modelNames.push(association.target.name);
if ((<any>association).through) {
modelNames.push((<any>association).through.model.name);
}
}
const models: ModelCtor<Model>[] = [];
// @ts-ignore
this.context.database.sequelize.modelManager.forEachModel((model) => {
if (modelNames.includes(model.name)) {
models.push(model);
}
});
for (const model of models) {
await model.sync(syncOptions);
}
2021-09-18 00:23:21 +08:00
}
}