Bläddra i källkod

add new query condition and replace raw codes

yohei0125 3 år sedan
förälder
incheckning
c67605bf0a
2 ändrade filer med 19 tillägg och 22 borttagningar
  1. 11 17
      packages/app/src/server/models/page.ts
  2. 8 5
      packages/app/src/server/service/page.ts

+ 11 - 17
packages/app/src/server/models/page.ts

@@ -21,7 +21,7 @@ import { getPageSchema, extractToAncestorsPaths, populateDataToShowRevision } fr
 import { PageRedirectModel } from './page-redirect';
 import { PageRedirectModel } from './page-redirect';
 
 
 const { addTrailingSlash, normalizePath } = pathUtils;
 const { addTrailingSlash, normalizePath } = pathUtils;
-const { isTopPage, collectAncestorPaths } = pagePathUtils;
+const { isTopPage, collectAncestorPaths, hasSlash } = pagePathUtils;
 
 
 const logger = loggerFactory('growi:models:page');
 const logger = loggerFactory('growi:models:page');
 /*
 /*
@@ -114,22 +114,6 @@ const schema = new Schema<PageDocument, PageModel>({
 schema.plugin(mongoosePaginate);
 schema.plugin(mongoosePaginate);
 schema.plugin(uniqueValidator);
 schema.plugin(uniqueValidator);
 
 
-export const hasSlash = (str: string): boolean => {
-  return str.includes('/');
-};
-
-/*
- * Generate RegExp instance for one level lower path
- */
-export const generateChildrenRegExp = (path: string): RegExp => {
-  // https://regex101.com/r/laJGzj/1
-  // ex. /any_level1
-  if (isTopPage(path)) return new RegExp(/^\/[^/]+$/);
-
-  // https://regex101.com/r/mrDJrx/1
-  // ex. /parent/any_child OR /any_level1
-  return new RegExp(`^${path}(\\/[^/]+)\\/?$`);
-};
 
 
 export class PageQueryBuilder {
 export class PageQueryBuilder {
 
 
@@ -436,6 +420,16 @@ export class PageQueryBuilder {
     return this;
     return this;
   }
   }
 
 
+  addConditionToListByRegexp(regexp) {
+    this.query = this.query
+      .and({
+        path: {
+          $in: regexp,
+        },
+      });
+    return this;
+  }
+
   addConditionToListByPageIdsArray(pageIds) {
   addConditionToListByPageIdsArray(pageIds) {
     this.query = this.query
     this.query = this.query
       .and({
       .and({

+ 8 - 5
packages/app/src/server/service/page.ts

@@ -22,7 +22,7 @@ import { IUserHasId } from '~/interfaces/user';
 import { PageMigrationErrorData, SocketEventName, UpdateDescCountRawData } from '~/interfaces/websocket';
 import { PageMigrationErrorData, SocketEventName, UpdateDescCountRawData } from '~/interfaces/websocket';
 import { stringifySnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
 import { stringifySnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
 import {
 import {
-  CreateMethod, PageCreateOptions, PageModel, PageDocument, PageQueryBuilder, addViewerCondition, generateChildrenRegExp, hasSlash,
+  CreateMethod, PageCreateOptions, PageModel, PageDocument, PageQueryBuilder, addViewerCondition,
 } from '~/server/models/page';
 } from '~/server/models/page';
 import { createBatchStream } from '~/server/util/batch-stream';
 import { createBatchStream } from '~/server/util/batch-stream';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -41,7 +41,7 @@ const debug = require('debug')('growi:services:page');
 const logger = loggerFactory('growi:services:page');
 const logger = loggerFactory('growi:services:page');
 const {
 const {
   isTrashPage, isTopPage, omitDuplicateAreaPageFromPages,
   isTrashPage, isTopPage, omitDuplicateAreaPageFromPages,
-  collectAncestorPaths, isMovablePage, canMoveByPath,
+  collectAncestorPaths, isMovablePage, canMoveByPath, hasSlash, generateChildrenRegExp,
 } = pagePathUtils;
 } = pagePathUtils;
 
 
 const { addTrailingSlash } = pathUtils;
 const { addTrailingSlash } = pathUtils;
@@ -3089,14 +3089,16 @@ class PageService {
   async findChildrenByParentPathOrIdAndViewer(parentPathOrId: string, user, userGroups = null): Promise<PageDocument[]> {
   async findChildrenByParentPathOrIdAndViewer(parentPathOrId: string, user, userGroups = null): Promise<PageDocument[]> {
     const Page = mongoose.model('Page') as unknown as PageModel;
     const Page = mongoose.model('Page') as unknown as PageModel;
     let queryBuilder: PageQueryBuilder;
     let queryBuilder: PageQueryBuilder;
+    queryBuilder = new PageQueryBuilder(Page.find(), true);
     if (hasSlash(parentPathOrId)) {
     if (hasSlash(parentPathOrId)) {
       const path = parentPathOrId;
       const path = parentPathOrId;
       const regexp = generateChildrenRegExp(path);
       const regexp = generateChildrenRegExp(path);
-      queryBuilder = new PageQueryBuilder(Page.find({ path: { $regex: regexp } }), true);
+      queryBuilder.addConditionToListByRegexp(regexp);
     }
     }
     else {
     else {
       const parentId = parentPathOrId;
       const parentId = parentPathOrId;
       queryBuilder = new PageQueryBuilder(Page.find({ parent: parentId } as any), true); // TODO: improve type
       queryBuilder = new PageQueryBuilder(Page.find({ parent: parentId } as any), true); // TODO: improve type
+      queryBuilder.addConditionToFilteringByParentId(parentId);
     }
     }
     await addViewerCondition(queryBuilder, user, userGroups);
     await addViewerCondition(queryBuilder, user, userGroups);
 
 
@@ -3110,12 +3112,13 @@ class PageService {
   async findAncestorsChildrenByPathAndViewer(path: string, user, userGroups = null): Promise<Record<string, PageDocument[]>> {
   async findAncestorsChildrenByPathAndViewer(path: string, user, userGroups = null): Promise<Record<string, PageDocument[]>> {
     const Page = mongoose.model('Page') as unknown as PageModel;
     const Page = mongoose.model('Page') as unknown as PageModel;
     const ancestorPaths = isTopPage(path) ? ['/'] : collectAncestorPaths(path); // root path is necessary for rendering
     const ancestorPaths = isTopPage(path) ? ['/'] : collectAncestorPaths(path); // root path is necessary for rendering
-    const regexps = ancestorPaths.map(path => new RegExp(generateChildrenRegExp(path))); // cannot use re2
+    const regexp = ancestorPaths.map(path => new RegExp(generateChildrenRegExp(path))); // cannot use re2
 
 
     // get pages at once
     // get pages at once
-    const queryBuilder = new PageQueryBuilder(Page.find({ path: { $in: regexps } }), true);
+    const queryBuilder = new PageQueryBuilder(Page.find(), true);
     await addViewerCondition(queryBuilder, user, userGroups);
     await addViewerCondition(queryBuilder, user, userGroups);
     const _pages = await queryBuilder
     const _pages = await queryBuilder
+      .addConditionToListByRegexp(regexp)
       .addConditionAsMigrated()
       .addConditionAsMigrated()
       .addConditionToMinimizeDataForRendering()
       .addConditionToMinimizeDataForRendering()
       .addConditionToSortPagesByAscPath()
       .addConditionToSortPagesByAscPath()