all files / lib/ DatabaseManager.js

83.33% Statements 35/42
83.33% Branches 5/6
53.33% Functions 8/15
83.33% Lines 35/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171                           14× 14×                                                                                                                                                                           15× 15×                         12× 12×                           28× 10× 10× 10×   18×           56× 10×   56×            
var _ = require('lodash')
  , Knex = require('knex')
  , Promise = require('bluebird')
  , multiRequire = require('./multi-require').multiRequire;
 
/**
 * Base class for database managers.
 *
 * Database manager is used to create/drop databases, run migrations for them and doing other "super user" stuff.
 *
 * @constructor
 * @param {object} config
 *    Database configuration. See `index.js` for example config and `database` feature for further description.
 */
function DatabaseManager(config) {
  this.config = config;
  this._knex = null;
}
 
/**
 * Creates user which is used to access the database described in knex configuration.
 *
 * @returns {Promise} Resolves if success reject if user could not be created for some reason.
 */
DatabaseManager.prototype.createDbOwnerIfNotExist = function() {
  throw new Error(this.constructor.name + '.createDbOwner not implemented');
};
 
/**
 * Creates and initializes a database `databaseName`.
 *
 * Rejects promise if databaseName already exists or could not
 * be created.
 *
 * @param {String=} databaseName if not given, database from knex config is used
 * @returns {Promise}
 */
DatabaseManager.prototype.createDb = function(databaseName) {
  throw new Error(this.constructor.name + '.initDb not implemented');
};
 
/**
 * Drops the database `databaseName`.
 *
 * @param {String=} databaseName
 * @returns {Promise}
 */
DatabaseManager.prototype.dropDb = function(databaseName) {
  throw new Error(this.constructor.name + '.dropDb not implemented');
};
 
/**
 * Makes copy of database.
 *
 * Good for backing up stuff before running migrations etc.
 *
 * @param {String} fromDatabaseName
 * @param {String} toDatabaseName
 * @returns {Promise}
 */
DatabaseManager.prototype.copyDb = function(fromDatabaseName, toDatabaseName) {
  throw new Error(this.constructor.name + '.copyDb not implemented');
};
 
/**
 * Truncates all tables in the database from knex configuration and also resets all
 * sequences.
 *
 * @returns {Promise}
 */
DatabaseManager.prototype.truncateDb = function(ignoreTables) {
  throw new Error(this.constructor.name + '.truncateDb not implemented');
};
 
/**
 * Updates the primary key sequences for all tables so that next insert selects
 * correct id (one that does not conflict with previous ids and is valid).
 *
 * This means that the next id will be greater (by 1) than currently largest
 * id in the table. If the table is empty, minimum value for the key sequence
 * will be used instead.
 *
 * This function assumes that the primary key for each table is called `id`.
 *
 * @returns {Promise}
 */
DatabaseManager.prototype.updateIdSequences = function() {
  throw new Error(this.constructor.name + '.updateIdSequences not implemented');
};
 
/**
 * Populate database.
 *
 * @param {String=} populatePathPattern
 * @returns {Promise}
 */
DatabaseManager.prototype.populateDb = function(populatePathPattern) {
  populatePathPattern = populatePathPattern || this.config.populatePathPattern;
 
  var knex = this.knexInstance();
  var modules = multiRequire(populatePathPattern).filterModule(_.isFunction).require();
 
  return Promise
    .all(_.map(modules, function (module) {
      return knex.transaction(function (trx) {
        return module.module(trx);
      });
    }));
};
 
/**
 * Runs migrations for database in knex config.
 *
 * @returns {Promise}
 */
DatabaseManager.prototype.migrateDb = function() {
  var knex = this.knexInstance();
  return knex.migrate.latest();
};
 
/**
 * Gets the migration version of the database of knex config.
 *
 * If no migrations run returns 'none'
 * Otherwise returns first numbers of latest migration file ran
 * e.g. for 20141024070315_test_schema.js version will be
 * '20141024070315'
 *
 * @returns {Promise}
 */
DatabaseManager.prototype.dbVersion = function() {
  var knex = this.knexInstance();
  return knex.migrate.currentVersion();
};
 
/**
 * Closes all connections made by the the manager.
 *
 * @returns {Promise}
 */
DatabaseManager.prototype.close = function() {
  throw new Error(this.constructor.name + '.close not implemented');
};
 
/**
 * Closes connection made with knex directly to certain database
 */
DatabaseManager.prototype.closeKnex = function() {
  if (this._knex) {
    knex = this._knex;
    this._knex = null;
    return knex.destroy();
  }
  return Promise.resolve();
};
 
/**
 * @return {QueryBuilder} Knex query builder for knex configuration.
 */
DatabaseManager.prototype.knexInstance = function() {
  if (!this._knex) {
    this._knex = Knex(this.config.knex);
  }
  return this._knex;
};
 
module.exports = {
  default: DatabaseManager,
  DatabaseManager: DatabaseManager
}