OpenVeo Core server

API Docs for: 7.0.0
Show:

File: app/server/migration/migrationProcess.js

'use strict';

/**
 * @module core-migration
 */

/**
 * Provides functions to execute migration script.
 *
 * @main core-migration
 * @class migrationProcess
 * @static
 */

var semver = require('semver');
var async = require('async');
var openVeoApi = require('@openveo/api');
var storage = process.require('app/server/storage.js');
var ResourceFilter = openVeoApi.storages.ResourceFilter;

/**
 * Saves in core_system table the last migration successfull done.
 *
 * @method saveMigrationVersion
 * @private
 * @static
 * @param {String} name Name of module (core, publish...)
 * @param {String} version Version of the script successfully executed
 * @param {Object} db DB instance to update value
 * @param {Function} callback callback A callback with 1 arguments :
 *    - **Error** An Error object or null
 */
function saveMigrationVersion(name, version, db, callback) {

  // Find plugin information
  db.getOne('core_system', new ResourceFilter().equal('name', name), null, function(error, pluginInformation) {
    if (error) return callback(error);

    if (!pluginInformation) {

      // Plugin information not found
      // Create it
      db.add(
        'core_system',
        [
          {
            name: name,
            version: version
          }
        ],
        function(error) {
          callback(error);
        }
      );

    } else {

      // Plugin information found
      // Update it
      db.updateOne('core_system', new ResourceFilter().equal('name', name), {version: version}, function(error) {
        callback(error);
      });

    }
  });
}

/**
 * Creates async series according to migration script order.
 *
 * @method createMigrationSeries
 * @private
 * @static
 * @param {Object} module Script collection to execute
 *  exemple: {
 *    1.1.0 : 'path/to/migration/1.1.0.js',
 *    1.2.0 : 'path/to/migration/1.2.0.js'
 *  }
 * @param {String} name Name of module (core, publish...)
 * @return {Array} Array of synchronous function to execute
 */
function createMigrationSeries(module, name) {
  var series = [];
  var db = storage.getDatabase();
  Object.keys(module).sort(semver.compare).forEach(function(version) {
    series.push(function(callback) {

      var migrationUpdate = require(module[version]);
      migrationUpdate.update(function(error) {
        if (error) {
          callback(error);
          return;
        }

        // Call saveMigrationVersion when a migration is successfull
        saveMigrationVersion(name, version, db, callback);
      });
    });
  });
  return series;
}

/**
 * Executes a collection of migration script.
 *
 * @method executeMigrationScript
 * @param {Object} migrations migrations object to execute
 *  exemple:
 *  {
 *    core:{
 *      1.1.0: 'path/to/migration/1.1.0.js',
 *      2.0.0: 'path/to/migration/2.0.0.js'
 *    },
 *    publish:{
 *      1.2.0: 'path/to/migration/1.2.0.js',
 *      1.3.0: 'path/to/migration/1.3.0.js',
 *    }
 *  }
 * @param {Function} callback A callback with 1 arguments :
 *    - **Error** An Error object or null
 */
module.exports.executeMigrationScript = function(migrations, callback) {
  var series = [];

  // Update Core first
  if (migrations.core) {
    var coreSeries = createMigrationSeries(migrations.core, 'core');
    series = series.concat(coreSeries);
    delete migrations.core;
  }

  // For each module
  Object.keys(migrations).forEach(function(moduleKey) {
    var pluginSeries = createMigrationSeries(migrations[moduleKey], moduleKey);
    series = series.concat(pluginSeries);
  });

  async.series(series, function(error) {
    if (error) {
      process.logger.error(error && error.message);
      throw new Error(error);
    }

    if (series.length) process.logger.info('All migration done with success');
    else process.logger.info('No migration needed - Database is up to date');
    callback();
  });
};