UNPKG

mysql-node-migrator

Version:

A database change management tool for nodejs and mysql

307 lines (232 loc) 9.52 kB
'use strict'; 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