From 96b81eabef582ef6c9df6ad2402233b8757ad492 Mon Sep 17 00:00:00 2001
From: Andrey Sobolev <haiodo@users.noreply.github.com>
Date: Thu, 15 Feb 2024 22:18:09 +0700
Subject: [PATCH] UBERF-5538: Fix server queryFind with mixins (#4653)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
---
 packages/query/src/index.ts | 11 +++++++++++
 server/core/src/storage.ts  | 21 ++++++++++++++-------
 server/mongo/src/storage.ts | 15 +++++----------
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/packages/query/src/index.ts b/packages/query/src/index.ts
index a1285a35fd..283d5d6f0b 100644
--- a/packages/query/src/index.ts
+++ b/packages/query/src/index.ts
@@ -180,6 +180,7 @@ export class LiveQuery extends TxProcessor implements Client {
       options.projection = {
         ...options.projection,
         _class: 1,
+        space: 1,
         modifiedOn: 1
       }
     }
@@ -209,6 +210,7 @@ export class LiveQuery extends TxProcessor implements Client {
       options.projection = {
         ...options.projection,
         _class: 1,
+        space: 1,
         modifiedOn: 1
       }
     }
@@ -341,6 +343,7 @@ export class LiveQuery extends TxProcessor implements Client {
       options.projection = {
         ...options.projection,
         _class: 1,
+        space: 1,
         modifiedOn: 1
       }
     }
@@ -362,6 +365,14 @@ export class LiveQuery extends TxProcessor implements Client {
     query: DocumentQuery<T>,
     options?: FindOptions<T>
   ): Promise<FindResult<T>> {
+    if (options?.projection !== undefined) {
+      options.projection = {
+        ...options.projection,
+        _class: 1,
+        space: 1,
+        modifiedOn: 1
+      }
+    }
     const current = this.findQuery(_class, query, options)
     if (current === undefined) {
       const q = this.createQuery(
diff --git a/server/core/src/storage.ts b/server/core/src/storage.ts
index 2a107ed5b2..964771568b 100644
--- a/server/core/src/storage.ts
+++ b/server/core/src/storage.ts
@@ -55,7 +55,8 @@ import core, {
   WorkspaceEvent,
   WorkspaceId,
   WorkspaceIdWithUrl,
-  generateId
+  generateId,
+  toFindResult
 } from '@hcengineering/core'
 import { MinioService } from '@hcengineering/minio'
 import { Metadata, getResource } from '@hcengineering/platform'
@@ -143,15 +144,21 @@ class TServerStorage implements ServerStorage {
       },
       close: async () => {},
       findAll: async (_class, query, options) => {
-        return await metrics.with('query', {}, async (ctx) => await this.findAll(ctx, _class, query, options))
+        return await metrics.with('query', {}, async (ctx) => {
+          const results = await this.findAll(ctx, _class, query, options)
+          return toFindResult(
+            results.map((v) => {
+              return this.hierarchy.updateLookupMixin(_class, v, options)
+            }),
+            results.total
+          )
+        })
       },
       findOne: async (_class, query, options) => {
         return (
-          await metrics.with(
-            'query',
-            {},
-            async (ctx) => await this.findAll(ctx, _class, query, { ...options, limit: 1 })
-          )
+          await metrics.with('query', {}, async (ctx) => {
+            return await this.findAll(ctx, _class, query, { ...options, limit: 1 })
+          })
         )[0]
       },
       tx: async (tx) => {
diff --git a/server/mongo/src/storage.ts b/server/mongo/src/storage.ts
index 2f8ad3599a..917ba058e3 100644
--- a/server/mongo/src/storage.ts
+++ b/server/mongo/src/storage.ts
@@ -16,7 +16,6 @@
 import core, {
   DOMAIN_MODEL,
   DOMAIN_TX,
-  MeasureMetricsContext,
   SortingOrder,
   TxProcessor,
   cutObjectArray,
@@ -112,13 +111,9 @@ abstract class MongoAdapterBase implements DbAdapter {
 
   async init (): Promise<void> {}
 
-  async toArray<T>(ctx: MeasureContext, cursor: AbstractCursor<T>): Promise<T[]> {
-    const st = Date.now()
+  async toArray<T>(cursor: AbstractCursor<T>): Promise<T[]> {
     const data = await cursor.toArray()
     await cursor.close()
-    if (Date.now() - st > 1000) {
-      console.error('toArray', Date.now() - st, data.length)
-    }
     return data
   }
 
@@ -480,7 +475,7 @@ abstract class MongoAdapterBase implements DbAdapter {
     const result: WithLookup<T>[] = []
     let total = options?.total === true ? 0 : -1
     try {
-      const rres = await ctx.with('toArray', {}, async (ctx) => await this.toArray(ctx, cursor), {
+      const rres = await ctx.with('toArray', {}, async (ctx) => await this.toArray(cursor), {
         domain,
         pipeline
       })
@@ -626,7 +621,7 @@ abstract class MongoAdapterBase implements DbAdapter {
 
     // Error in case of timeout
     try {
-      const res: T[] = await ctx.with('toArray', {}, async (ctx) => await this.toArray(ctx, cursor), {
+      const res: T[] = await ctx.with('toArray', {}, async (ctx) => await this.toArray(cursor), {
         mongoQuery,
         options,
         domain
@@ -795,7 +790,7 @@ abstract class MongoAdapterBase implements DbAdapter {
       return []
     }
     const cursor = this.db.collection<Doc>(domain).find<Doc>({ _id: { $in: docs } }, { limit: docs.length })
-    const result = await this.toArray(new MeasureMetricsContext('', {}), cursor)
+    const result = await this.toArray(cursor)
     return this.stripHash(this.stripHash(result))
   }
 
@@ -1262,7 +1257,7 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter {
       .collection(DOMAIN_TX)
       .find<Tx>({ objectSpace: core.space.Model })
       .sort({ _id: 1, modifiedOn: 1 })
-    const model = await this.toArray(new MeasureMetricsContext('', {}), cursor)
+    const model = await this.toArray(cursor)
     // We need to put all core.account.System transactions first
     const systemTx: Tx[] = []
     const userTx: Tx[] = []