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

refactor ensure latest revision body length

ryoji-s 2 лет назад
Родитель
Сommit
ad2b44d094
2 измененных файлов с 37 добавлено и 62 удалено
  1. 6 12
      apps/app/src/pages/utils/commons.ts
  2. 31 50
      apps/app/src/server/models/page.ts

+ 6 - 12
apps/app/src/pages/utils/commons.ts

@@ -2,7 +2,6 @@ import type { ColorScheme, IUserHasId } from '@growi/core';
 import {
   DevidedPagePath, Lang, AllLang, isServer,
 } from '@growi/core';
-import mongoose from 'mongoose';
 import type { GetServerSideProps, GetServerSidePropsContext } from 'next';
 import type { SSRConfig, UserConfig } from 'next-i18next';
 
@@ -12,7 +11,7 @@ import { detectLocaleFromBrowserAcceptLanguage } from '~/client/util/locale-util
 import type { CrowiRequest } from '~/interfaces/crowi-request';
 import type { ISidebarConfig } from '~/interfaces/sidebar-config';
 import type { IUserUISettings } from '~/interfaces/user-ui-settings';
-import type { PageModel, PageDocument } from '~/server/models/page';
+import type { PageDocument } from '~/server/models/page';
 import type { UserUISettingsDocument } from '~/server/models/user-ui-settings';
 import {
   useCurrentProductNavWidth, useCurrentSidebarContents, usePreferDrawerModeByUser, usePreferDrawerModeOnEditByUser, useSidebarCollapsed,
@@ -173,21 +172,16 @@ export const useInitSidebarConfig = (sidebarConfig: ISidebarConfig, userUISettin
   useCurrentProductNavWidth(userUISettings?.currentProductNavWidth);
 };
 
-async function ensureLatestRevisionBodyLength(page: PageDocument): Promise<number> {
-  if (!page.isLatestRevision() || page.latestRevisionBodyLength == null) {
-    const Page = mongoose.model('Page') as unknown as PageModel;
-    return Page.updateLatestRevisionBodyLength(page._id);
-  }
-
-  return page.latestRevisionBodyLength;
-}
-
 export const skipSSR = async(page: PageDocument): Promise<boolean> => {
   if (!isServer()) {
     throw new Error('This method is not available on the client-side');
   }
 
-  const latestRevisionBodyLength = await ensureLatestRevisionBodyLength(page);
+  const latestRevisionBodyLength = await page.ensureLatestRevisionBodyLength();
+
+  if (latestRevisionBodyLength == null) {
+    return false;
+  }
 
   const { configManager } = await import('~/server/service/config-manager');
   await configManager.loadConfigs();

+ 31 - 50
apps/app/src/server/models/page.ts

@@ -40,6 +40,7 @@ const STATUS_DELETED = 'deleted';
 
 export interface PageDocument extends IPage, Document {
   [x:string]: any // for obsolete methods
+  ensureLatestRevisionBodyLength(): Promise<number | null>
 }
 
 
@@ -722,56 +723,6 @@ export async function pushRevision(pageData, newRevision, user) {
   return pageData.save();
 }
 
-/*
- * add latestRevisionBodyLength fuilds
- */
-schema.statics.updateLatestRevisionBodyLength = async function(pageId: ObjectIdLike): Promise<number> {
-  const pipeline = [
-    {
-      $match: {
-        _id: pageId,
-      },
-    },
-    {
-      $lookup: {
-        from: 'revisions',
-        localField: 'revision',
-        foreignField: '_id',
-        as: 'latestRevisionData',
-      },
-    },
-    {
-      $addFields: {
-        latestRevisionData: { $arrayElemAt: ['$latestRevisionData', 0] },
-      },
-    },
-    {
-      $set: {
-        latestRevisionBodyLength: { $strLenCP: '$latestRevisionData.body' },
-      },
-    },
-    {
-      $project: {
-        latestRevisionData: 0,
-      },
-    },
-  ];
-
-  const result = await this.aggregate(pipeline);
-
-  if (result.length !== 1) {
-    throw new Error('latestRevisionBodyLength is not found');
-  }
-
-  await this.findByIdAndUpdate(pageId, {
-    $set: {
-      latestRevisionBodyLength: result[0].latestRevisionBodyLength,
-    },
-  });
-
-  return result[0].latestRevisionBodyLength;
-};
-
 /**
  * add/subtract descendantCount of pages with provided paths by increment.
  * increment can be negative number
@@ -1009,6 +960,36 @@ schema.statics.findNonEmptyClosestAncestor = async function(path: string): Promi
   return ancestors[0];
 };
 
+export async function calculateAndUpdateLatestRevisionBodyLength(page: PageDocument): Promise<number> {
+  const latestRevisionData = await mongoose.model('Revision').findById(page.revision, { body: 1 });
+
+  if (latestRevisionData == null || typeof latestRevisionData.body !== 'string') {
+    throw new Error('The latest revision body could not be found or is not a string.');
+  }
+
+  const latestRevisionBodyLength = latestRevisionData.body.length;
+
+  page.latestRevisionBodyLength = latestRevisionBodyLength;
+  await page.save();
+
+  return latestRevisionBodyLength;
+}
+
+/*
+ * ensure latest revision body length
+ */
+schema.methods.ensureLatestRevisionBodyLength = async function(this: PageDocument): Promise<number | null> {
+  if (!this.isLatestRevision() || this.revision == null) {
+    return null;
+  }
+
+  if (this.latestRevisionBodyLength == null) {
+    const calculatedLatestRevisionBodyLength = await calculateAndUpdateLatestRevisionBodyLength(this);
+    return calculatedLatestRevisionBodyLength;
+  }
+
+  return this.latestRevisionBodyLength;
+};
 
 export type PageCreateOptions = {
   format?: string