mysql-node-migrator
Version:
A database change management tool for nodejs and mysql
307 lines (232 loc) • 9.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var applyMigration = function () {
var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(connection, migrationScript) {
var queries, i, query;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
queries = _fileHelper2.default.readAndParseScript(migrationScript);
_context.prev = 1;
_context.next = 4;
return connection.beginTransaction();
case 4:
i = 0;
case 5:
if (!(i < queries.length)) {
_context.next = 13;
break;
}
query = queries[i];
Logger.info('trying to execute query: ' + query);
// eslint-disable-next-line no-await-in-loop
_context.next = 10;
return connection.query(query);
case 10:
i += 1;
_context.next = 5;
break;
case 13:
_context.next = 15;
return _databaseHelper2.default.insertMigrationInformation(connection, migrationScript);
case 15:
_context.next = 17;
return connection.commit();
case 17:
Logger.info('migration [' + migrationScript.version + '][' + migrationScript.name + '] successfully applied');
_context.next = 26;
break;
case 20:
_context.prev = 20;
_context.t0 = _context['catch'](1);
Logger.error('cannot execute query. Reason [' + _context.t0.message + ']');
_context.next = 25;
return connection.rollback();
case 25:
throw _context.t0;
case 26:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[1, 20]]);
}));
return function applyMigration(_x, _x2) {
return _ref.apply(this, arguments);
};
}();
/**
* Sorts the migrations from file system and filters already executed ones.
*
* @param connection {Connection}
* @param migrationsFromFileSystem {string[]}
* @return {Promise<object[]>}
*/
var getMigrationsToExecute = function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(connection, migrationsFromFileSystem) {
var existingMigrations;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return _databaseHelper2.default.getExistingMigrations(connection);
case 2:
existingMigrations = _context2.sent;
return _context2.abrupt('return', migrationsFromFileSystem.sort(function (a, b) {
return a.version - b.version;
}).filter(function (mScript) {
return !existingMigrations.some(function (m) {
return m.version === mScript.version;
});
}));
case 4:
case 'end':
return _context2.stop();
}
}
}, _callee2, this);
}));
return function getMigrationsToExecute(_x3, _x4) {
return _ref2.apply(this, arguments);
};
}();
/**
*
* @param connection {Connection} - to work with database
* @param migrationsToExecute {object[]} - all existed migrations data
*/
var _promiseMysql = require('promise-mysql');
var _promiseMysql2 = _interopRequireDefault(_promiseMysql);
var _logger = require('./logger');
var _logger2 = _interopRequireDefault(_logger);
var _fileHelper = require('./fileHelper');
var _fileHelper2 = _interopRequireDefault(_fileHelper);
var _databaseHelper = require('./databaseHelper');
var _databaseHelper2 = _interopRequireDefault(_databaseHelper);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var Logger = void 0;
function executeMigrations(connection, migrationsToExecute) {
// Make our forEach async functions synchronous
return migrationsToExecute.reduce(function (promiseChain, migrationScript) {
return promiseChain.then(function () {
return applyMigration(connection, migrationScript);
});
}, Promise.resolve());
}
// noinspection JSUnusedGlobalSymbols
/**
* parse file name {version, name}
*
* @param connectionOptions
* @param {Object} options Other options
* @param {string} options.folder
* @param {function} [options.loggingFunction=console] The logging function to use
* @param {boolean} [options.shouldLog=true] If the script shall write logging information
* @return {Promise} Whether or not the migration was successful
*/
exports.default = function () {
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee3(connectionOptions, options) {
var folder, _options$loggingFunct, loggingFunction, _options$shouldLog, shouldLog, connection, migrations, migrationsToExecute;
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
folder = options.folder, _options$loggingFunct = options.loggingFunction, loggingFunction = _options$loggingFunct === undefined ? console : _options$loggingFunct, _options$shouldLog = options.shouldLog, shouldLog = _options$shouldLog === undefined ? true : _options$shouldLog;
Logger = (0, _logger2.default)(loggingFunction, shouldLog);
connection = void 0;
_context3.prev = 3;
Logger.info('initiating migration');
_context3.prev = 5;
_context3.next = 8;
return _promiseMysql2.default.createConnection(connectionOptions);
case 8:
connection = _context3.sent;
Logger.info('connected to db');
_context3.next = 16;
break;
case 12:
_context3.prev = 12;
_context3.t0 = _context3['catch'](5);
Logger.error('could not connect to db: ' + _context3.t0.message);
throw _context3.t0;
case 16:
_context3.prev = 16;
_context3.next = 19;
return _databaseHelper2.default.insertTable(connection);
case 19:
_context3.next = 25;
break;
case 21:
_context3.prev = 21;
_context3.t1 = _context3['catch'](16);
Logger.error('could not create sql migrations table: ' + _context3.t1.message);
throw _context3.t1;
case 25:
migrations = void 0;
_context3.prev = 26;
_context3.next = 29;
return _fileHelper2.default.readMigrations(folder, Logger);
case 29:
migrations = _context3.sent;
_context3.next = 36;
break;
case 32:
_context3.prev = 32;
_context3.t2 = _context3['catch'](26);
Logger.error('could not read migrations: ' + _context3.t2.message);
throw _context3.t2;
case 36:
migrationsToExecute = void 0;
_context3.prev = 37;
_context3.next = 40;
return getMigrationsToExecute(connection, migrations);
case 40:
migrationsToExecute = _context3.sent;
Logger.info('wanting to execute [' + migrationsToExecute.length + '] migrations');
_context3.next = 48;
break;
case 44:
_context3.prev = 44;
_context3.t3 = _context3['catch'](37);
Logger.error('could not filter migrations to execute: ' + _context3.t3.message);
throw _context3.t3;
case 48:
_context3.prev = 48;
_context3.next = 51;
return executeMigrations(connection, migrationsToExecute);
case 51:
Logger.info('all migrations successfully applied to database');
_context3.next = 58;
break;
case 54:
_context3.prev = 54;
_context3.t4 = _context3['catch'](48);
Logger.error('could not process migrations: ' + _context3.t4.message);
throw _context3.t4;
case 58:
Logger.info('finished migration');
case 59:
_context3.prev = 59;
if (connection) {
connection.end();
}
return _context3.finish(59);
case 62:
case 'end':
return _context3.stop();
}
}
}, _callee3, this, [[3,, 59, 62], [5, 12], [16, 21], [26, 32], [37, 44], [48, 54]]);
}));
return function (_x5, _x6) {
return _ref3.apply(this, arguments);
};
}();
//# sourceMappingURL=index.js.map