UNPKG

abstract-migrate

Version:
529 lines (413 loc) 17 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.framework = exports.needsToRun = exports.run = exports.loadFromFs = exports.DIRECTION_ROLLBACK = exports.DIRECTION_DOWN = exports.DIRECTION_UP = undefined; var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); var _intro, _nothing; var loadFromFs = exports.loadFromFs = function () { var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(migrationPath) { return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: return _context.abrupt('return', new _promise2.default(function (resolve, reject) { _fs2.default.readdir(migrationPath, function (err, files) { if (err) { reject(err); } else { resolve(files.filter(function (file) { return file.match(/^\d+-[\w\d_-]+\.js$/); }).map(function (file) { return file.slice(0, -3); }).sort()); } }); })); case 1: case 'end': return _context.stop(); } } }, _callee, this); })); return function loadFromFs(_x) { return _ref.apply(this, arguments); }; }(); var run = exports.run = function () { var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(filename, direction, timestamp) { var migration; return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: migration = require(_path2.default.join(_config2.default.migrationPath, filename)); if (!(direction === DIRECTION_UP)) { _context2.next = 6; break; } _context2.next = 4; return (0, _promise3.promiseback)(migration.up); case 4: _context2.next = 12; break; case 6: if (!(direction === DIRECTION_DOWN || direction === DIRECTION_ROLLBACK)) { _context2.next = 11; break; } _context2.next = 9; return (0, _promise3.promiseback)(migration.down); case 9: _context2.next = 12; break; case 11: throw new Error('Unknown migration direction'); case 12: return _context2.abrupt('return', { name: filename, timestamp: timestamp }); case 13: case 'end': return _context2.stop(); } } }, _callee2, this); })); return function run(_x2, _x3, _x4) { return _ref2.apply(this, arguments); }; }(); var needsToRun = exports.needsToRun = function () { var _ref12 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(direction, options) { var ranMigrations, files; return _regenerator2.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return _storage2.default.load(); case 2: ranMigrations = _context3.sent; // Sort the ran migrations by their name -- newest migration first ranMigrations.sort(function (_ref13, _ref14) { var left = _ref13.name; var right = _ref14.name; return right.localeCompare(left); }); _context3.next = 6; return loadFromFs(_config2.default.migrationPath); case 6: files = _context3.sent; _context3.t0 = direction; _context3.next = _context3.t0 === DIRECTION_UP ? 10 : _context3.t0 === DIRECTION_DOWN ? 11 : _context3.t0 === DIRECTION_ROLLBACK ? 12 : 13; break; case 10: return _context3.abrupt('return', filterUp(ranMigrations, files, options)); case 11: return _context3.abrupt('return', filterDown(ranMigrations, files, options)); case 12: return _context3.abrupt('return', filterRollback(ranMigrations, files, options)); case 13: throw new Error('Unknown migration direct \'' + direction); case 14: case 'end': return _context3.stop(); } } }, _callee3, this); })); return function needsToRun(_x5, _x6) { return _ref12.apply(this, arguments); }; }(); var framework = exports.framework = function () { var _ref15 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6(direction, name, options) { var _this = this; var t, UP, needsLock, lockAcquired, _ret2; return _regenerator2.default.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: t = mapWords(direction); UP = direction === DIRECTION_UP; needsLock = !options.dryRun; console.log(_chalk2.default.gray(t('intro'))); if (!needsLock) { _context6.next = 11; break; } _context6.next = 7; return _storage2.default.acquireLock(); case 7: lockAcquired = _context6.sent; if (lockAcquired) { _context6.next = 11; break; } console.log(_chalk2.default.yellow.bold('Could not lock') + _chalk2.default.yellow(' Lock could not be acquired, quitting')); return _context6.abrupt('return'); case 11: _context6.prev = 11; return _context6.delegateYield(_regenerator2.default.mark(function _callee5() { var nameValue, migrationsToRun, now, ranMigrations; return _regenerator2.default.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: nameValue = (0, _arguments.nameOrNumber)(name); _context5.next = 3; return needsToRun(direction, { ignorePast: UP ? options.ignorePast : undefined, only: !!options.only, until: typeof nameValue !== 'number' ? nameValue : null, count: typeof nameValue === 'number' ? nameValue : null }); case 3: migrationsToRun = _context5.sent; if (migrationsToRun.length) { _context5.next = 7; break; } console.log(t('nothing')); return _context5.abrupt('return', { v: void 0 }); case 7: if (!options.dryRun) { _context5.next = 11; break; } console.log(_chalk2.default.yellow.bold('Dry run') + _chalk2.default.yellow(' No migrations will be executed')); migrationsToRun.forEach(function (file) { console.log('[✓] ' + _chalk2.default.cyan(file)); }); return _context5.abrupt('return', { v: void 0 }); case 11: // Record time once so rollback functions properly now = Date.now(); // Run the migrations serially _context5.next = 14; return (0, _promise3.mapSeries)(migrationsToRun, function () { var _ref16 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4(file) { var migration; return _regenerator2.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.prev = 0; _context4.next = 3; return run(file, direction, now); case 3: migration = _context4.sent; console.log('[✓] ' + _chalk2.default.cyan(file)); return _context4.abrupt('return', migration); case 8: _context4.prev = 8; _context4.t0 = _context4['catch'](0); console.log('[✘] ' + _chalk2.default.red(file)); console.log(_chalk2.default.yellow.bold('Migration failed!') + _chalk2.default.yellow(' Your database may be in an invalid state.')); throw _context4.t0; case 13: case 'end': return _context4.stop(); } } }, _callee4, _this, [[0, 8]]); })); return function (_x10) { return _ref16.apply(this, arguments); }; }()); case 14: ranMigrations = _context5.sent; if (!UP) { _context5.next = 20; break; } _context5.next = 18; return _storage2.default.add(ranMigrations.slice().reverse()); case 18: _context5.next = 22; break; case 20: _context5.next = 22; return _storage2.default.remove(ranMigrations); case 22: case 'end': return _context5.stop(); } } }, _callee5, _this); })(), 't0', 13); case 13: _ret2 = _context6.t0; if (!((typeof _ret2 === 'undefined' ? 'undefined' : (0, _typeof3.default)(_ret2)) === "object")) { _context6.next = 16; break; } return _context6.abrupt('return', _ret2.v); case 16: _context6.prev = 16; if (!needsLock) { _context6.next = 20; break; } _context6.next = 20; return _storage2.default.releaseLock(); case 20: return _context6.finish(16); case 21: case 'end': return _context6.stop(); } } }, _callee6, this, [[11,, 16, 21]]); })); return function framework(_x7, _x8, _x9) { return _ref15.apply(this, arguments); }; }(); exports.filterUp = filterUp; exports.filterDown = filterDown; exports.filterRollback = filterRollback; var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk); var _config = require('../config'); var _config2 = _interopRequireDefault(_config); var _storage = require('./storage'); var _storage2 = _interopRequireDefault(_storage); var _arguments = require('./arguments'); var _promise3 = require('./promise'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DIRECTION_UP = exports.DIRECTION_UP = 'direction/up'; var DIRECTION_DOWN = exports.DIRECTION_DOWN = 'direction/down'; var DIRECTION_ROLLBACK = exports.DIRECTION_ROLLBACK = 'direction/rollback'; function filterUp(ranMigrations, files, _ref3) { var _ref3$ignorePast = _ref3.ignorePast, ignorePast = _ref3$ignorePast === undefined ? false : _ref3$ignorePast, until = _ref3.until, count = _ref3.count, only = _ref3.only; var migrationsToRun = void 0; if (!ranMigrations.length) { // We have no ran migrations, run them all! migrationsToRun = files; } else if (ignorePast) { (function () { // Only grab migrations since the most recently ran var timestamp = ranMigrations[0].name.match(/^(\d+)-/)[1]; migrationsToRun = files.filter(function (filename) { return filename.match(/^(\d+)-/)[1] > timestamp; }); })(); } else { // Grab all of the unran migrations migrationsToRun = files.filter(function (file) { return !ranMigrations.find(function (migration) { return file === migration.name; }); }); } // If we're requesting a specific migration, check for validity and return if (only) { if (!until) { throw new Error('A migration name must be provided with the --only flag'); } return migrationsToRun.filter(function (file) { return file === until; }); } if (until) { return migrationsToRun.filter(function (file) { return file <= until; }); } if (count) { return migrationsToRun.slice(0, count); } return migrationsToRun; } function filterDown(ranMigrations, files, _ref4) { var until = _ref4.until, count = _ref4.count, only = _ref4.only; if (!ranMigrations) { return []; } var migrationsToRun = void 0; if (only) { if (!until) { throw new Error('A migration name must be provided with the --only flag'); } migrationsToRun = ranMigrations.filter(function (_ref5) { var name = _ref5.name; return name === until; }); } else if (count) { migrationsToRun = ranMigrations.slice(0, count); } else if (until) { migrationsToRun = ranMigrations.filter(function (_ref6) { var name = _ref6.name; return name >= until; }); } else { throw new Error('A downward migration requires either a migration name or count'); } migrationsToRun = migrationsToRun.map(function (_ref7) { var name = _ref7.name; return name; }); migrationsToRun.forEach(function (migration) { if (files.indexOf(migration) === -1) { throw new Error('Migration \'' + migration + '\' cannot be downgraded because it does not have a migration file'); } }); return migrationsToRun; } function filterRollback(ranMigrations, files) { if (!ranMigrations || !ranMigrations.length) { return []; } var ranMigrationsByDate = ranMigrations.slice().sort(function (_ref8, _ref9) { var left = _ref8.timestamp; var right = _ref9.timestamp; return right - left; }); var migrationsToRun = ranMigrationsByDate.filter(function (_ref10) { var timestamp = _ref10.timestamp; return timestamp === ranMigrationsByDate[0].timestamp; }).map(function (_ref11) { var name = _ref11.name; return name; }).sort().reverse(); migrationsToRun.forEach(function (migration) { if (files.indexOf(migration) === -1) { throw new Error('Migration \'' + migration + '\' cannot be downgraded because it does not have a migration file'); } }); return migrationsToRun; } var wordMap = { intro: (_intro = {}, (0, _defineProperty3.default)(_intro, DIRECTION_UP, 'Running migrations'), (0, _defineProperty3.default)(_intro, DIRECTION_DOWN, 'Running down migrations'), (0, _defineProperty3.default)(_intro, DIRECTION_ROLLBACK, 'Rolling back migrations'), _intro), nothing: (_nothing = {}, (0, _defineProperty3.default)(_nothing, DIRECTION_UP, 'There are no pending migrations'), (0, _defineProperty3.default)(_nothing, DIRECTION_DOWN, 'There are no migrations to run down'), (0, _defineProperty3.default)(_nothing, DIRECTION_ROLLBACK, 'There are no migrations to roll back'), _nothing) }; var mapWords = function mapWords(direction) { return function (topic) { return wordMap[topic][direction]; }; };