feat: init sort field values (#236)

* feat: init sort field values

* feat: handle sequelize afterSync hook
This commit is contained in:
ChengLei Shao 2022-03-14 13:24:00 +08:00 committed by GitHub
parent cf279409b4
commit 4c0af45105
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 3 deletions

View File

@ -7,6 +7,7 @@ describe('string field', () => {
beforeEach(async () => { beforeEach(async () => {
db = mockDatabase(); db = mockDatabase();
await db.clean({ drop: true });
db.registerFieldTypes({ db.registerFieldTypes({
sort: SortField, sort: SortField,
}); });
@ -31,6 +32,45 @@ describe('string field', () => {
expect(test3.sort).toBe(3); expect(test3.sort).toBe(3);
}); });
it('should init sort value on data already exits', async () => {
const Test = db.collection({
name: 'tests',
fields: [
{
type: 'string',
name: 'name',
},
],
});
await db.sync();
await db.getRepository('tests').create({
values: {
name: 't1',
},
});
await db.getRepository('tests').create({
values: {
name: 't2',
},
});
await db.getRepository('tests').create({
values: {
name: 't3',
},
});
const field = Test.addField('sort', { type: 'sort' });
await field.sync({});
const items = await db.getRepository('tests').find({
order: ['id'],
});
expect(items.map((item) => item.get('sort'))).toEqual([1, 2, 3]);
});
test.skip('simultaneously create ', async () => { test.skip('simultaneously create ', async () => {
const Test = db.collection({ const Test = db.collection({
name: 'tests', name: 'tests',

View File

@ -1,7 +1,7 @@
import merge from 'deepmerge'; import merge from 'deepmerge';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { default as lodash, default as _ } from 'lodash'; import { default as lodash, default as _ } from 'lodash';
import { ModelCtor, ModelOptions, SyncOptions } from 'sequelize'; import { col, ModelCtor, ModelOptions, SyncOptions } from 'sequelize';
import { Database } from './database'; import { Database } from './database';
import { Field, FieldOptions } from './fields'; import { Field, FieldOptions } from './fields';
import { Model } from './model'; import { Model } from './model';

View File

@ -41,8 +41,38 @@ export class SortField extends Field {
} }
} }
async initRecordsSortValue({ syncOptions }) {
const totalCount = await this.collection.repository.count();
const emptyCount = await this.collection.repository.count({
filter: {
[this.name]: null,
},
});
if (emptyCount === totalCount && emptyCount > 0) {
const records = await this.collection.repository.find({
order: [this.collection.model.primaryKeyAttribute],
});
let start = 1;
for (const record of records) {
await record.update(
{
sort: start,
},
{
silent: true,
},
);
start += 1;
}
}
}
bind() { bind() {
super.bind(); super.bind();
this.on('afterSync', this.initRecordsSortValue.bind(this));
this.on('beforeUpdate', this.onScopeChange.bind(this)); this.on('beforeUpdate', this.onScopeChange.bind(this));
this.on('beforeCreate', this.setSortValue.bind(this)); this.on('beforeCreate', this.setSortValue.bind(this));
} }
@ -51,6 +81,7 @@ export class SortField extends Field {
super.unbind(); super.unbind();
this.off('beforeUpdate', this.onScopeChange.bind(this)); this.off('beforeUpdate', this.onScopeChange.bind(this));
this.off('beforeCreate', this.setSortValue.bind(this)); this.off('beforeCreate', this.setSortValue.bind(this));
this.off('afterSync', this.initRecordsSortValue.bind(this));
} }
} }

View File

@ -31,9 +31,15 @@ export class ModelHook {
return (<Model>arg).constructor.name; return (<Model>arg).constructor.name;
} }
if (lodash.isPlainObject(arg) && arg['model']) { if (lodash.isPlainObject(arg)) {
if (arg['model']) {
return arg['model'].name; return arg['model'].name;
} }
if (lodash.get(arg, 'name.plural')) {
return lodash.get(arg, 'name.plural');
}
}
} }
return null; return null;
@ -50,6 +56,7 @@ export class ModelHook {
sequelizeHookBuilder(eventName) { sequelizeHookBuilder(eventName) {
return async (...args: any[]) => { return async (...args: any[]) => {
const modelName = this.findModelName(args); const modelName = this.findModelName(args);
if (modelName) { if (modelName) {
// emit model event // emit model event
await this.database.emitAsync(`${modelName}.${eventName}`, ...args); await this.database.emitAsync(`${modelName}.${eventName}`, ...args);