UNPKG

anydb-sql-migrations

Version:
137 lines (136 loc) 5.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Promise = require("bluebird"); var _ = require("lodash"); var fs = require("fs"); var path = require("path"); function create(db, tasks) { var list = []; var migrations = db.define({ name: '_migrations', columns: { version: { dataType: db.dialect() === 'mysql' ? 'varchar(255)' : 'text', notNull: true, primaryKey: true } } }); function runMigration(migfn) { return db.transaction(function (tx) { return migrations.create().ifNotExists().execWithin(tx) .then(function (_) { return migfn(tx); }) .thenReturn(); }); } function defineMigration(name, fns) { if (_.find(list, function (m) { return m.name == name; }) != null) return; list.push({ name: name, up: fns.up, down: fns.down }); } function getMigrationList(tx) { return migrations.select() .order(migrations.version.descending) .allWithin(tx) .then(function (migs) { var alreadyExecuted = migs.map(function (m) { return m.version; }); return _(list).sortBy(function (m) { return m.name; }).filter(function (m) { return !_.includes(alreadyExecuted, m.name); }).value(); }); } function unmigrate() { } function add(tx, name) { return migrations.insert({ version: name }).execWithin(tx); } function remove(tx, name) { return migrations.where({ version: name }).delete().execWithin(tx); } function runSingle(tx, type, m) { return type == 'up' ? m.up(tx).then(function () { return add(tx, m.name); }) : m.down(tx).then(function () { return remove(tx, m.name); }); } function migrate(opts) { if (opts === void 0) { opts = {}; } return runMigration(function (tx) { return getMigrationList(tx).then(function (migrations) { return migrations.reduce(function (acc, m) { return acc.then(function (_) { return runSingle(tx, "up", m); }) .then(function (_) { return !opts.silent && console.log("Completed:", m.name); }) .thenReturn(); }, Promise.resolve()); }); }); } function undoLast() { return runMigration(function (tx) { return migrations.select() .order(migrations.version.descending) .getWithin(tx).then(function (mig) { if (!mig) throw new Error("No migrations available to rollback"); var undoMigration = _.find(list, function (item) { return item.name == mig.version; }); return runSingle(tx, "down", undoMigration); }); }); } function undoAll() { return runMigration(function (tx) { return migrations.select() .order(migrations.version.descending) .allWithin(tx).then(function (migrations) { if (!migrations.length) { throw new Error("No migrations available to rollback"); } return Promise.each(migrations, function (mig) { var task = _.find(list, function (item) { return item.name == mig.version; }); return runSingle(tx, "down", task); }); }); }); } function loadFromPath(location) { fs.readdirSync(location) .filter(function (file) { return (/\.js$/.test(file)); }) .forEach(function (file) { return defineMigration(file.replace(/\.js$/, ''), require(path.resolve(location, file))); }); } function check(f) { return runMigration(function (tx) { return getMigrationList(tx).then(f); }); } function run() { var args = require('yargs').argv; if (args.check) return check(function (migrations) { if (migrations.length) { console.log("Migrations to run"); migrations.forEach(function (item) { return console.log("-", item.name); }); process.exit(1); } else { console.log("No pending migrations"); process.exit(0); } }); else if (args.execute) return migrate().done(function (_) { return process.exit(0); }, function (e) { console.error(e.stack); process.exit(1); }); else if (args.rollback) { return undoLast().done(function (_) { return process.exit(0); }, function (e) { if (e.message == 'No migrations available to rollback') { console.error(e.message); } else { console.error(e.stack); } process.exit(1); }); } else if (args.drop) { return undoAll().done(function (_) { return process.exit(0); }, function (e) { if (e.message == 'No migrations available to rollback') { console.error(e.message); } else { console.error(e.stack); } process.exit(1); }); } console.error("Add a --check, --execute, --drop or --rollback argument"); process.exit(1); } if (typeof tasks === 'string') loadFromPath(tasks); else tasks.forEach(function (task) { return defineMigration(task.name, task); }); return { run: run, check: check, migrate: migrate, undoLast: undoLast, drop: undoAll }; } exports.create = create;