From 79d3badedb1384ce2ce6430ebc4c52652b81f514 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Thu, 13 Jun 2024 16:52:47 +0700 Subject: [PATCH] UBERF-7247: Fix queryFind for mixins on server Signed-off-by: Andrey Sobolev --- packages/query/src/__tests__/minmodel.ts | 73 +++++++++++++++++++--- packages/query/src/__tests__/query.test.ts | 27 ++++++++ server/core/src/server/storage.ts | 12 ++-- 3 files changed, 99 insertions(+), 13 deletions(-) diff --git a/packages/query/src/__tests__/minmodel.ts b/packages/query/src/__tests__/minmodel.ts index 8e7322b60e..b03547ebd0 100644 --- a/packages/query/src/__tests__/minmodel.ts +++ b/packages/query/src/__tests__/minmodel.ts @@ -13,7 +13,20 @@ // limitations under the License. // -import type { Account, Arr, Class, Data, Doc, Domain, Mixin, Obj, Ref, TxCreateDoc, TxCUD } from '@hcengineering/core' +import type { + Account, + Arr, + Class, + Data, + Doc, + Domain, + Mixin, + Obj, + Ref, + Space, + TxCreateDoc, + TxCUD +} from '@hcengineering/core' import core, { AccountRole, AttachedDoc, ClassifierKind, DOMAIN_MODEL, DOMAIN_TX, TxFactory } from '@hcengineering/core' import type { IntlString, Plugin } from '@hcengineering/platform' import { plugin } from '@hcengineering/platform' @@ -54,16 +67,26 @@ export interface AttachedComment extends AttachedDoc { message: string } +interface TestProject extends Space { + prjName: string +} + +interface TestProjectMixin extends TestProject { + someField?: string +} + /** * @public */ export const test = plugin('test' as Plugin, { mixin: { - TestMixin: '' as Ref> + TestMixin: '' as Ref>, + TestProjectMixin: '' as Ref> }, class: { TestComment: '' as Ref>, - ParticipantsHolder: '' as Ref> + ParticipantsHolder: '' as Ref>, + TestProject: '' as Ref> } }) @@ -89,20 +112,28 @@ export function genMinModel (): TxCUD[] { createClass(core.class.Doc, { label: 'Doc' as IntlString, extends: core.class.Obj, kind: ClassifierKind.CLASS }) ) txes.push( - createClass(core.class.AttachedDoc, { - label: 'AttachedDoc' as IntlString, + createClass(core.class.Class, { + label: 'Class' as IntlString, extends: core.class.Doc, - kind: ClassifierKind.MIXIN + kind: ClassifierKind.CLASS, + domain: DOMAIN_MODEL }) ) txes.push( - createClass(core.class.Class, { - label: 'Class' as IntlString, - extends: core.class.Doc, + createClass(core.class.Mixin, { + label: 'Mixin' as IntlString, + extends: core.class.Class, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }) ) + txes.push( + createClass(core.class.AttachedDoc, { + label: 'AttachedDoc' as IntlString, + extends: core.class.Doc, + kind: ClassifierKind.MIXIN + }) + ) txes.push( createClass(core.class.Space, { label: 'Space' as IntlString, @@ -164,6 +195,13 @@ export function genMinModel (): TxCUD[] { kind: ClassifierKind.CLASS }) ) + txes.push( + createClass(core.class.TxMixin, { + label: 'TxMixin' as IntlString, + extends: core.class.TxCUD, + kind: ClassifierKind.CLASS + }) + ) txes.push( createClass(test.mixin.TestMixin, { @@ -173,6 +211,23 @@ export function genMinModel (): TxCUD[] { }) ) + txes.push( + createClass(test.class.TestProject, { + label: 'TestProject' as IntlString, + extends: core.class.Space, + kind: ClassifierKind.CLASS, + domain: DOMAIN_TEST + }) + ) + + txes.push( + createClass(test.mixin.TestProjectMixin, { + label: 'TestProjectMixin' as IntlString, + extends: test.class.TestProject, + kind: ClassifierKind.MIXIN + }) + ) + txes.push( createClass(test.class.TestComment, { label: 'TestComment' as IntlString, diff --git a/packages/query/src/__tests__/query.test.ts b/packages/query/src/__tests__/query.test.ts index 7d6bf134c3..9a1a288f10 100644 --- a/packages/query/src/__tests__/query.test.ts +++ b/packages/query/src/__tests__/query.test.ts @@ -942,4 +942,31 @@ describe('query', () => { const result = await resolveP expect(result.length).toEqual(2) }) + + it('check query mixin projection', async () => { + const { liveQuery, factory } = await getClient() + + let projects = await liveQuery.queryFind(test.mixin.TestProjectMixin, {}, { projection: { _id: 1 } }) + expect(projects.length).toEqual(0) + const project = await factory.createDoc(test.class.TestProject, core.space.Space, { + archived: false, + description: '', + members: [], + private: false, + prjName: 'test project', + name: 'qwe' + }) + + projects = await liveQuery.queryFind(test.mixin.TestProjectMixin, {}, { projection: { _id: 1 } }) + expect(projects.length).toEqual(0) + await factory.createMixin(project, test.class.TestProject, core.space.Space, test.mixin.TestProjectMixin, { + someField: 'qwe' + }) + // We need to process all events before we could do query again + await new Promise((resolve) => { + setTimeout(resolve, 100) + }) + projects = await liveQuery.queryFind(test.mixin.TestProjectMixin, {}, { projection: { _id: 1 } }) + expect(projects.length).toEqual(1) + }) }) diff --git a/server/core/src/server/storage.ts b/server/core/src/server/storage.ts index d4e32898f7..df9e42c633 100644 --- a/server/core/src/server/storage.ts +++ b/server/core/src/server/storage.ts @@ -146,7 +146,13 @@ export class TServerStorage implements ServerStorage { findOne: async (_class, query, options) => { return ( await metrics.with('query', {}, async (ctx) => { - return await this.findAll(ctx, _class, query, { ...options, limit: 1 }) + const results = await this.findAll(ctx, _class, query, { ...options, limit: 1 }) + return toFindResult( + results.map((v) => { + return this.hierarchy.updateLookupMixin(_class, v, options) + }), + results.total + ) }) )[0] }, @@ -232,9 +238,7 @@ export class TServerStorage implements ServerStorage { const r = await ctx.with('adapter-tx', { domain: lastDomain }, async (ctx) => await adapter.tx(ctx, ...part)) // Update server live queries. - for (const t of part) { - await this.liveQuery.tx(t) - } + await this.liveQuery.tx(...part) if (Array.isArray(r)) { result.push(...r) } else {