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

Merge branch 'feat/pt-dev-2' into feat/update-parent-when-create-page

Taichi Masuyama 4 лет назад
Родитель
Сommit
84e1e229f4

+ 1 - 1
packages/app/src/client/services/AdminAppContainer.js

@@ -452,7 +452,7 @@ export default class AdminAppContainer extends Container {
   /**
    * Start v5 page migration
    * @memberOf AdminAppContainer
-   * @property action takes only 'upgrade' for now. 'upgrade' will start or resume migration
+   * @property action takes only 'initialMigration' for now. 'initialMigration' will start or resume migration
    */
   async v5PageMigrationHandler(action) {
     const response = await this.appContainer.apiv3.post('/pages/v5-schema-migration', { action });

+ 1 - 1
packages/app/src/components/Admin/App/V5PageMigration.tsx

@@ -17,7 +17,7 @@ const V5PageMigration: FC<Props> = (props: Props) => {
   const onConfirm = async() => {
     setIsV5PageMigrationModalShown(false);
     try {
-      const { isV5Compatible } = await adminAppContainer.v5PageMigrationHandler('upgrade');
+      const { isV5Compatible } = await adminAppContainer.v5PageMigrationHandler('initialMigration');
       if (isV5Compatible) {
 
         return toastSuccess(t('admin:v5_page_migration.already_upgraded'));

+ 2 - 2
packages/app/src/server/routes/apiv3/pages.js

@@ -690,11 +690,11 @@ module.exports = (crowi) => {
 
     try {
       switch (action) {
-        case 'upgrade':
+        case 'initialMigration':
           if (!isV5Compatible) {
             const Page = crowi.model('Page');
             // this method throws and emit socketIo event when error occurs
-            crowi.pageService.v5Migration(Page.GRANT_PUBLIC); // not await
+            crowi.pageService.v5InitialMigration(Page.GRANT_PUBLIC); // not await
           }
           break;
 

+ 48 - 36
packages/app/src/server/service/page.js

@@ -738,17 +738,50 @@ class PageService {
     }
   }
 
-  async v5Migration(grant, rootPath = null) {
+  async v5InitialMigration(grant) {
     const socket = this.crowicrowi.socketIoService.getAdminSocket();
     try {
-      await this._v5RecursiveMigration(grant, rootPath);
+      await this._v5RecursiveMigration(grant);
     }
     catch (err) {
-      logger.error('V5 miration failed.', err);
-      socket.emit('v5MirationFailed', { error: err.message });
+      logger.error('V5 initial miration failed.', err);
+      socket.emit('v5InitialMirationFailed', { error: err.message });
 
       throw err;
     }
+
+    const Page = this.crowi.model('Page');
+    const indexStatus = await Page.aggregate([{ $indexStats: {} }]);
+    const pathIndexStatus = indexStatus.filter(status => status.name === 'path_1')?.[0];
+    const isPathIndexExists = pathIndexStatus != null;
+    const isUnique = isPathIndexExists && pathIndexStatus.spec?.unique === true;
+
+    if (isUnique || !isPathIndexExists) {
+      try {
+        await this._v5NormalizeIndex(isPathIndexExists);
+      }
+      catch (err) {
+        logger.error('V5 index normalization failed.', err);
+        socket.emit('v5IndexNormalizationFailed', { error: err.message });
+
+        throw err;
+      }
+    }
+
+    await this._setIsV5CompatibleTrue();
+  }
+
+  async _setIsV5CompatibleTrue() {
+    try {
+      await this.crowi.configManager.updateConfigsInTheSameNamespace('crowi', {
+        'app:isV5Compatible': true,
+      });
+      logger.info('Successfully migrated all public pages.');
+    }
+    catch (err) {
+      logger.warn('Failed to update app:isV5Compatible to true.');
+      throw err;
+    }
   }
 
   // TODO: use websocket to show progress
@@ -854,51 +887,30 @@ class PageService {
       return this.v5RecursiveMigration(grant, rootPath);
     }
 
-    /*
-     * After completed migration
-     */
-    if (grant !== Page.GRANT_PUBLIC) {
-      return;
-    }
+  }
 
+  async _v5NormalizeIndex(isPathIndexExists) {
     const collection = mongoose.connection.collection('pages');
-    const indexStatus = await Page.aggregate([{ $indexStats: {} }]);
-    const pathIndexStatus = indexStatus.filter(status => status.name === 'path_1')?.[0]?.spec?.unique;
-
-    // skip index modification if path is unique
-    if (pathIndexStatus == null || pathIndexStatus === true) {
-      // drop only when true. this condition is for in case createIndex failed but dropIndex succeeded before
-      if (pathIndexStatus) {
-        try {
-          // drop pages.path_1 indexes
-          await collection.dropIndex('path_1');
-          logger.info('Succeeded to drop unique indexes from pages.path.');
-        }
-        catch (err) {
-          logger.warn('Failed to drop unique indexes from pages.path.', err);
-          throw err;
-        }
-      }
 
+    if (isPathIndexExists) {
       try {
-        // create indexes without
-        await collection.createIndex({ path: 1 }, { unique: false });
-        logger.info('Succeeded to create non-unique indexes on pages.path.');
+        // drop pages.path_1 indexes
+        await collection.dropIndex('path_1');
+        logger.info('Succeeded to drop unique indexes from pages.path.');
       }
       catch (err) {
-        logger.warn('Failed to create non-unique indexes on pages.path.', err);
+        logger.warn('Failed to drop unique indexes from pages.path.', err);
         throw err;
       }
     }
 
     try {
-      await this.crowi.configManager.updateConfigsInTheSameNamespace('crowi', {
-        'app:isV5Compatible': true,
-      });
-      logger.info('Successfully migrated all public pages.');
+      // create indexes without
+      await collection.createIndex({ path: 1 }, { unique: false });
+      logger.info('Succeeded to create non-unique indexes on pages.path.');
     }
     catch (err) {
-      logger.warn('Failed to update app:isV5Compatible to true.');
+      logger.warn('Failed to create non-unique indexes on pages.path.', err);
       throw err;
     }
   }