Просмотр исходного кода

implement recountAndUpdateDescendantCount

yohei0125 3 лет назад
Родитель
Сommit
a74e5db688
1 измененных файлов с 44 добавлено и 2 удалено
  1. 44 2
      packages/app/src/server/service/page.ts

+ 44 - 2
packages/app/src/server/service/page.ts

@@ -618,7 +618,7 @@ class PageService {
     }
 
     const {
-      page, toPath, options, user,
+      page, fromPath, toPath, options, user,
     } = pageOp;
 
     // check property
@@ -626,8 +626,17 @@ class PageService {
       throw Error(`Property toPath is missing which is needed to resume page operation(${pageOp._id})`);
     }
 
-    this.renameSubOperation(page, toPath, user, options, renamedPage, pageOp._id);
+    // this want be used only in this method
+    const renameAndRecountDescendantCount = async(
+        page, user, options, renamedPage: PageDocument, pageOpId, fromPath:string, toPath:string,
+    ): Promise<void> => {
+      await this.renameSubOperation(page, toPath, user, options, renamedPage, pageOpId);
+      // get ancestors
+      const ancestors = this.crowi.pageOperationService.getAncestorsPathsByFromAndToPath(fromPath, toPath);
+      await this.recountAndUpdateDescendantCount(ancestors);
+    };
 
+    renameAndRecountDescendantCount(page, user, options, renamedPage, pageOp._id, fromPath, toPath);
   }
 
   private isRenamingToUnderTarget(fromPath: string, toPath: string): boolean {
@@ -3045,6 +3054,39 @@ class PageService {
     return nMigratablePages;
   }
 
+  /**
+   * Todo: need refactoring
+   */
+  async recountAndUpdateDescendantCount(paths: string[]): Promise<void> {
+    const BATCH_SIZE = 200;
+    const Page = this.crowi.model('Page');
+    const { PageQueryBuilder } = Page;
+
+    const builder = new PageQueryBuilder(Page.find(), true);
+    builder.addConditionToListByPathsArray(paths); // find by paths
+    builder.addConditionToSortPagesByDescPath(); // sort in DESC
+
+    const aggregatedPages = await builder.query.lean().cursor({ batchSize: BATCH_SIZE });
+    const recountWriteStream = new Writable({
+      objectMode: true,
+      async write(pageDocuments, encoding, callback) {
+        for await (const document of pageDocuments) {
+          const descendantCount = await Page.recountDescendantCount(document._id);
+          await Page.findByIdAndUpdate(document._id, { descendantCount });
+        }
+        callback();
+      },
+      final(callback) {
+        callback();
+      },
+    });
+    aggregatedPages
+      .pipe(createBatchStream(BATCH_SIZE))
+      .pipe(recountWriteStream);
+
+    await streamToPromise(recountWriteStream);
+  }
+
   /**
    * update descendantCount of the following pages
    * - page that has the same path as the provided path