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

correct collections from mongoose.connection instance

Yuki Takei 6 лет назад
Родитель
Сommit
04e4a86835
3 измененных файлов с 24 добавлено и 23 удалено
  1. 2 4
      src/server/routes/apiv3/export.js
  2. 3 2
      src/server/routes/apiv3/mongo.js
  3. 19 17
      src/server/service/export.js

+ 2 - 4
src/server/routes/apiv3/export.js

@@ -42,7 +42,7 @@ module.exports = (crowi) => {
   const adminRequired = require('../../middleware/admin-required')(crowi);
   const adminRequired = require('../../middleware/admin-required')(crowi);
   const csrf = require('../../middleware/csrf')(crowi);
   const csrf = require('../../middleware/csrf')(crowi);
 
 
-  const { growiBridgeService, exportService } = crowi;
+  const { exportService } = crowi;
 
 
   this.adminEvent = crowi.event('admin');
   this.adminEvent = crowi.event('admin');
 
 
@@ -103,10 +103,8 @@ module.exports = (crowi) => {
     // TODO: add express validator
     // TODO: add express validator
     try {
     try {
       const { collections } = req.body;
       const { collections } = req.body;
-      // get model for collection
-      const models = collections.map(collectionName => growiBridgeService.getModelFromCollectionName(collectionName));
 
 
-      exportService.export(models);
+      exportService.export(collections);
 
 
       const status = await exportService.getStatus();
       const status = await exportService.getStatus();
 
 

+ 3 - 2
src/server/routes/apiv3/mongo.js

@@ -3,6 +3,7 @@ const loggerFactory = require('@alias/logger');
 const logger = loggerFactory('growi:routes:apiv3:mongo'); // eslint-disable-line no-unused-vars
 const logger = loggerFactory('growi:routes:apiv3:mongo'); // eslint-disable-line no-unused-vars
 
 
 const express = require('express');
 const express = require('express');
+const mongoose = require('mongoose');
 
 
 const router = express.Router();
 const router = express.Router();
 
 
@@ -33,12 +34,12 @@ module.exports = (crowi) => {
    *                      type: string
    *                      type: string
    */
    */
   router.get('/collections', async(req, res) => {
   router.get('/collections', async(req, res) => {
-    const collections = Object.values(crowi.models).map(model => model.collection.name);
+    const collections = Object.keys(mongoose.connection.collections);
 
 
     // TODO: use res.apiv3
     // TODO: use res.apiv3
     return res.json({
     return res.json({
       ok: true,
       ok: true,
-      collections: [...new Set(collections)], // remove duplicates
+      collections,
     });
     });
   });
   });
 
 

+ 19 - 17
src/server/service/export.js

@@ -1,9 +1,13 @@
 const logger = require('@alias/logger')('growi:services:ExportService'); // eslint-disable-line no-unused-vars
 const logger = require('@alias/logger')('growi:services:ExportService'); // eslint-disable-line no-unused-vars
+
 const fs = require('fs');
 const fs = require('fs');
 const path = require('path');
 const path = require('path');
+const mongoose = require('mongoose');
 const { Transform } = require('stream');
 const { Transform } = require('stream');
 const streamToPromise = require('stream-to-promise');
 const streamToPromise = require('stream-to-promise');
 const archiver = require('archiver');
 const archiver = require('archiver');
+
+
 const toArrayIfNot = require('../../lib/util/toArrayIfNot');
 const toArrayIfNot = require('../../lib/util/toArrayIfNot');
 
 
 
 
@@ -26,10 +30,10 @@ class ExportingStatus {
     this.progressMap = {};
     this.progressMap = {};
   }
   }
 
 
-  async init(models) {
-    const promisesForCreatingInstance = models.map(async(Model) => {
-      const collectionName = Model.collection.name;
-      const totalCount = await Model.countDocuments();
+  async init(collections) {
+    const promisesForCreatingInstance = collections.map(async(collectionName) => {
+      const collection = mongoose.connection.collection(collectionName);
+      const totalCount = await collection.count();
       return new ExportingProgress(collectionName, totalCount);
       return new ExportingProgress(collectionName, totalCount);
     });
     });
     this.progressList = await Promise.all(promisesForCreatingInstance);
     this.progressList = await Promise.all(promisesForCreatingInstance);
@@ -177,15 +181,13 @@ class ExportService {
    * dump a mongodb collection into json
    * dump a mongodb collection into json
    *
    *
    * @memberOf ExportService
    * @memberOf ExportService
-   * @param {object} Model instance of mongoose model
+   * @param {string} collectionName collection name
    * @return {string} path to zip file
    * @return {string} path to zip file
    */
    */
-  async exportCollectionToJson(Model) {
-    const collectionName = Model.collection.name;
+  async exportCollectionToJson(collectionName) {
+    const collection = mongoose.connection.collection(collectionName);
 
 
-    // get native Cursor instance
-    //  cz: Mongoose cursor might cause memory leak
-    const nativeCursor = Model.collection.find();
+    const nativeCursor = collection.find();
     const readStream = nativeCursor
     const readStream = nativeCursor
       .snapshot()
       .snapshot()
       .stream({ transform: JSON.stringify });
       .stream({ transform: JSON.stringify });
@@ -215,14 +217,14 @@ class ExportService {
    * export multiple Collections into json and Zip
    * export multiple Collections into json and Zip
    *
    *
    * @memberOf ExportService
    * @memberOf ExportService
-   * @param {Array.<object>} models array of instances of mongoose model
+   * @param {Array.<string>} collections array of collection name
    * @return {Array.<string>} paths to json files created
    * @return {Array.<string>} paths to json files created
    */
    */
-  async exportCollectionsToZippedJson(models) {
+  async exportCollectionsToZippedJson(collections) {
     const metaJson = await this.createMetaJson();
     const metaJson = await this.createMetaJson();
 
 
-    const promisesForModels = models.map(Model => this.exportCollectionToJson(Model));
-    const jsonFiles = await Promise.all(promisesForModels);
+    const promises = collections.map(collectionName => this.exportCollectionToJson(collectionName));
+    const jsonFiles = await Promise.all(promises);
 
 
     // zip json
     // zip json
     const configs = jsonFiles.map((jsonFile) => { return { from: jsonFile, as: path.basename(jsonFile) } });
     const configs = jsonFiles.map((jsonFile) => { return { from: jsonFile, as: path.basename(jsonFile) } });
@@ -240,16 +242,16 @@ class ExportService {
     // TODO: remove broken zip file
     // TODO: remove broken zip file
   }
   }
 
 
-  async export(models) {
+  async export(collections) {
     if (this.currentExportingStatus != null) {
     if (this.currentExportingStatus != null) {
       throw new Error('There is an exporting process running.');
       throw new Error('There is an exporting process running.');
     }
     }
 
 
     this.currentExportingStatus = new ExportingStatus();
     this.currentExportingStatus = new ExportingStatus();
-    await this.currentExportingStatus.init(models);
+    await this.currentExportingStatus.init(collections);
 
 
     try {
     try {
-      await this.exportCollectionsToZippedJson(models);
+      await this.exportCollectionsToZippedJson(collections);
     }
     }
     finally {
     finally {
       this.currentExportingStatus = null;
       this.currentExportingStatus = null;