From 2f8e7a8087042909ecd6e7a60e3e124b2ff96255 Mon Sep 17 00:00:00 2001 From: ChengLei Shao Date: Sat, 1 Apr 2023 09:06:20 +0800 Subject: [PATCH] fix: init sort value in sort field with scopeKey (#1626) --- .../src/__tests__/fields/sort-field.test.ts | 46 +++++++++ .../core/database/src/fields/sort-field.ts | 99 ++++++++++++------- packages/core/database/src/mock-database.ts | 7 +- 3 files changed, 114 insertions(+), 38 deletions(-) diff --git a/packages/core/database/src/__tests__/fields/sort-field.test.ts b/packages/core/database/src/__tests__/fields/sort-field.test.ts index dfd36aab7..a30c4e1d0 100644 --- a/packages/core/database/src/__tests__/fields/sort-field.test.ts +++ b/packages/core/database/src/__tests__/fields/sort-field.test.ts @@ -17,6 +17,52 @@ describe('string field', () => { await db.close(); }); + it('should init sorted value with scopeKey', async () => { + const Test = db.collection({ + name: 'tests', + fields: [ + { + type: 'string', + name: 'name', + }, + { + type: 'string', + name: 'group', + }, + ], + }); + + await db.sync(); + await Test.repository.create({ + values: [ + { + group: 'a', + name: 'r1', + }, + { + group: 'b', + name: 'r2', + }, + { + group: 'a', + name: 'r3', + }, + { + group: 'b', + name: 'r4', + }, + ], + }); + + Test.setField('sort', { type: 'sort', scopeKey: 'group' }); + + await db.sync(); + + const records = await Test.repository.find({}); + const r3 = records.find((r) => r.get('name') === 'r3'); + expect(r3.get('sort')).toBe(2); + }); + it('should init sorted value by createdAt when primaryKey not exists', async () => { const Test = db.collection({ autoGenId: false, diff --git a/packages/core/database/src/fields/sort-field.ts b/packages/core/database/src/fields/sort-field.ts index a63829663..c59fa8d52 100644 --- a/packages/core/database/src/fields/sort-field.ts +++ b/packages/core/database/src/fields/sort-field.ts @@ -42,50 +42,75 @@ export class SortField extends Field { }; initRecordsSortValue = async ({ transaction }) => { - const totalCount = await this.collection.repository.count({ - transaction, - }); - - const emptyCount = await this.collection.repository.count({ - filter: { - [this.name]: null, - }, - transaction, - }); - - const orderKey = (() => { - const model = this.collection.model; - if (model.primaryKeyAttribute) { - return model.primaryKeyAttribute; - } - if (model.rawAttributes['createdAt']) { - return 'createdAt'; + const doInit = async (scopeKey = null, scopeValue = null) => { + const filter = {}; + if (scopeKey && scopeValue) { + filter[scopeKey] = scopeValue; } - throw new Error(`can not find order key for collection ${this.collection.name}`); - })(); - - if (emptyCount === totalCount && emptyCount > 0) { - const records = await this.collection.repository.find({ - order: [orderKey], + const totalCount = await this.collection.repository.count({ + filter, transaction, }); - let start = 1; - for (const record of records) { - await record.update( - { - sort: start, - }, - { - hooks: false, - transaction, - silent: true, - }, - ); + const emptyCount = await this.collection.repository.count({ + filter: { + [this.name]: null, + ...filter, + }, + transaction, + }); - start += 1; + const orderKey = (() => { + const model = this.collection.model; + if (model.primaryKeyAttribute) { + return model.primaryKeyAttribute; + } + if (model.rawAttributes['createdAt']) { + return 'createdAt'; + } + + throw new Error(`can not find order key for collection ${this.collection.name}`); + })(); + + if (emptyCount === totalCount && emptyCount > 0) { + const records = await this.collection.repository.find({ + order: [orderKey], + filter, + transaction, + }); + + let start = 1; + for (const record of records) { + await record.update( + { + sort: start, + }, + { + hooks: false, + transaction, + silent: true, + }, + ); + + start += 1; + } } + }; + + const scopeKey = this.options.scopeKey; + if (scopeKey) { + const groups = await this.collection.repository.find({ + attributes: [scopeKey], + group: [scopeKey], + raw: true, + }); + + for (const group of groups) { + await doInit(scopeKey, group[scopeKey]); + } + } else { + await doInit(); } }; diff --git a/packages/core/database/src/mock-database.ts b/packages/core/database/src/mock-database.ts index 6414232bd..137f7a927 100644 --- a/packages/core/database/src/mock-database.ts +++ b/packages/core/database/src/mock-database.ts @@ -21,7 +21,7 @@ export function getConfigByEnv() { host: process.env.DB_HOST, port: process.env.DB_PORT, dialect: process.env.DB_DIALECT || 'sqlite', - logging: process.env.DB_LOGGING === 'on' ? console.log : false, + logging: process.env.DB_LOGGING === 'on' ? customLogger : false, storage: process.env.DB_STORAGE && process.env.DB_STORAGE !== ':memory:' ? resolve(process.cwd(), process.env.DB_STORAGE) @@ -39,6 +39,11 @@ export function getConfigByEnv() { }; } +function customLogger(queryString, queryObject) { + console.log(queryString); // outputs a string + console.log(queryObject.bind); // outputs an array +} + export function mockDatabase(options: IDatabaseOptions = {}): MockDatabase { const dbOptions = merge(getConfigByEnv(), options) as any; return new MockDatabase(dbOptions);