db-migrate
Advanced tools
Comparing version 0.10.0-beta.24 to 0.10.0
866
api.js
@@ -1,91 +0,36 @@ | ||
var assert = require('assert'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var util = require('util'); | ||
var mkdirp = require('mkdirp'); | ||
var optimist = require('optimist'); | ||
'use strict'; | ||
var load = require('./lib/commands'); | ||
var log = require('db-migrate-shared').log; | ||
var pkginfo = require('pkginfo')(module, 'version'); // jshint ignore:line | ||
var dotenv = require('dotenv'); | ||
var Promise = Promise; | ||
var onComplete = require('./lib/commands/on-complete.js'); | ||
require('pkginfo')(module, 'version'); // jshint ignore:line | ||
var Promise; | ||
var onComplete = load('on-complete'); | ||
function registerPluginLoader(plugins) { | ||
return { | ||
overwrite: function(name) { | ||
if(plugins[name] && plugins[name].length) { | ||
var plugin = plugins[name]; | ||
if(plugin.length !== 1) { | ||
log.warn( | ||
'Attention, multiple overwrites registered for %s, we are ' + | ||
'only loading the first plugin %s!', | ||
name, | ||
plugin.name | ||
); | ||
} | ||
plugin = plugin[0]; | ||
if(typeof(plugin.loadPlugin) === 'function') | ||
plugin.loadPlugin(); | ||
return plugin; | ||
} | ||
return false; | ||
}, | ||
hook: function(name) { | ||
if(plugins[name] && plugins[name].length) { | ||
var plugin = plugins[name]; | ||
plugin.map(function(plugin) { | ||
if(typeof(plugin.loadPlugin) === 'function') | ||
plugin.loadPlugin(); | ||
}); | ||
return plugin; | ||
} | ||
return false; | ||
} | ||
}; | ||
} | ||
// constant hooks for this file | ||
var APIHooks = { | ||
'init:api:addfunction:hook': function(name, fn) { | ||
'init:api:addfunction:hook': function (name, fn) { | ||
this[name] = fn; | ||
return; | ||
}, | ||
'init:api:accessapi:hook': function(cb) { | ||
return cb(this); | ||
'init:api:accessapi:hook': function (cb) { | ||
return this; | ||
} | ||
}; | ||
function dbmigrate(plugins, isModule, options, callback) { | ||
function dbmigrate (plugins, isModule, options, callback) { | ||
var dotenv = require('dotenv'); | ||
var setDefaultArgv = load('set-default-argv'); | ||
var setDefaultArgv = require('./lib/commands/set-default-argv.js'); | ||
this.internals = { | ||
onComplete: onComplete, | ||
migrationProtocol: 1 | ||
}; | ||
if (typeof isModule !== 'function') { | ||
this.internals.isModule = isModule; | ||
} | ||
var internals = this.internals; | ||
this.internals.plugins = registerPluginLoader(plugins); | ||
this.internals.plugins = load('fn/plugin')(plugins); | ||
if (typeof(callback) === 'function') | ||
this.internals.onComplete = callback; | ||
else if (typeof(options) === 'function') | ||
this.internals.onComplete = options; | ||
if (typeof callback === 'function') this.internals.onComplete = callback; | ||
else if (typeof options === 'function') this.internals.onComplete = options; | ||
@@ -100,32 +45,29 @@ this.internals.dbm = require('./'); | ||
/* $lab:coverage:off$ */ | ||
if(options && !options.throwUncatched) | ||
registerEvents(); | ||
if (options && !options.throwUncatched) load('helper/register-events')(); | ||
/* $lab:coverage:on$ */ | ||
if (typeof(options) === 'object') { | ||
if (typeof(options.config) === 'string') | ||
if (typeof options === 'object') { | ||
if (typeof options.config === 'string') { | ||
internals.configFile = options.config; | ||
else if (typeof(options.config) === 'object') | ||
} else if (typeof options.config === 'object') { | ||
internals.configObject = options.config; | ||
} | ||
if (typeof(options.env) === 'string') | ||
internals.currentEnv = options.env; | ||
if (typeof options.env === 'string') internals.currentEnv = options.env; | ||
if (typeof(options.cwd) === 'string') | ||
internals.cwd = options.cwd; | ||
else | ||
internals.cwd = process.cwd(); | ||
} else | ||
internals.cwd = process.cwd(); | ||
if (typeof options.cwd === 'string') internals.cwd = options.cwd; | ||
else internals.cwd = process.cwd(); | ||
} else internals.cwd = process.cwd(); | ||
if (typeof(isModule) === 'function') { | ||
if (typeof isModule === 'function') { | ||
this.internals.onComplete = isModule; | ||
setDefaultArgv(this.internals); | ||
} else | ||
setDefaultArgv(this.internals, isModule); | ||
} else setDefaultArgv(this.internals, isModule); | ||
this.config = loadConfig( require('./lib/config.js'), this.internals ); | ||
this.config = load('helper/load-config')( | ||
require('./lib/config.js'), | ||
this.internals | ||
); | ||
//delayed loading of bluebird | ||
// delayed loading of bluebird | ||
Promise = require('bluebird'); | ||
@@ -143,17 +85,3 @@ this.internals.migrationOptions = { | ||
function registerEvents() { | ||
process.on('uncaughtException', function(err) { | ||
log.error(err.stack || err); | ||
process.exit(1); | ||
}); | ||
process.on('unhandledRejection', function(reason) { | ||
log.error(reason.stack); | ||
process.exit(1); | ||
}); | ||
} | ||
dbmigrate.prototype = { | ||
/** | ||
@@ -165,4 +93,3 @@ * Add a global defined variable to db-migrate, to enable access from | ||
*/ | ||
addGlobal: function(library) { | ||
addGlobal: function (library) { | ||
try { | ||
@@ -182,4 +109,3 @@ require(library); | ||
*/ | ||
registerAPIHook: function(callback) { | ||
registerAPIHook: function (callback) { | ||
var plugins = this.internals.plugins; | ||
@@ -189,19 +115,17 @@ var self = this; | ||
return Promise.resolve(Object.keys(APIHooks)) | ||
.each(function(hook) { | ||
.each(function (hook) { | ||
var plugin = plugins.hook(hook); | ||
if (!plugin) return; | ||
var plugin = plugins.hook(hook); | ||
if(!plugin) return; | ||
var APIHook = APIHooks[hook].bind(self); | ||
var APIHook = APIHooks[hook].bind(self); | ||
return Promise.resolve(plugin) | ||
.map(function(plugin) { | ||
return plugin[hook](); | ||
return Promise.resolve(plugin) | ||
.map(function (plugin) { | ||
return plugin[hook](); | ||
}) | ||
.each(function (args) { | ||
return APIHook.apply(self, args); | ||
}); | ||
}) | ||
.each(function(args) { | ||
return APIHook.apply(self, args); | ||
}); | ||
}).asCallback(callback); | ||
.asCallback(callback); | ||
}, | ||
@@ -216,4 +140,3 @@ | ||
*/ | ||
addConfiguration: function(description, args, type) { | ||
addConfiguration: function (description, args, type) { | ||
var name = args.shift(); | ||
@@ -223,3 +146,2 @@ this.internals.argv.describe(name, description); | ||
for (var i = 0; i < args.length; ++i) { | ||
this.internals.argv.alias(args[i], name); | ||
@@ -229,3 +151,2 @@ } | ||
switch (type) { | ||
case 'string': | ||
@@ -246,7 +167,6 @@ this.internals.argv.string(name); | ||
/** | ||
* Resets and sets argv to a specified new argv. | ||
*/ | ||
resetConfiguration: function(argv) { | ||
resetConfiguration: function (argv) { | ||
this.internals.argv = argv; | ||
@@ -260,26 +180,18 @@ }, | ||
*/ | ||
up: function(specification, opts, callback) { | ||
up: function (specification, opts, callback) { | ||
var executeUp = load('up'); | ||
var executeUp = require('./lib/commands/up.js'); | ||
if (arguments.length > 0) { | ||
if (typeof(specification) === 'string') { | ||
if (typeof specification === 'string') { | ||
this.internals.argv.destination = specification; | ||
} else if (typeof(specification) === 'number') { | ||
} else if (typeof specification === 'number') { | ||
this.internals.argv.count = specification; | ||
} | ||
else if (typeof(specification) === 'function') { | ||
} else if (typeof specification === 'function') { | ||
callback = specification; | ||
} | ||
if (typeof(opts) === 'string') { | ||
if (typeof opts === 'string') { | ||
this.internals.migrationMode = opts; | ||
this.internals.matching = opts; | ||
} | ||
else if (typeof(opts) === 'function') { | ||
} else if (typeof opts === 'function') { | ||
callback = opts; | ||
@@ -289,6 +201,7 @@ } | ||
return Promise.fromCallback(function(callback) { | ||
executeUp(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeUp(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -301,23 +214,16 @@ | ||
*/ | ||
down: function(specification, opts, callback) { | ||
down: function (specification, opts, callback) { | ||
var executeDown = load('down'); | ||
var executeDown = require('./lib/commands/down.js'); | ||
if (arguments.length > 0) { | ||
if (typeof(specification) === 'number') { | ||
if (typeof specification === 'number') { | ||
this.internals.argv.count = arguments[0]; | ||
} | ||
else if (typeof(specification) === 'function') { | ||
} else if (typeof specification === 'function') { | ||
callback = specification; | ||
} | ||
if (typeof(opts) === 'string') { | ||
if (typeof opts === 'string') { | ||
this.internals.migrationMode = opts; | ||
this.internals.matching = opts; | ||
} | ||
else if (typeof(opts) === 'function') { | ||
} else if (typeof opts === 'function') { | ||
callback = opts; | ||
@@ -327,6 +233,7 @@ } | ||
return Promise.fromCallback(function(callback) { | ||
executeDown(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeDown(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -339,19 +246,14 @@ | ||
*/ | ||
sync: function(specification, opts, callback) { | ||
sync: function (specification, opts, callback) { | ||
var executeSync = load('sync'); | ||
var executeSync = require('./lib/commands/sync.js'); | ||
if (arguments.length > 0) { | ||
if (typeof(specification) === 'string') { | ||
if (typeof specification === 'string') { | ||
this.internals.argv.destination = specification; | ||
} | ||
if (typeof(opts) === 'string') { | ||
if (typeof opts === 'string') { | ||
this.internals.migrationMode = opts; | ||
this.internals.matching = opts; | ||
} | ||
else if (typeof(opts) === 'function') { | ||
} else if (typeof opts === 'function') { | ||
callback = opts; | ||
@@ -361,6 +263,7 @@ } | ||
return Promise.fromCallback(function(callback) { | ||
executeSync(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeSync(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -371,13 +274,9 @@ | ||
*/ | ||
reset: function(scope, callback) { | ||
reset: function (scope, callback) { | ||
var executeDown = load('down'); | ||
var executeDown = require('./lib/commands/down.js'); | ||
if (typeof(scope) === 'string') { | ||
if (typeof scope === 'string') { | ||
this.internals.migrationMode = scope; | ||
this.internals.matching = scope; | ||
} | ||
else if(typeof(scope) === 'function') { | ||
} else if (typeof scope === 'function') { | ||
callback = scope; | ||
@@ -387,6 +286,7 @@ } | ||
this.internals.argv.count = Number.MAX_VALUE; | ||
return Promise.fromCallback(function(callback) { | ||
executeDown(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeDown(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -397,4 +297,3 @@ | ||
*/ | ||
silence: function(isSilent) { | ||
silence: function (isSilent) { | ||
return log.silence(isSilent); | ||
@@ -406,5 +305,4 @@ }, | ||
*/ | ||
transition: function() { | ||
transition(this.internals); | ||
transition: function () { | ||
load('transition')(this.internals); | ||
}, | ||
@@ -415,9 +313,7 @@ | ||
*/ | ||
create: function(migrationName, scope, callback) { | ||
if (typeof(scope) === 'function') { | ||
create: function (migrationName, scope, callback) { | ||
var executeCreateMigration = load('create-migration'); | ||
if (typeof scope === 'function') { | ||
callback = scope; | ||
} else if (scope) { | ||
this.internals.migrationMode = scope; | ||
@@ -428,6 +324,7 @@ this.internals.matching = scope; | ||
this.internals.argv._.push(migrationName); | ||
return Promise.fromCallback(function(callback) { | ||
executeCreateMigration(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeCreateMigration(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -438,10 +335,11 @@ | ||
*/ | ||
createDatabase: function(dbname, callback) { | ||
createDatabase: function (dbname, callback) { | ||
var executeDB = load('db'); | ||
this.internals.argv._.push(dbname); | ||
this.internals.mode = 'create'; | ||
return Promise.fromCallback(function(callback) { | ||
executeDB(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeDB(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -452,10 +350,11 @@ | ||
*/ | ||
dropDatabase: function(dbname, callback) { | ||
dropDatabase: function (dbname, callback) { | ||
var executeDB = load('db'); | ||
this.internals.argv._.push(dbname); | ||
this.internals.mode = 'drop'; | ||
return Promise.fromCallback(function(callback) { | ||
executeDB(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeDB(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -468,13 +367,10 @@ | ||
*/ | ||
setConfigParam: function(param, value) { | ||
setConfigParam: function (param, value) { | ||
return (this.internals.argv[param] = value); | ||
}, | ||
/** | ||
* Sets the callback to the default onComplete | ||
*/ | ||
setDefaultCallback: function() { | ||
setDefaultCallback: function () { | ||
this.internals.onComplete = onComplete; | ||
@@ -487,4 +383,3 @@ }, | ||
*/ | ||
setCustomCallback: function(callback) { | ||
setCustomCallback: function (callback) { | ||
this.internals.onComplete = callback; | ||
@@ -497,6 +392,5 @@ }, | ||
*/ | ||
seed: function(mode, scope, callback) { | ||
seed: function (mode, scope, callback) { | ||
var executeSeed = load('seed'); | ||
if (scope) { | ||
this.internals.migrationMode = scope; | ||
@@ -507,6 +401,7 @@ this.internals.matching = scope; | ||
this.internals.mode = mode || 'vc'; | ||
return Promise.fromCallback(function(callback) { | ||
executeSeed(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeSeed(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -517,16 +412,13 @@ | ||
*/ | ||
undoSeed: function(specification, scope, callback) { | ||
undoSeed: function (specification, scope, callback) { | ||
var executeUndoSeed = load('undo-seed'); | ||
if (arguments.length > 0) { | ||
if (typeof(specification) === 'number') { | ||
if (typeof specification === 'number') { | ||
this.internals.argv.count = specification; | ||
if (scope) { | ||
this.internals.migrationMode = scope; | ||
this.internals.matching = scope; | ||
} | ||
} else if (typeof(specification) === 'string') { | ||
} else if (typeof specification === 'string') { | ||
this.internals.migrationMode = scope; | ||
@@ -537,6 +429,7 @@ this.internals.matching = scope; | ||
return Promise.fromCallback(function(callback) { | ||
executeUndoSeed(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeUndoSeed(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -547,16 +440,13 @@ | ||
*/ | ||
resetSeed: function(specification, scope, callback) { | ||
resetSeed: function (specification, scope, callback) { | ||
var executeUndoSeed = load('undo-seed'); | ||
if (arguments.length > 0) { | ||
if (typeof(specification) === 'number') { | ||
if (typeof specification === 'number') { | ||
this.internals.argv.count = specification; | ||
if (scope) { | ||
this.internals.migrationMode = scope; | ||
this.internals.matching = scope; | ||
} | ||
} else if (typeof(specification) === 'string') { | ||
} else if (typeof specification === 'string') { | ||
this.internals.migrationMode = scope; | ||
@@ -568,6 +458,7 @@ this.internals.matching = scope; | ||
this.internals.argv.count = Number.MAX_VALUE; | ||
return Promise.fromCallback(function(callback) { | ||
executeUndoSeed(this.internals, this.config, callback); | ||
}.bind(this)).asCallback(callback); | ||
return Promise.fromCallback( | ||
function (callback) { | ||
executeUndoSeed(this.internals, this.config, callback); | ||
}.bind(this) | ||
).asCallback(callback); | ||
}, | ||
@@ -578,468 +469,7 @@ | ||
*/ | ||
run: function() { | ||
run(this.internals, this.config); | ||
run: function () { | ||
load('run')(this.internals, this.config); | ||
} | ||
}; | ||
function createMigrationDir(dir, callback) { | ||
fs.stat(dir, function(err) { | ||
if (err) { | ||
mkdirp(dir, callback); | ||
} else { | ||
callback(); | ||
} | ||
}); | ||
} | ||
function loadConfig( config, internals ) { | ||
var out, | ||
currentEnv = internals.currentEnv || internals.argv.env; | ||
if (internals.configObject) { | ||
out = config.loadObject(internals.configObject, currentEnv); | ||
} else { | ||
out = config.loadFile(internals.argv.config, currentEnv, internals.plugins); | ||
} | ||
if (internals.verbose) { | ||
var current = out.getCurrent(); | ||
var s = JSON.parse(JSON.stringify(current.settings)); | ||
if (s.password) | ||
s.password = '******'; | ||
log.info('Using', current.env, 'settings:', s); | ||
} | ||
return out; | ||
} | ||
function executeCreateMigration(internals, config, callback) { | ||
var migrationsDir = internals.argv['migrations-dir']; | ||
internals.runTimestamp = new Date(); | ||
if (internals.migrationMode && internals.migrationMode !== 'all') { | ||
migrationsDir = internals.argv['migrations-dir'] + '/' + | ||
internals.migrationMode; | ||
} | ||
var folder, path; | ||
if (internals.argv._.length === 0) { | ||
log.error('\'migrationName\' is required.'); | ||
optimist.showHelp(); | ||
process.exit(1); | ||
} | ||
createMigrationDir(migrationsDir, function(err) { | ||
var index = require('./connect'); | ||
var Migration = require('./lib/migration.js'); | ||
if (err) { | ||
log.error('Failed to create migration directory at ', migrationsDir, | ||
err); | ||
process.exit(1); | ||
} | ||
internals.argv.title = internals.argv._.shift(); | ||
folder = internals.argv.title.split('/'); | ||
internals.argv.title = folder[folder.length - 2] || folder[0]; | ||
path = migrationsDir; | ||
if (folder.length > 1) { | ||
path += '/'; | ||
for (var i = 0; i < folder.length - 1; ++i) { | ||
path += folder[i] + '/'; | ||
} | ||
} | ||
var templateType = Migration.TemplateType.DEFAULT_JS; | ||
if (shouldCreateSqlFiles( internals, config ) && | ||
shouldCreateCoffeeFile( internals, config )) { | ||
templateType = Migration.TemplateType.COFFEE_SQL_FILE_LOADER; | ||
} else if (shouldCreateSqlFiles( internals, config ) && | ||
shouldIgnoreOnInitFiles( internals, config )) { | ||
templateType = Migration.TemplateType.SQL_FILE_LOADER_IGNORE_ON_INIT; | ||
} else if (shouldCreateSqlFiles( internals, config )) { | ||
templateType = Migration.TemplateType.SQL_FILE_LOADER; | ||
} else if (shouldCreateCoffeeFile( internals, config )) { | ||
templateType = Migration.TemplateType.DEFAULT_COFFEE; | ||
} | ||
var migration = new Migration(internals.argv.title + ( | ||
shouldCreateCoffeeFile( internals, config ) ? '.coffee' : '.js'), path, internals.runTimestamp, | ||
templateType); | ||
index.createMigration(migration, function(err, migration) { | ||
if (_assert(err, callback)) { | ||
log.info(util.format('Created migration at %s', migration.path)); | ||
if (shouldCreateSqlFiles(internals, config)) { | ||
createSqlFiles(internals, config, callback); | ||
} else { | ||
if (typeof(callback) === 'function') { | ||
callback(); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
function shouldCreateSqlFiles( internals, config ) { | ||
return internals.argv['sql-file'] || config['sql-file']; | ||
} | ||
function shouldIgnoreOnInitFiles( internals, config ) { | ||
return internals.argv['ignore-on-init'] || config[ | ||
'ignore-on-init']; | ||
} | ||
function shouldCreateCoffeeFile( internals, config ) { | ||
return internals.argv['coffee-file'] || config['coffee-file']; | ||
} | ||
function createSqlFiles(internals, config, callback) { | ||
var migrationsDir = internals.argv['migrations-dir']; | ||
if (internals.migrationMode && internals.migrationMode !== 'all') { | ||
migrationsDir = internals.argv['migrations-dir'] + '/' + | ||
internals.migrationMode; | ||
} | ||
var sqlDir = migrationsDir + '/sqls'; | ||
createMigrationDir(sqlDir, function(err) { | ||
var index = require('./connect'); | ||
var Migration = require('./lib/migration.js'); | ||
if (err) { | ||
log.error('Failed to create migration directory at ', sqlDir, err); | ||
if (typeof(callback) !== 'function') { | ||
process.exit(1); | ||
} else { | ||
return callback(err); | ||
} | ||
} | ||
var templateTypeDefaultSQL = Migration.TemplateType.DEFAULT_SQL; | ||
var migrationUpSQL = new Migration(internals.argv.title + '-up.sql', | ||
sqlDir, internals.runTimestamp, templateTypeDefaultSQL); | ||
index.createMigration(migrationUpSQL, function(err, migration) { | ||
if (_assert(err, callback)) { | ||
log.info(util.format('Created migration up sql file at %s', | ||
migration.path)); | ||
var migrationDownSQL = new Migration(internals.argv.title + | ||
'-down.sql', sqlDir, internals.runTimestamp, templateTypeDefaultSQL); | ||
index.createMigration(migrationDownSQL, function(err, migration) { | ||
if (_assert(err, callback)) { | ||
log.info(util.format( | ||
'Created migration down sql file at %s', | ||
migration.path)); | ||
if (typeof(callback) === 'function') | ||
callback(); | ||
} | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
function _assert(err, callback) { | ||
if (err) { | ||
if (typeof(callback) === 'function') { | ||
callback(err); | ||
return false; | ||
} else { | ||
assert.ifError(err); | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
function migrationHook(internals) { | ||
var Migration = require('./lib/migration.js'); | ||
return Migration.registerHook(internals.plugins, internals); | ||
} | ||
function executeDB(internals, config, callback) { | ||
var index = require('./connect'); | ||
if (internals.argv._.length > 0) { | ||
internals.argv.dbname = internals.argv._.shift().toString(); | ||
} else { | ||
log.info('Error: You must enter a database name!'); | ||
return; | ||
} | ||
index.driver(config.getCurrent().settings, function(err, db) { | ||
assert.ifError(err); | ||
if (internals.mode === 'create') { | ||
db.createDatabase(internals.argv.dbname, { | ||
ifNotExists: true | ||
}, function(err) { | ||
if (err) { | ||
if( err.error ) | ||
err = err.error; | ||
log.info('Error: Failed to create database!', err); | ||
} else { | ||
log.info('Created database "' + internals.argv.dbname + '"'); | ||
} | ||
db.close(); | ||
if( typeof(callback) === 'function' ) | ||
callback(); | ||
}); | ||
} else if (internals.mode === 'drop') { | ||
db.dropDatabase(internals.argv.dbname, { | ||
ifExists: true | ||
}, function(err) { | ||
if (err) { | ||
if( err.error ) | ||
err = err.error; | ||
log.info('Error: Failed to drop database!', err); | ||
} else { | ||
log.info('Deleted database "' + internals.argv.dbname + '"'); | ||
} | ||
db.close(); | ||
if( typeof(callback) === 'function' ) | ||
callback(); | ||
}); | ||
} else | ||
return; | ||
}); | ||
} | ||
function executeSeed(internals, config, callback) { | ||
var index = require('./connect'); | ||
var Seeder = require('./lib/seeder.js'); | ||
if (internals.argv._.length > 0) { | ||
internals.argv.destination = internals.argv._.shift().toString(); | ||
} | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Seeder, function(err, seeder) { | ||
assert.ifError(err); | ||
seeder.seedDir = path.resolve(internals.argv[(internals.mode !== | ||
'static') ? 'vcseeder-dir' : 'staticseeder-dir']); | ||
if (internals.mode === 'static') { | ||
seeder.seed(internals.argv, internals.onComplete.bind(this, seeder, | ||
internals, callback)); | ||
} else { | ||
seeder.createSeedsTable(function(err) { | ||
if (_assert(err, callback)) { | ||
seeder.seed(internals.argv, internals.onComplete.bind(this, | ||
seeder, internals, callback)); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
function executeUndoSeed(internals, config, callback) { | ||
var index = require('./connect'); | ||
var Seeder = require('./lib/seeder.js'); | ||
if (!internals.argv.count) { | ||
log.info('Defaulting to running 1 down seed.'); | ||
internals.argv.count = 1; | ||
} | ||
if (internals.argv._.length > 0) { | ||
internals.argv.destination = internals.argv._.shift().toString(); | ||
} | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Seeder, function(err, seeder) { | ||
assert.ifError(err); | ||
seeder.seedDir = path.resolve(internals.argv[(internals.mode !== | ||
'static') ? 'vcseeder-dir' : 'staticseeder-dir']); | ||
if (internals.mode === 'static') { | ||
internals.onComplete( seeder, callback, | ||
{ stack: 'Static seeders can\'t be undone. Use VC Seeders instead!' } ); | ||
} else { | ||
seeder.createSeedsTable(function(err) { | ||
if (_assert(err, callback)) { | ||
seeder.down(internals.argv, internals.onComplete.bind(this, | ||
seeder, internals, callback)); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
function transition(internals) { | ||
require('./lib/transitions/transitioner.js')(internals); | ||
} | ||
function run(internals, config) { | ||
var action = internals.argv._.shift(), | ||
folder = action.split(':'); | ||
action = folder[0]; | ||
switch (action) { | ||
case 'transition': | ||
transition(internals); | ||
break; | ||
case 'create': | ||
if (folder[1]) { | ||
internals.matching = folder[1]; | ||
internals.migrationMode = folder[1]; | ||
} | ||
executeCreateMigration(internals, config); | ||
break; | ||
case 'sync': | ||
var executeSync = require('./lib/commands/sync.js'); | ||
if (internals.argv._.length === 0) { | ||
log.error('Missing sync destination!'); | ||
process.exit(1); | ||
} | ||
internals.argv.count = Number.MAX_VALUE; | ||
internals.argv.destination = internals.argv._.shift().toString(); | ||
if (folder[1]) { | ||
internals.matching = folder[1]; | ||
internals.migrationMode = folder[1]; | ||
} | ||
executeSync(internals, config); | ||
break; | ||
case 'up': | ||
case 'down': | ||
case 'reset': | ||
if (action === 'reset') | ||
internals.argv.count = Number.MAX_VALUE; | ||
if (internals.argv._.length > 0) { | ||
if (action === 'down') { | ||
internals.argv.count = internals.argv.count || Number.MAX_VALUE; | ||
internals.argv.destination = internals.argv._.shift().toString(); | ||
} else { | ||
internals.argv.destination = internals.argv._.shift().toString(); | ||
} | ||
} | ||
if (folder[1]) { | ||
internals.matching = folder[1]; | ||
internals.migrationMode = folder[1]; | ||
} | ||
if (action === 'up') { | ||
var executeUp = require('./lib/commands/up.js'); | ||
executeUp(internals, config); | ||
} else { | ||
var executeDown = require('./lib/commands/down.js'); | ||
executeDown(internals, config); | ||
} | ||
break; | ||
case 'db': | ||
if (folder.length < 1) { | ||
log.info('Please enter a valid command, i.e. db:create|db:drop'); | ||
} else { | ||
internals.mode = folder[1]; | ||
executeDB(internals, config); | ||
} | ||
break; | ||
case 'seed': | ||
internals.mode = folder[1] || 'vc'; | ||
internals.migrationMode = folder[2]; | ||
if (internals.argv._[0] === 'down' || internals.argv._[0] === 'reset') { | ||
if (internals.argv._[0] === 'reset') | ||
internals.argv.count = Number.MAX_VALUE; | ||
internals.argv._.shift(); | ||
executeUndoSeed(internals, config); | ||
} else { | ||
executeSeed(internals, config); | ||
} | ||
break; | ||
default: | ||
var plugins = internals.plugins; | ||
var plugin = plugins.overwrite( | ||
'run:default:action:' + action + ':overwrite' | ||
); | ||
if(plugin) { | ||
plugin['run:default:action:' + action + ':overwrite'] | ||
(internals, config); | ||
} | ||
else { | ||
log.error('Invalid Action: Must be [up|down|create|reset|sync|' + | ||
'db|transition].'); | ||
optimist.showHelp(); | ||
process.exit(1); | ||
} | ||
break; | ||
} | ||
} | ||
module.exports = dbmigrate; |
@@ -0,1 +1,31 @@ | ||
## 0.10.0 | ||
Note: | ||
This is a cornerstone release. It provides groundwork for many things to come and has worked | ||
on stability and flexibility, while mostly retaining backwards compatibility. | ||
This release was a rewrite of nearly the whole module. However backwards compatibility | ||
was mostly preeserved. Bug fixes wont be listed for this release, all subsequent releases | ||
will follow the angular standard to automatically generate changelogs. | ||
New Features: | ||
- Sync | ||
- Driverless Core | ||
- Plugin Hooks and overwrites | ||
- Adjusted migration schema, to allow specific setup routines | ||
- Version migration schemas itself for future iterations | ||
- Promise style migrations | ||
- Programmatic API | ||
- Restructered major parts of db-migrate | ||
- Transactional migrations | ||
- New configuration options | ||
Find a full list of features added here: | ||
https://github.com/db-migrate/node-db-migrate/issues?utf8=%E2%9C%93&q=milestone%3Av0.10.0 | ||
# Old Changelogs | ||
## 0.1.0 | ||
@@ -2,0 +32,0 @@ |
179
connect.js
@@ -7,8 +7,6 @@ var recursive = require('final-fs').readdirRecursive; | ||
var internals = {}; | ||
exports.connect = function(config, passedClass, callback) { | ||
exports.connect = function (config, PassedClass, callback) { | ||
var internals = {}; | ||
if( config.config ) { | ||
if (config.config) { | ||
internals = config.internals; | ||
@@ -18,38 +16,59 @@ config = config.config; | ||
driver.connect(config, internals, function(err, db) { | ||
if (err) { callback(err); return; } | ||
driver.connect(config, internals, function (err, db) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
if(internals.migrationMode) | ||
{ | ||
if (internals.migrationMode) { | ||
var dirPath = path.resolve(config['migrations-dir'] || 'migrations'); | ||
if(internals.migrationMode !== 'all') | ||
{ | ||
var switched = false, | ||
newConf; | ||
if (internals.migrationMode !== 'all') { | ||
var switched = false; | ||
var newConf; | ||
try { | ||
newConf = require(path.resolve(config['migrations-dir'] || 'migrations', internals.migrationMode) + '/config.json'); | ||
log.info('loaded extra config for migration subfolder: "' + internals.migrationMode + '/config.json"'); | ||
newConf = require(path.resolve( | ||
config['migrations-dir'] || 'migrations', | ||
internals.migrationMode | ||
) + '/config.json'); | ||
log.info( | ||
'loaded extra config for migration subfolder: "' + | ||
internals.migrationMode + | ||
'/config.json"' | ||
); | ||
switched = true; | ||
} catch(e) {} | ||
} catch (e) {} | ||
if(switched) { | ||
db.switchDatabase(newConf, function() | ||
{ | ||
if (switched) { | ||
db.switchDatabase(newConf, function () { | ||
internals.locTitle = internals.migrationMode; | ||
callback(null, new passedClass(db, config['migrations-dir'], internals.mode !== 'static', internals)); | ||
callback( | ||
null, | ||
new PassedClass( | ||
db, | ||
config['migrations-dir'], | ||
internals.mode !== 'static', | ||
internals | ||
) | ||
); | ||
}); | ||
} | ||
else | ||
{ | ||
} else { | ||
internals.locTitle = internals.migrationMode; | ||
callback(null, new passedClass(db, config['migrations-dir'], internals.mode !== 'static', internals)); | ||
callback( | ||
null, | ||
new PassedClass( | ||
db, | ||
config['migrations-dir'], | ||
internals.mode !== 'static', | ||
internals | ||
) | ||
); | ||
} | ||
} | ||
else | ||
{ | ||
recursive(dirPath, false, config['migrations-dir'] || 'migrations') | ||
.then(function(files) { | ||
} else { | ||
recursive( | ||
dirPath, | ||
false, | ||
config['migrations-dir'] || 'migrations' | ||
).then(function (files) { | ||
var oldClose = db.close; | ||
@@ -63,4 +82,14 @@ | ||
db.close = function(cb) { migrationFiles(files, callback, config, | ||
internals, passedClass, db, oldClose, cb); }; | ||
db.close = function (cb) { | ||
migrationFiles( | ||
files, | ||
callback, | ||
config, | ||
internals, | ||
PassedClass, | ||
db, | ||
oldClose, | ||
cb | ||
); | ||
}; | ||
@@ -70,14 +99,19 @@ db.close(); | ||
} | ||
} else { | ||
callback( | ||
null, | ||
new PassedClass( | ||
db, | ||
config['migrations-dir'], | ||
internals.mode !== 'static', | ||
internals | ||
) | ||
); | ||
} | ||
else | ||
callback(null, new passedClass(db, config['migrations-dir'], internals.mode !== 'static', internals)); | ||
}); | ||
}; | ||
exports.driver = function(config, callback) { | ||
exports.driver = function (config, callback) { | ||
var internals = {}; | ||
var _config = config; | ||
if( config.config ) { | ||
if (config.config) { | ||
internals = config.internals; | ||
@@ -90,10 +124,17 @@ config = config.config; | ||
function migrationFiles(files, callback, config, internals, | ||
passedClass, db, close, cb) { | ||
var file, | ||
switched = false, | ||
newConf; | ||
function migrationFiles ( | ||
files, | ||
callback, | ||
config, | ||
internals, | ||
PassedClass, | ||
db, | ||
close, | ||
cb | ||
) { | ||
var file; | ||
var switched = false; | ||
var newConf; | ||
if(files.length === 1) | ||
{ | ||
if (files.length === 1) { | ||
db.close = close; | ||
@@ -103,38 +144,48 @@ } | ||
file = files.pop(); | ||
log.info( 'Enter scope "' + ((file !== '') ? file : '/') + '"' ); | ||
log.info('Enter scope "' + (file !== '' ? file : '/') + '"'); | ||
if(file !== '') | ||
{ | ||
if (file !== '') { | ||
try { | ||
fs.statSync(path.resolve(file + '/config.json')); | ||
newConf = require(path.resolve(file + '/config.json')); | ||
log.info('loaded extra config for migration subfolder: "' + file + '/config.json"'); | ||
log.info( | ||
'loaded extra config for migration subfolder: "' + | ||
file + | ||
'/config.json"' | ||
); | ||
switched = true; | ||
} catch(e) {} | ||
} catch (e) {} | ||
} | ||
db.switchDatabase((switched) ? newConf : config.database, function() | ||
{ | ||
internals.matching = file.substr(file.indexOf(config['migrations-dir'] || 'migrations') + | ||
(config['migrations-dir'] || 'migrations').length + 1); | ||
db.switchDatabase(switched ? newConf : config.database, function () { | ||
internals.matching = file.substr( | ||
file.indexOf(config['migrations-dir'] || 'migrations') + | ||
(config['migrations-dir'] || 'migrations').length + | ||
1 | ||
); | ||
if(internals.matching.length === 0) | ||
if (internals.matching.length === 0) { | ||
internals.matching = ''; | ||
} | ||
internals.locTitle = internals.matching; | ||
callback(null, new passedClass(db, config['migrations-dir'], internals.mode !== 'static', internals)); | ||
callback( | ||
null, | ||
new PassedClass( | ||
db, | ||
config['migrations-dir'], | ||
internals.mode !== 'static', | ||
internals | ||
) | ||
); | ||
if(typeof(cb) === 'function') | ||
if (typeof cb === 'function') { | ||
cb(); | ||
} | ||
}); | ||
} | ||
exports.createMigration = function(migration, callback) { | ||
migration.write(function(err) { | ||
exports.createMigration = function (migration, callback) { | ||
migration.write(function (err) { | ||
if (err) { | ||
callback(err); | ||
@@ -141,0 +192,0 @@ return; |
64
index.js
@@ -1,2 +0,2 @@ | ||
var pkginfo = require('pkginfo')(module, 'version'); // jshint ignore:line | ||
require('pkginfo')(module, 'version'); // jshint ignore:line | ||
var fs = require('fs'); | ||
@@ -7,17 +7,12 @@ var path = require('path'); | ||
function loadPluginList() { | ||
function loadPluginList () { | ||
var plugins = JSON.parse( | ||
fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8') | ||
); | ||
var targets = []; | ||
var plugins = JSON.parse(fs.readFileSync( | ||
path.join(process.cwd(), 'package.json'), | ||
'utf-8' | ||
) | ||
), | ||
targets = []; | ||
plugins = Object.assign(plugins.dependencies, plugins.devDependencies); | ||
for(var plugin in plugins) { | ||
if(plugin.startsWith('db-migrate-plugin')) | ||
targets.push(plugin); | ||
for (var plugin in plugins) { | ||
if (plugin.startsWith('db-migrate-plugin')) targets.push(plugin); | ||
} | ||
@@ -28,18 +23,20 @@ | ||
function loadPlugins() { | ||
function loadPlugins () { | ||
var plugins = loadPluginList(); | ||
var i = 0; | ||
var length = plugins.length; | ||
var hooks = {}; | ||
var plugins = loadPluginList(), | ||
i = 0, | ||
length = plugins.length, | ||
hooks = {}; | ||
for(; i < length; ++i) { | ||
for (; i < length; ++i) { | ||
var plugin = require(path.join(process.cwd(), 'node_modules', plugins[i])); | ||
if(typeof(plugin.name) !== 'string' || !plugin.hooks || !plugin.loadPlugin) | ||
if ( | ||
typeof plugin.name !== 'string' || | ||
!plugin.hooks || | ||
!plugin.loadPlugin | ||
) { | ||
continue; | ||
} | ||
plugin.hooks.map(function(hook) { | ||
plugin.hooks.map(function (hook) { | ||
hooks[hook] = hooks[hook] || []; | ||
@@ -53,22 +50,17 @@ hooks[hook].push(plugin); | ||
module.exports.getInstance = function(isModule, options, callback) { | ||
module.exports.getInstance = function (isModule, options, callback) { | ||
delete require.cache[require.resolve('./api.js')]; | ||
delete require.cache[require.resolve('optimist')]; | ||
var mod = require('./api.js'), | ||
plugins = {}; | ||
var Mod = require('./api.js'); | ||
var plugins = {}; | ||
try { | ||
if (!options || !options.noPlugins) plugins = loadPlugins(); | ||
} catch (ex) {} | ||
if(!options || !options.noPlugins) | ||
plugins = loadPlugins(); | ||
} | ||
catch(ex) {} | ||
if(options && options.plugins) { | ||
if (options && options.plugins) { | ||
plugins = Object.assign(plugins, options.plugins); | ||
} | ||
return new mod(plugins, isModule, options, callback); | ||
return new Mod(plugins, isModule, options, callback); | ||
}; |
@@ -6,9 +6,17 @@ /* Simple JavaScript Inheritance | ||
// Inspired by base2 and Prototype | ||
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; | ||
var initializing = false; | ||
/*eslint-disable */ | ||
var fnTest = /xyz/.test(function() { | ||
xyz; | ||
}) | ||
? /\b_super\b/ | ||
: /.*/; | ||
/* eslint-enable */ | ||
// The base Class implementation (does nothing) | ||
var Class = function(){}; | ||
var Class = function () {}; | ||
// Create a new Class that inherits from this class | ||
Class.extend = function ext(prop) { | ||
Class.extend = function ext (prop) { | ||
var _super = this.prototype; | ||
@@ -25,28 +33,31 @@ | ||
// Check if we're overwriting an existing function | ||
prototype[name] = typeof prop[name] === "function" && | ||
typeof _super[name] === "function" && fnTest.test(prop[name]) ? | ||
(function(name, fn){ | ||
return function() { | ||
var tmp = this._super; | ||
prototype[name] = | ||
typeof prop[name] === 'function' && | ||
typeof _super[name] === 'function' && | ||
fnTest.test(prop[name]) | ||
? (function (name, fn) { | ||
return function () { | ||
var tmp = this._super; | ||
// Add a new ._super() method that is the same method | ||
// but on the super-class | ||
this._super = _super[name]; | ||
// Add a new ._super() method that is the same method | ||
// but on the super-class | ||
this._super = _super[name]; | ||
// The method only need to be bound temporarily, so we | ||
// remove it when we're done executing | ||
var ret = fn.apply(this, arguments); | ||
this._super = tmp; | ||
// The method only need to be bound temporarily, so we | ||
// remove it when we're done executing | ||
var ret = fn.apply(this, arguments); | ||
this._super = tmp; | ||
return ret; | ||
}; | ||
})(name, prop[name]) : | ||
prop[name]; | ||
return ret; | ||
}; | ||
})(name, prop[name]) | ||
: prop[name]; | ||
} | ||
// The dummy class constructor | ||
function Class() { | ||
function Class () { | ||
// All construction is actually done in the init method | ||
if ( !initializing && this.init ) | ||
if (!initializing && this.init) { | ||
this.init.apply(this, arguments); | ||
} | ||
} | ||
@@ -53,0 +64,0 @@ |
@@ -6,30 +6,28 @@ var path = require('path'); | ||
module.exports = function(internals, config, callback) { | ||
module.exports = function (internals, config, callback) { | ||
migrationHook(internals) | ||
.then(function() { | ||
.then(function () { | ||
var Migrator = require('../migrator.js'); | ||
var index = require('../../connect'); | ||
var Migrator = require('../migrator.js'); | ||
var index = require('../../connect'); | ||
if (!internals.argv.count) { | ||
log.info('Defaulting to running 1 down migration.'); | ||
internals.argv.count = 1; | ||
} | ||
if (!internals.argv.count) { | ||
log.info('Defaulting to running 1 down migration.'); | ||
internals.argv.count = 1; | ||
} | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Migrator, function (err, migrator) { | ||
if (!assert(err)) return; | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Migrator, function(err, migrator) { | ||
if(!assert(err)) return; | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); | ||
migrator.driver.createMigrationsTable(function(err) { | ||
if(!assert(err)) return; | ||
migrator.down(internals.argv, internals.onComplete.bind(this, | ||
migrator, internals, callback)); | ||
migrator.driver.createMigrationsTable(function (err) { | ||
if (!assert(err)) return; | ||
migrator.down(internals.argv, internals.onComplete.bind(this, | ||
migrator, internals, callback)); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; |
var assert = require('assert'); | ||
module.exports = function(err, callback) { | ||
module.exports = function (err, callback) { | ||
if (err) { | ||
if (typeof(callback) === 'function') { | ||
if (typeof (callback) === 'function') { | ||
callback(err); | ||
return false; | ||
} else { | ||
assert.ifError(err); | ||
@@ -13,0 +10,0 @@ return false; |
module.exports = function(internals) { | ||
module.exports = function (internals) { | ||
var Migration = require('../../migration.js'); | ||
return Migration.registerHook(internals.plugins, internals); | ||
}; |
var assert = require('assert'); | ||
var log = require('db-migrate-shared').log; | ||
module.exports = function(migrator, internals, callback, originalErr) { | ||
if (typeof(callback) !== 'function') { | ||
module.exports = function (migrator, internals, callback, originalErr) { | ||
if (typeof callback !== 'function') { | ||
originalErr = originalErr || callback; | ||
} | ||
migrator.driver.close(function(err) { | ||
if ((err || originalErr) && typeof(callback) === 'function') { | ||
callback({ | ||
err: err, | ||
originalErr: originalErr | ||
}); | ||
migrator.driver.close(function (err) { | ||
if ((err || originalErr) && typeof callback === 'function') { | ||
callback( | ||
new Error({ | ||
err: err, | ||
originalErr: originalErr | ||
}) | ||
); | ||
return; | ||
} else { | ||
assert.ifError(originalErr); | ||
@@ -30,3 +29,3 @@ assert.ifError(err); | ||
if (typeof(callback) === 'function') { | ||
if (typeof callback === 'function') { | ||
callback(); | ||
@@ -33,0 +32,0 @@ } |
var optimist = require('optimist'); | ||
var log = require('db-migrate-shared').log; | ||
module.exports = function(internals, isModule) { | ||
module.exports = function (internals, isModule) { | ||
var rc = require('rc'); | ||
@@ -21,4 +21,3 @@ var deepExtend = require('deep-extend'); | ||
if(!isModule) { | ||
if (!isModule) { | ||
internals.argv = optimist | ||
@@ -30,37 +29,37 @@ .default(defaultConfig) | ||
) | ||
.describe('env', | ||
'The environment to run the migrations under (dev, test, prod).') | ||
.describe( | ||
'env', | ||
'The environment to run the migrations under (dev, test, prod).' | ||
) | ||
.alias('e', 'env') | ||
.string('e') | ||
.describe('migrations-dir', 'The directory containing your migration files.') | ||
.describe( | ||
'migrations-dir', | ||
'The directory containing your migration files.' | ||
) | ||
.alias('m', 'migrations-dir') | ||
.string('m') | ||
.describe('count', 'Max number of migrations to run.') | ||
.describe('count', 'Max number of migrations to run.') | ||
.alias('c', 'count') | ||
.string('c') | ||
.describe('dry-run', 'Prints the SQL but doesn\'t run it.') | ||
.describe('dry-run', "Prints the SQL but doesn't run it.") | ||
.boolean('dry-run') | ||
.describe('force-exit', 'Forcibly exit the migration process on completion.') | ||
.describe( | ||
'force-exit', | ||
'Forcibly exit the migration process on completion.' | ||
) | ||
.boolean('force-exit') | ||
.describe('verbose', 'Verbose mode.') | ||
.describe('verbose', 'Verbose mode.') | ||
.alias('v', 'verbose') | ||
.boolean('v') | ||
.alias('h', 'help') | ||
.alias('h', 'help') | ||
.alias('h', '?') | ||
.boolean('h') | ||
.describe('version', 'Print version info.') | ||
.describe('version', 'Print version info.') | ||
.alias('i', 'version') | ||
.boolean('version') | ||
.describe('config', 'Location of the database.json file.') | ||
.describe('config', 'Location of the database.json file.') | ||
.string('config') | ||
.describe('sql-file', | ||
.describe( | ||
'sql-file', | ||
'Automatically create two sql files for up and down statements in ' + | ||
@@ -70,11 +69,12 @@ '/sqls and generate the javascript code that loads them.' | ||
.boolean('sql-file') | ||
.describe('coffee-file', 'Create a coffeescript migration file') | ||
.describe('coffee-file', 'Create a coffeescript migration file') | ||
.boolean('coffee-file') | ||
.describe('ignore-on-init', | ||
.describe( | ||
'ignore-on-init', | ||
'Create files that will run only if ignore-on-init in the env is set ' + | ||
'to false (currently works onlt with SQL)' | ||
).boolean('ignore-on-init') | ||
.describe('migration-table', | ||
'to false (currently works only with SQL)' | ||
) | ||
.boolean('ignore-on-init') | ||
.describe( | ||
'migration-table', | ||
'Set the name of the migration table, which stores the migration history.' | ||
@@ -85,28 +85,23 @@ ) | ||
.string('t') | ||
.describe('seeds-table', | ||
'Set the name of the seeds table, which stores the seed history.') | ||
.describe( | ||
'seeds-table', | ||
'Set the name of the seeds table, which stores the seed history.' | ||
) | ||
.string('seeds-table') | ||
.describe('vcseeder-dir', | ||
'Set the path to the Version Controlled Seeder directory.') | ||
.describe( | ||
'vcseeder-dir', | ||
'Set the path to the Version Controlled Seeder directory.' | ||
) | ||
.string('vcseeder-dir') | ||
.describe('staticseeder-dir', 'Set the path to the Seeder directory.') | ||
.describe('staticseeder-dir', 'Set the path to the Seeder directory.') | ||
.string('staticseeder-dir') | ||
.describe('non-transactional', 'Explicitly disable transactions') | ||
.describe('non-transactional', 'Explicitly disable transactions') | ||
.boolean('non-transactional') | ||
.describe('ignore-completed-migrations', 'Start at the first migration') | ||
.describe('ignore-completed-migrations', 'Start at the first migration') | ||
.boolean('ignore-completed-migrations') | ||
.describe('log-level', 'Set the log-level, for example sql|warn') | ||
.describe('log-level', 'Set the log-level, for example sql|warn') | ||
.string('log-level'); | ||
} | ||
else { | ||
} else { | ||
internals.argv = { | ||
get argv() { | ||
get argv () { | ||
return defaultConfig; | ||
@@ -121,11 +116,7 @@ } | ||
if(plugin) { | ||
plugin.forEach(function(plugin) { | ||
var configs = plugin['init:cli:config:hook'](); | ||
if(!configs) return; | ||
//hook not yet used, we look into migrating away from optimist first | ||
return; | ||
if (plugin) { | ||
plugin.forEach(function (plugin) { | ||
// var configs = plugin['init:cli:config:hook'](); | ||
// if (!configs) return; | ||
// hook not yet used, we look into migrating away from optimist first | ||
}); | ||
@@ -149,3 +140,2 @@ } | ||
if (internals.argv['log-level']) { | ||
log.setLogLevel(internals.argv['log-level']); | ||
@@ -167,3 +157,2 @@ } | ||
} | ||
}; |
@@ -6,36 +6,33 @@ var path = require('path'); | ||
module.exports = function(internals, config, callback) { | ||
module.exports = function (internals, config, callback) { | ||
migrationHook(internals) | ||
.then(function() { | ||
.then(function () { | ||
var Migrator = require('../migrator.js'); | ||
var index = require('../../connect'); | ||
var Migrator = require('../migrator.js'); | ||
var index = require('../../connect'); | ||
if (!internals.argv.count) { | ||
internals.argv.count = Number.MAX_VALUE; | ||
} | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Migrator, function (err, migrator) { | ||
if (!assert(err)) return; | ||
if (!internals.argv.count) { | ||
internals.argv.count = Number.MAX_VALUE; | ||
} | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Migrator, function(err, migrator) { | ||
if(!assert(err)) return; | ||
if (internals.locTitle) { | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir'], | ||
internals.locTitle); | ||
} else { migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); } | ||
if (internals.locTitle) | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir'], | ||
internals.locTitle); | ||
else | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); | ||
internals.migrationsDir = migrator.migrationsDir; | ||
internals.migrationsDir = migrator.migrationsDir; | ||
migrator.driver.createMigrationsTable(function (err) { | ||
if (!assert(err)) return; | ||
log.verbose('migration table created'); | ||
migrator.driver.createMigrationsTable(function(err) { | ||
if(!assert(err)) return; | ||
log.verbose('migration table created'); | ||
migrator.sync(internals.argv, internals.onComplete.bind(this, | ||
migrator, internals, callback)); | ||
migrator.sync(internals.argv, internals.onComplete.bind(this, | ||
migrator, internals, callback)); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; |
@@ -6,36 +6,33 @@ var path = require('path'); | ||
module.exports = function(internals, config, callback) { | ||
module.exports = function (internals, config, callback) { | ||
migrationHook(internals) | ||
.then(function() { | ||
.then(function () { | ||
var Migrator = require('../migrator.js'); | ||
var index = require('../../connect'); | ||
var Migrator = require('../migrator.js'); | ||
var index = require('../../connect'); | ||
if (!internals.argv.count) { | ||
internals.argv.count = Number.MAX_VALUE; | ||
} | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Migrator, function (err, migrator) { | ||
if (!assert(err, callback)) return; | ||
if (!internals.argv.count) { | ||
internals.argv.count = Number.MAX_VALUE; | ||
} | ||
index.connect({ | ||
config: config.getCurrent().settings, | ||
internals: internals | ||
}, Migrator, function(err, migrator) { | ||
if(!assert(err, callback)) return; | ||
if (internals.locTitle) { | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir'], | ||
internals.locTitle); | ||
} else { migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); } | ||
if (internals.locTitle) | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir'], | ||
internals.locTitle); | ||
else | ||
migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); | ||
internals.migrationsDir = migrator.migrationsDir; | ||
internals.migrationsDir = migrator.migrationsDir; | ||
migrator.driver.createMigrationsTable(function (err) { | ||
if (!assert(err, callback)) return; | ||
log.verbose('migration table created'); | ||
migrator.driver.createMigrationsTable(function(err) { | ||
if(!assert(err, callback)) return; | ||
log.verbose('migration table created'); | ||
migrator.up(internals.argv, internals.onComplete.bind(this, | ||
migrator, internals, callback)); | ||
migrator.up(internals.argv, internals.onComplete.bind(this, | ||
migrator, internals, callback)); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; |
@@ -7,22 +7,23 @@ var fs = require('fs'); | ||
var setCurrent = exports.setCurrent = function (env) { | ||
var setCurrent = (exports.setCurrent = function (env) { | ||
env = dbmUtil.isArray(env) ? env : [env]; | ||
env.forEach(function (current) { | ||
if (dbmUtil.isString(current) && this[current]) { | ||
this.getCurrent = function () { | ||
return { | ||
env: current, | ||
settings: this[current] | ||
env.forEach( | ||
function (current) { | ||
if (dbmUtil.isString(current) && this[current]) { | ||
this.getCurrent = function () { | ||
return { | ||
env: current, | ||
settings: this[current] | ||
}; | ||
}; | ||
}; | ||
} | ||
}.bind(this)); | ||
} | ||
}.bind(this) | ||
); | ||
if (!this.getCurrent) { | ||
throw new Error('Environment(s) \'' + env.join(', ') + '\' not found.'); | ||
throw new Error("Environment(s) '" + env.join(', ') + "' not found."); | ||
} | ||
}; | ||
}); | ||
function Config() { | ||
} | ||
function Config () {} | ||
@@ -33,4 +34,4 @@ Config.prototype = { | ||
exports.load = function(config, currentEnv) { | ||
if (typeof(config) === 'object') { | ||
exports.load = function (config, currentEnv) { | ||
if (typeof config === 'object') { | ||
return exports.loadObject(config, currentEnv); | ||
@@ -42,3 +43,3 @@ } else { | ||
exports.loadFile = function(fileName, currentEnv, plugins) { | ||
exports.loadFile = function (fileName, currentEnv, plugins) { | ||
var config; | ||
@@ -48,7 +49,6 @@ | ||
fs.statSync(fileName); | ||
} catch(e) { | ||
if(!process.env.DATABASE_URL) { | ||
throw new Error('Could not find database config file \'' + fileName + '\''); | ||
} | ||
else { | ||
} catch (e) { | ||
if (!process.env.DATABASE_URL) { | ||
throw new Error("Could not find database config file '" + fileName + "'"); | ||
} else { | ||
return exports.loadUrl(process.env.DATABASE_URL, currentEnv); | ||
@@ -59,18 +59,17 @@ } | ||
try { | ||
var plugin = false; | ||
if(plugins) | ||
if (plugins) { | ||
plugin = plugins.overwrite('init:config:overwrite:require'); | ||
} | ||
if(plugin !== false) { | ||
if (plugin !== false) { | ||
try { | ||
config = plugin['init:config:overwrite:require'](fileName); | ||
} | ||
catch(ex) { | ||
log.warn('Plugin failure "' + plugin.name + | ||
'", falling back to default behavior!'); | ||
} catch (ex) { | ||
log.warn( | ||
'Plugin failure "' + | ||
plugin.name + | ||
'", falling back to default behavior!' | ||
); | ||
log.verbose(ex); | ||
@@ -80,9 +79,8 @@ | ||
} | ||
} else { | ||
config = require(fileName); | ||
} | ||
else | ||
config = require(fileName); | ||
} catch(e) { | ||
} catch (e) { | ||
// distinguish broken files from missing ones | ||
if (e instanceof SyntaxError){ | ||
if (e instanceof SyntaxError) { | ||
throw e; | ||
@@ -93,9 +91,6 @@ } | ||
config = require(path.join(process.cwd(), fileName)); | ||
} | ||
catch(e) { | ||
if(!process.env.DATABASE_URL) { | ||
} catch (e) { | ||
if (!process.env.DATABASE_URL) { | ||
throw e; | ||
} | ||
else { | ||
} else { | ||
return exports.loadUrl(process.env.DATABASE_URL, currentEnv); | ||
@@ -109,17 +104,13 @@ } | ||
function walkConfig(level) { | ||
function walkConfig (level) { | ||
for (var configEntry in level) { | ||
if (level[configEntry] && level[configEntry].ENV){ | ||
if(!process.env[level[configEntry].ENV]) { | ||
log.verbose('Environment variable ' + level[configEntry].ENV + | ||
' is empty!'); | ||
if (level[configEntry] && level[configEntry].ENV) { | ||
if (!process.env[level[configEntry].ENV]) { | ||
log.verbose( | ||
'Environment variable ' + level[configEntry].ENV + ' is empty!' | ||
); | ||
} | ||
level[configEntry] = process.env[level[configEntry].ENV]; | ||
} | ||
else if(level[configEntry] && typeof(level[configEntry]) === 'object') { | ||
level[configEntry] = process.env[level[configEntry].ENV]; | ||
} else if (level[configEntry] && typeof level[configEntry] === 'object') { | ||
level[configEntry] = walkConfig(level[configEntry]); | ||
@@ -132,4 +123,3 @@ } | ||
exports.loadObject = function(_config, currentEnv) { | ||
exports.loadObject = function (_config, currentEnv) { | ||
var out = new Config(); | ||
@@ -140,13 +130,13 @@ // do not overwrite the users config | ||
for (var env in config) { | ||
if (config[env].ENV) { | ||
if(!process.env[config[env].ENV]) | ||
if (!process.env[config[env].ENV]) { | ||
log.verbose('Environment variable ' + config[env].ENV + ' is empty!'); | ||
else | ||
} else { | ||
out[env] = parseDatabaseUrl(process.env[config[env].ENV]); | ||
} else if (typeof(config[env]) === 'string') { | ||
} | ||
} else if (typeof config[env] === 'string') { | ||
out[env] = parseDatabaseUrl(config[env]); | ||
} else { | ||
//Check config entry's for ENV objects | ||
//which will tell us to grab configuration from the environment | ||
// Check config entry's for ENV objects | ||
// which will tell us to grab configuration from the environment | ||
config[env] = walkConfig(config[env]); | ||
@@ -156,5 +146,4 @@ out[env] = config[env]; | ||
if(typeof(config[env].url) === 'string' || process.env.DATABASE_URL) { | ||
if(typeof(config[env].url) !== 'string') { | ||
if (typeof config[env].url === 'string' || process.env.DATABASE_URL) { | ||
if (typeof config[env].url !== 'string') { | ||
config[env] = Object.assign( | ||
@@ -164,4 +153,3 @@ config[env], | ||
); | ||
} | ||
else { | ||
} else { | ||
config[env] = Object.assign( | ||
@@ -173,20 +161,18 @@ config[env], | ||
delete config[env].url; | ||
} | ||
else if(config[env].url && config[env].url.value) { | ||
} else if (config[env].url && config[env].url.value) { | ||
config[env].url = config[env].url.value; | ||
} | ||
if(config[env].overwrite || config[env].addIfNotExists) { | ||
if (config[env].overwrite || config[env].addIfNotExists) { | ||
var overwrite = config[env].overwrite || {}; | ||
if(config[env].addIfNotExists) { | ||
if (config[env].addIfNotExists) { | ||
var addIfNotExists = config[env].addIfNotExists; | ||
Object.keys(addIfNotExists).filter(function(key) { | ||
return !overwrite[key] && !config[env][key]; | ||
}).forEach(function(key) { | ||
config[env][key] = addIfNotExists[key]; | ||
}); | ||
Object.keys(addIfNotExists) | ||
.filter(function (key) { | ||
return !overwrite[key] && !config[env][key]; | ||
}) | ||
.forEach(function (key) { | ||
config[env][key] = addIfNotExists[key]; | ||
}); | ||
@@ -196,3 +182,3 @@ delete config[env].addIfNotExists; | ||
Object.keys(overwrite).forEach(function(key) { | ||
Object.keys(overwrite).forEach(function (key) { | ||
config[env][key] = overwrite[key]; | ||
@@ -205,7 +191,7 @@ }); | ||
if(currentEnv) { | ||
if (currentEnv) { | ||
out.setCurrent(currentEnv); | ||
} else if(config['default']) { | ||
} else if (config['default']) { | ||
out.setCurrent(config['default']); | ||
} else if(config.defaultEnv) { | ||
} else if (config.defaultEnv) { | ||
if (config.defaultEnv.ENV) { | ||
@@ -223,5 +209,5 @@ out.setCurrent(process.env[config.defaultEnv.ENV]); | ||
exports.loadUrl = function(databaseUrl, currentEnv) { | ||
var config = parseDatabaseUrl(databaseUrl), | ||
out = new Config(); | ||
exports.loadUrl = function (databaseUrl, currentEnv) { | ||
var config = parseDatabaseUrl(databaseUrl); | ||
var out = new Config(); | ||
@@ -228,0 +214,0 @@ if (currentEnv) { |
@@ -8,10 +8,11 @@ var internals = {}; | ||
var log = internals.mod.log; | ||
var Promise = require('bluebird'), | ||
SeederInterface = require('../interface/seederInterface.js'), | ||
MigratorInterface = require('../interface/migratorInterface.js'), | ||
resolve = require( 'resolve' ); | ||
var Promise = require('bluebird'); | ||
var SeederInterface = require('../interface/seederInterface.js'); | ||
var MigratorInterface = require('../interface/migratorInterface.js'); | ||
var resolve = require('resolve'); | ||
var ShadowProto = { | ||
createTable: function() { return Promise.resolve(); } | ||
createTable: function () { | ||
return Promise.resolve(); | ||
} | ||
}; | ||
@@ -26,5 +27,4 @@ | ||
//add interface extensions to allow drivers to add new methods | ||
// add interface extensions to allow drivers to add new methods | ||
internals.interfaces = { | ||
SeederInterface: SeederInterface.extending, | ||
@@ -34,22 +34,20 @@ MigratorInterface: MigratorInterface.extending | ||
if ( !config.user && config.username ) | ||
if (!config.user && config.username) { | ||
config.user = config.username; | ||
} | ||
if (config.driver === undefined) { | ||
throw new Error( | ||
'config must include a driver key specifing which driver to use'); | ||
'config must include a driver key specifing which driver to use' | ||
); | ||
} | ||
if (config.driver && typeof (config.driver) === 'object') { | ||
if (config.driver && typeof config.driver === 'object') { | ||
log.verbose('require:', config.driver.require); | ||
driver = require(config.driver.require); | ||
} | ||
else { | ||
switch(config.driver) { | ||
} else { | ||
switch (config.driver) { | ||
case 'sqlite': | ||
config.driver = 'sqlite3'; | ||
break; | ||
break; | ||
@@ -59,42 +57,36 @@ case 'postgres': | ||
config.driver = 'pg'; | ||
break; | ||
break; | ||
} | ||
try { | ||
req = 'db-migrate-' + config.driver; | ||
log.verbose('require:', req); | ||
try { | ||
driver = require( | ||
resolve.sync(req, { basedir: process.cwd() }) | ||
); | ||
} | ||
catch(e1) { | ||
driver = require(resolve.sync(req, { basedir: process.cwd() })); | ||
} catch (e1) { | ||
try { | ||
driver = require(req); | ||
} | ||
catch (e2) { | ||
} catch (e2) { | ||
driver = require('../../../' + req); | ||
} | ||
} | ||
} | ||
catch (e3) { | ||
} catch (e3) { | ||
try { | ||
//Fallback to internal drivers, while moving drivers to new repos | ||
// Fallback to internal drivers, while moving drivers to new repos | ||
req = './' + config.driver; | ||
log.verbose('require:', req); | ||
driver = require(req); | ||
} catch (e4) { | ||
return callback( | ||
new Error({ | ||
stack: | ||
'No such driver found, please try to install it via ' + | ||
'npm install db-migrate-' + | ||
config.driver + | ||
' or ' + | ||
'npm install -g db-migrate-' + | ||
config.driver | ||
}) | ||
); | ||
} | ||
catch (e4) { | ||
return callback( { stack: 'No such driver found, please try to install it via ' + | ||
'npm install db-migrate-' + config.driver + ' or ' + | ||
'npm install -g db-migrate-' + config.driver } ); | ||
} | ||
} | ||
@@ -105,7 +97,5 @@ } | ||
var connect = function(config) { | ||
var connect = function (config) { | ||
driver.connect(config, intern, function (err, db) { | ||
if (err) { | ||
callback(err); | ||
@@ -116,4 +106,5 @@ return; | ||
if (!global.immunity) | ||
if (!global.immunity) { | ||
db = Shadow.infect(db, internals, ShadowProto); | ||
} | ||
@@ -131,3 +122,5 @@ callback(null, db); | ||
if (tunnelConfig.privateKeyPath) { | ||
tunnelConfig.privateKey = require('fs').readFileSync(tunnelConfig.privateKeyPath); | ||
tunnelConfig.privateKey = require('fs').readFileSync( | ||
tunnelConfig.privateKeyPath | ||
); | ||
} | ||
@@ -148,6 +141,5 @@ | ||
}); | ||
} | ||
else { | ||
} else { | ||
connect(config); | ||
} | ||
}; |
@@ -14,29 +14,26 @@ /** | ||
*/ | ||
exports.infect = function(db, intern, ShadowProto) { | ||
var internals = intern; | ||
exports.infect = function (db, intern, ShadowProto) { | ||
db._shadowsHost = {}; | ||
db._shadowProto = {}; | ||
for(var prop in db) { | ||
if (typeof ShadowProto[prop] === "function" && | ||
typeof db[prop] === "function") { | ||
for (var prop in db) { | ||
if ( | ||
typeof ShadowProto[prop] === 'function' && | ||
typeof db[prop] === 'function' | ||
) { | ||
db._shadowsHost[prop] = db[prop]; | ||
db._shadowProto[prop] = ShadowProto[prop]; | ||
(function(property) { | ||
(function (property) { | ||
db[property] = function () { | ||
var params = arguments; | ||
var self = this; | ||
db[property] = function() { | ||
var params = arguments, | ||
self = this; | ||
return self._shadowProto[property].apply(self, params) | ||
.then( function() { | ||
return self._shadowsHost[property].apply(self, params); | ||
}.bind(this)); | ||
return self._shadowProto[property] | ||
.apply(self, params) | ||
.then(function () { | ||
return self._shadowsHost[property].apply(self, params); | ||
}); | ||
}; | ||
}(prop)); | ||
})(prop); | ||
} | ||
@@ -43,0 +40,0 @@ } |
@@ -28,8 +28,7 @@ /** | ||
function dummy() { | ||
function dummy () { | ||
arguments[arguments.length - 1]('not implemented'); | ||
} | ||
function MigratorInterface() { | ||
function MigratorInterface () { | ||
@@ -126,12 +125,10 @@ } | ||
module.exports = MigratorInterface; | ||
module.exports.deprecated = { | ||
insert: function() { | ||
insert: function () { | ||
arguments[arguments.length - 1]('not implemented'); | ||
}, | ||
arguments[arguments.length - 1]('not implemented'); | ||
}, | ||
insert_deprecation: 'is going to be completely removed, use version controlled seeds instead.' | ||
insert_deprecation: 'is going to be completely removed, use version controlled seeds instead.' | ||
}; | ||
@@ -138,0 +135,0 @@ |
@@ -42,33 +42,20 @@ /** | ||
function _l( field ) { | ||
return { type: 'lookup', field: field }; | ||
} | ||
function insert(table, options, callback) { | ||
function insert (table, options, callback) { | ||
var foreignLinkage = this.foreignLinkage[table]; | ||
for(var o = 0; o < options.length; ++o) | ||
{ | ||
for (var o = 0; o < options.length; ++o) { | ||
var option = Object.keys(options[o]); | ||
for(var i = 0; i < option.length; ++i) { | ||
if (typeof(options[option[i]]) === 'object') { | ||
for (var i = 0; i < option.length; ++i) { | ||
if (typeof options[option[i]] === 'object') { | ||
if (options[option[i]].type === 'lookup') { | ||
if (!options[option[i]].table) { | ||
if (foreignLinkage[option[i]]) { | ||
options[option[i]].table = foreignLinkage[option[i]].table; | ||
options[option[i]].field = foreignLinkage[option[i]].field; | ||
} else { | ||
return Promise.reject( | ||
new Error('missing foreign key linkage!') | ||
).nodeify(callback); | ||
} | ||
else { | ||
return Promise.reject('missing foreign key linkage!'). | ||
nodeify(callback); | ||
} | ||
} | ||
@@ -81,33 +68,26 @@ } | ||
return lookup(options) | ||
.then(function(){ | ||
return this.driver.insert(options); | ||
}) | ||
.catch(function(e) { | ||
throw e; | ||
}) | ||
.nodeify(callback); | ||
.then(function () { | ||
return this.driver.insert(options); | ||
}) | ||
.catch(function (e) { | ||
throw e; | ||
}) | ||
.nodeify(callback); | ||
} | ||
function lookup(options) { | ||
function lookup (options) { | ||
var lookups = []; | ||
var i = 0; | ||
var lookups = [], | ||
i = 0; | ||
for(var o = 0; o < options.length; ++o) | ||
{ | ||
for (var o = 0; o < options.length; ++o) { | ||
var option = Object.keys(options[o]); | ||
for(; i < option.length; ++i) { | ||
if (typeof(options[option]) === 'object') { | ||
for (; i < option.length; ++i) { | ||
if (typeof options[option] === 'object') { | ||
if (options[option].type === 'lookup') { | ||
lookups.push(this.driver.lookup(options[option]) | ||
.catch(function(err) { | ||
throw err; | ||
})); | ||
lookups.push( | ||
this.driver.lookup(options[option]).catch(function (err) { | ||
throw err; | ||
}) | ||
); | ||
} | ||
@@ -121,53 +101,48 @@ } | ||
function dummy() { | ||
arguments[arguments.length - 1]('not implemented'); | ||
function dummy () { | ||
arguments[arguments.length - 1]('not implemented'); | ||
} | ||
var SeederInterface = { | ||
lookup: dummy, | ||
lookup: dummy, | ||
insert: dummy, | ||
insert: dummy, | ||
delete: dummy, | ||
delete: dummy, | ||
runSql: dummy, | ||
runSql: dummy, | ||
buildWhereClause: dummy, | ||
buildWhereClause: dummy, | ||
quoteDDLArr: dummy, | ||
quoteDDLArr: dummy, | ||
quoteArr: dummy, | ||
quoteArr: dummy, | ||
escapeString: dummy, | ||
escapeString: dummy, | ||
escape: dummy, | ||
escape: dummy, | ||
escapeDDL: dummy, | ||
escapeDDL: dummy, | ||
checkDBMS: dummy, | ||
checkDBMS: dummy, | ||
update: dummy, | ||
update: dummy, | ||
truncate: dummy, | ||
truncate: dummy, | ||
switchDatabase: dummy, | ||
switchDatabase: dummy, | ||
remove: dummy, | ||
remove: dummy, | ||
close: dummy | ||
close: dummy | ||
}; | ||
module.exports = SeederInterface; | ||
module.exports.deprecated = { | ||
}; | ||
module.exports.deprecated = {}; | ||
module.exports.extending = { | ||
_l: function( field ) { | ||
return { type: 'lookup', field: field }; | ||
} | ||
_l: function (field) { | ||
return { type: 'lookup', field: field }; | ||
}, | ||
__Test__insert: insert, | ||
__Test__lookup: lookup | ||
}; |
@@ -8,12 +8,5 @@ var fs = require('fs'); | ||
var filesRegEx = /\.js$/; | ||
var internals = {}; | ||
function writeMigrationRecord(db, migration, callback) { | ||
db._runSql('INSERT INTO ' + internals.migrationTable + | ||
' (name, run_on) VALUES (?, ?)', [migration.name, new Date()], callback); | ||
} | ||
var Migration = Skeleton.extend({ | ||
init: function() { | ||
init: function () { | ||
if (arguments.length >= 3) { | ||
@@ -38,5 +31,4 @@ this.title = arguments[0]; | ||
Migration.registerHook = function(plugin, internals) { | ||
var plugin = plugin.hook('migrator:migration:hook:require'); | ||
Migration.registerHook = function (Plugin, internals) { | ||
var plugin = Plugin.hook('migrator:migration:hook:require'); | ||
internals.parser = internals.parser || { | ||
@@ -47,30 +39,28 @@ filesRegEx: filesRegEx, | ||
if(!plugin) | ||
if (!plugin) { | ||
return Promise.resolve(null); | ||
} | ||
return Promise.resolve(plugin) | ||
.map(function(plugin) { | ||
.map(function (plugin) { | ||
return plugin['migrator:migration:hook:require'](); | ||
}) | ||
.each(function (parser) { | ||
if (parser && parser.extensions) { | ||
internals.parser.extensions = | ||
internals.parser.extensions + '|' + parser.extensions; | ||
} | ||
}) | ||
.then(function () { | ||
internals.parser.filesRegEx = new RegExp( | ||
'\\.(' + internals.parser.extensions + ')$' | ||
); | ||
return plugin['migrator:migration:hook:require'](); | ||
}) | ||
.each(function(parser) { | ||
if(parser && parser.extensions) | ||
internals.parser.extensions = internals.parser.extensions + '|' + | ||
parser.extensions; | ||
}) | ||
.then(function() { | ||
internals.parser.filesRegEx = new RegExp( | ||
'\\.(' + | ||
internals.parser.extensions + | ||
')$' | ||
); | ||
return internals.parser; | ||
}); | ||
return internals.parser; | ||
}); | ||
}; | ||
Migration.prototype.defaultCoffeeTemplate = function() { | ||
Migration.prototype.defaultCoffeeTemplate = function () { | ||
return [ | ||
'\'use strict\';', | ||
"'use strict';", | ||
'', | ||
@@ -96,5 +86,5 @@ 'dbm = undefined', | ||
Migration.prototype.defaultJsTemplate = function() { | ||
Migration.prototype.defaultJsTemplate = function () { | ||
return [ | ||
'\'use strict\';', | ||
"'use strict';", | ||
'', | ||
@@ -130,10 +120,9 @@ 'var dbm;', | ||
Migration.prototype.defaultSqlTemplate = function() { | ||
Migration.prototype.defaultSqlTemplate = function () { | ||
return '/* Replace with your SQL commands */'; | ||
}; | ||
Migration.prototype.sqlFileLoaderTemplate = function() { | ||
Migration.prototype.sqlFileLoaderTemplate = function () { | ||
return [ | ||
'\'use strict\';', | ||
"'use strict';", | ||
'', | ||
@@ -143,4 +132,4 @@ 'var dbm;', | ||
'var seed;', | ||
'var fs = require(\'fs\');', | ||
'var path = require(\'path\');', | ||
"var fs = require('fs');", | ||
"var path = require('path');", | ||
'var Promise;', | ||
@@ -160,8 +149,9 @@ '', | ||
'exports.up = function(db) {', | ||
' var filePath = path.join(__dirname, \'sqls\', \'' + this.name.replace( | ||
'.js', '') + '-up.sql\');', | ||
" var filePath = path.join(__dirname, 'sqls', '" + | ||
this.name.replace('.js', '') + | ||
"-up.sql');", | ||
' return new Promise( function( resolve, reject ) {', | ||
' fs.readFile(filePath, {encoding: \'utf-8\'}, function(err,data){', | ||
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", | ||
' if (err) return reject(err);', | ||
' console.log(\'received data: \' + data);', | ||
" console.log('received data: ' + data);", | ||
'', | ||
@@ -177,8 +167,9 @@ ' resolve(data);', | ||
'exports.down = function(db) {', | ||
' var filePath = path.join(__dirname, \'sqls\', \'' + this.name.replace( | ||
'.js', '') + '-down.sql\');', | ||
" var filePath = path.join(__dirname, 'sqls', '" + | ||
this.name.replace('.js', '') + | ||
"-down.sql');", | ||
' return new Promise( function( resolve, reject ) {', | ||
' fs.readFile(filePath, {encoding: \'utf-8\'}, function(err,data){', | ||
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", | ||
' if (err) return reject(err);', | ||
' console.log(\'received data: \' + data);', | ||
" console.log('received data: ' + data);", | ||
'', | ||
@@ -200,5 +191,5 @@ ' resolve(data);', | ||
Migration.prototype.sqlFileLoaderIgnoreOnInitTemplate = function() { | ||
Migration.prototype.sqlFileLoaderIgnoreOnInitTemplate = function () { | ||
return [ | ||
'\'use strict\';', | ||
"'use strict';", | ||
'', | ||
@@ -208,4 +199,4 @@ 'var dbm;', | ||
'var seed;', | ||
'var fs = require(\'fs\');', | ||
'var path = require(\'path\');', | ||
"var fs = require('fs');", | ||
"var path = require('path');", | ||
'var ignoreOnInit = false;', | ||
@@ -227,9 +218,10 @@ 'var Promise;', | ||
'exports.up = function(db, callback) {', | ||
' var filePath = path.join(__dirname + \'/sqls/' + this.name.replace( | ||
'.js', '') + '-up.sql\');', | ||
" var filePath = path.join(__dirname + '/sqls/" + | ||
this.name.replace('.js', '') + | ||
"-up.sql');", | ||
' if (!ignoreOnInit) {', | ||
' return new Promise( function( resolve, reject ) {', | ||
' fs.readFile(filePath, {encoding: \'utf-8\'}, function(err,data){', | ||
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", | ||
' if (err) return reject(err);', | ||
' console.log(\'received data: \' + data);', | ||
" console.log('received data: ' + data);", | ||
'', | ||
@@ -244,3 +236,3 @@ ' resolve(data);', | ||
' else {', | ||
' console.log(\'ignoring on init: \' + filePath)', | ||
" console.log('ignoring on init: ' + filePath)", | ||
' return null;', | ||
@@ -251,8 +243,9 @@ ' }', | ||
'exports.down = function(db, callback) {', | ||
' var filePath = path.join(__dirname + \'/sqls/' + this.name.replace( | ||
'.js', '') + '-down.sql\');', | ||
" var filePath = path.join(__dirname + '/sqls/" + | ||
this.name.replace('.js', '') + | ||
"-down.sql');", | ||
' return new Promise( function( resolve, reject ) {', | ||
' fs.readFile(filePath, {encoding: \'utf-8\'}, function(err,data){', | ||
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", | ||
' if (err) return reject(err);', | ||
' console.log(\'received data: \' + data);', | ||
" console.log('received data: ' + data);", | ||
'', | ||
@@ -274,5 +267,5 @@ ' resolve(data);', | ||
Migration.prototype.coffeeSqlFileLoaderTemplate = function() { | ||
Migration.prototype.coffeeSqlFileLoaderTemplate = function () { | ||
return [ | ||
'\'use strict\';', | ||
"'use strict';", | ||
'', | ||
@@ -282,4 +275,4 @@ 'dbm = undefined', | ||
'seed = undefined', | ||
'fs = require \'fs\'', | ||
'path = require \'path\'', | ||
"fs = require 'fs'", | ||
"path = require 'path'", | ||
'', | ||
@@ -297,5 +290,6 @@ '#', | ||
'exports.up = (db, callback) ->', | ||
' filePath = path.join "#{__dirname}/sqls/' + this.name.replace( | ||
'.coffee', '') + '-up.sql"', | ||
' fs.readFile filePath, {encoding: \'utf-8\'}, (err,data) ->', | ||
' filePath = path.join "#{__dirname}/sqls/' + | ||
this.name.replace('.coffee', '') + | ||
'-up.sql"', | ||
" fs.readFile filePath, {encoding: 'utf-8'}, (err,data) ->", | ||
' return callback err if err', | ||
@@ -306,6 +300,7 @@ '', | ||
'exports.down = (db, callback) ->', | ||
' filePath = path.join "#{__dirname}/sqls/' + this.name.replace( | ||
'.coffee', '') + '-down.sql"', | ||
' filePath = path.join "#{__dirname}/sqls/' + | ||
this.name.replace('.coffee', '') + | ||
'-down.sql"', | ||
' fs.readFile filePath, {encoding: \'utf-8\'}, (err,data) ->', | ||
" fs.readFile filePath, {encoding: 'utf-8'}, (err,data) ->", | ||
' return callback err if err', | ||
@@ -327,3 +322,3 @@ '', | ||
Migration.prototype.getTemplate = function() { | ||
Migration.prototype.getTemplate = function () { | ||
switch (this.templateType) { | ||
@@ -341,3 +336,3 @@ case Migration.TemplateType.DEFAULT_SQL: | ||
case Migration.TemplateType.DEFAULT_JS: | ||
/* falls through */ | ||
/* falls through */ | ||
default: | ||
@@ -348,9 +343,9 @@ return this.defaultJsTemplate(); | ||
Migration.prototype.write = function(callback) { | ||
Migration.prototype.write = function (callback) { | ||
fs.writeFile(this.path, this.getTemplate(), callback); | ||
}; | ||
Migration.loadFromFilesystem = function(dir, internals, callback) { | ||
Migration.loadFromFilesystem = function (dir, internals, callback) { | ||
log.verbose('loading migrations from dir', dir); | ||
fs.readdir(dir, function(err, files) { | ||
fs.readdir(dir, function (err, files) { | ||
if (err) { | ||
@@ -360,8 +355,6 @@ callback(err); | ||
} | ||
var coffeeWarn = true; | ||
files = files.filter(function(file) { | ||
files = files.filter(function (file) { | ||
return internals.parser.filesRegEx.test(file); | ||
}); | ||
var migrations = files.sort().map(function(file) { | ||
var migrations = files.sort().map(function (file) { | ||
return new Migration(path.join(dir, file), internals); | ||
@@ -373,10 +366,8 @@ }); | ||
Migration.loadFromDatabase = function(dir, driver, internals, callback) { | ||
Migration.loadFromDatabase = function (dir, driver, internals, callback) { | ||
if (internals.ignoreCompleted) { | ||
callback(null, []); | ||
} else { | ||
log.verbose('loading migrations from database'); | ||
driver.allLoadedMigrations(function(err, dbResults) { | ||
driver.allLoadedMigrations(function (err, dbResults) { | ||
if (err && !internals.dryRun) { | ||
@@ -388,8 +379,12 @@ callback(err); | ||
} | ||
var migrations = dbResults.filter(function(result) { | ||
return result.name.substr(0, result.name.lastIndexOf('/')) === | ||
internals.matching; | ||
}).map(function(result) { | ||
return new Migration(path.join(dir, result.name), internals); | ||
}); | ||
var migrations = dbResults | ||
.filter(function (result) { | ||
return ( | ||
result.name.substr(0, result.name.lastIndexOf('/')) === | ||
internals.matching | ||
); | ||
}) | ||
.map(function (result) { | ||
return new Migration(path.join(dir, result.name), internals); | ||
}); | ||
@@ -401,7 +396,2 @@ callback(null, migrations); | ||
Migration.exportInternals = function(intern) { | ||
internals = intern; | ||
}; | ||
module.exports = Migration; |
@@ -5,47 +5,44 @@ var dbmUtil = require('db-migrate-shared').util; | ||
var Promise = require('bluebird'); | ||
var MigratorInterface = require( './interface/migratorInterface.js'); | ||
var MigratorInterface = require('./interface/migratorInterface.js'); | ||
function SeedLink(driver, internals) { | ||
function SeedLink (driver, internals) { | ||
this.seeder = require('./seeder.js')( | ||
driver, internals.argv['vcseeder-dir'], true, internals | ||
driver, | ||
internals.argv['vcseeder-dir'], | ||
true, | ||
internals | ||
); | ||
this.internals = internals; | ||
this.links = []; | ||
} | ||
SeedLink.prototype = { | ||
seed: function (partialName) { | ||
var reset = !this.internals.notransactions; | ||
seed: function( partialName ) { | ||
this.internals.notransactions = true; | ||
var reset = !internals.notransactions; | ||
return new Promise(function (resolve, reject) { | ||
this.seeder.up(partialName, function (err) { | ||
if (reset) { | ||
this.internals.notransactions = false; | ||
} | ||
internals.notransactions = true; | ||
return new Promise( function( resolve, reject ) { | ||
this.seeder.up( partialName, function( err ) { | ||
if( reset ) | ||
internals.notransactions = false; | ||
if ( err ) | ||
reject( err ); | ||
else | ||
resolve( err ); | ||
} ); | ||
} ); | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(err); | ||
} | ||
}); | ||
}); | ||
}, | ||
link: function( partialName ) { | ||
this.links.push( partialName ); | ||
link: function (partialName) { | ||
this.links.push(partialName); | ||
}, | ||
process: function() { | ||
process: function () { | ||
this.clear(); | ||
}, | ||
clear: function() { | ||
clear: function () { | ||
this.links = []; | ||
@@ -55,4 +52,4 @@ } | ||
var Migrator = function(driver, migrationsDir, empty, intern) { | ||
this.driver = dbmUtil.reduceToInterface( driver, MigratorInterface ); | ||
var Migrator = function (driver, migrationsDir, empty, intern) { | ||
this.driver = dbmUtil.reduceToInterface(driver, MigratorInterface); | ||
this._driver = driver; | ||
@@ -62,4 +59,3 @@ this.migrationsDir = migrationsDir; | ||
if(intern.linked === false) { | ||
if (intern.linked === false) { | ||
this.seedLink = new SeedLink(driver, intern); | ||
@@ -70,13 +66,11 @@ intern.linked = true; | ||
this.internals.migrationOptions.relation = require('./relation'); | ||
Migration.exportInternals(intern); | ||
}; | ||
Migrator.prototype = { | ||
createMigrationsTable: function(callback) { | ||
createMigrationsTable: function (callback) { | ||
this._driver.createMigrationsTable(callback); | ||
}, | ||
writeMigrationRecord: function(migration, callback) { | ||
function onComplete(err) { | ||
writeMigrationRecord: function (migration, callback) { | ||
function onComplete (err) { | ||
if (err) { | ||
@@ -89,7 +83,10 @@ log.error(migration.name, err); | ||
} | ||
this._driver.addMigrationRecord(this.internals.matching + '/' + migration.name, onComplete); | ||
this._driver.addMigrationRecord( | ||
this.internals.matching + '/' + migration.name, | ||
onComplete | ||
); | ||
}, | ||
deleteMigrationRecord: function(migration, callback) { | ||
function onComplete(err) { | ||
deleteMigrationRecord: function (migration, callback) { | ||
function onComplete (err) { | ||
if (err) { | ||
@@ -102,16 +99,15 @@ log.error(migration.name, err); | ||
} | ||
this._driver.deleteMigration(this.internals.matching + '/' + migration.name, function(err) { | ||
if(!this.internals.matching) { | ||
this._driver.deleteMigration(migration.name, onComplete); | ||
} | ||
else { | ||
onComplete.apply(err); | ||
} | ||
}.bind(this)); | ||
this._driver.deleteMigration( | ||
this.internals.matching + '/' + migration.name, | ||
function (err) { | ||
if (!this.internals.matching) { | ||
this._driver.deleteMigration(migration.name, onComplete); | ||
} else { | ||
onComplete.apply(err); | ||
} | ||
}.bind(this) | ||
); | ||
}, | ||
up: function(funcOrOpts, callback) { | ||
up: function (funcOrOpts, callback) { | ||
if (dbmUtil.isFunction(funcOrOpts)) { | ||
@@ -124,3 +120,3 @@ return funcOrOpts(this.driver, callback); | ||
down: function(funcOrOpts, callback) { | ||
down: function (funcOrOpts, callback) { | ||
if (dbmUtil.isFunction(funcOrOpts)) { | ||
@@ -133,120 +129,149 @@ return funcOrOpts(this.driver, callback); | ||
sync: function(funcOrOpts, callback) { | ||
sync: function (funcOrOpts, callback) { | ||
var self = this; | ||
Migration.loadFromDatabase(self.migrationsDir, self._driver, | ||
self.internals, function(err, completedMigrations) { | ||
if (err) { callback(err); return; } | ||
Migration.loadFromDatabase( | ||
self.migrationsDir, | ||
self._driver, | ||
self.internals, | ||
function (err, completedMigrations) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
var mode = dbmUtil.syncMode( | ||
completedMigrations, | ||
funcOrOpts.destination | ||
); | ||
if(mode === 1) { | ||
log.info('Syncing upwards.'); | ||
self.up(funcOrOpts, callback); | ||
var mode = dbmUtil.syncMode( | ||
completedMigrations, | ||
funcOrOpts.destination | ||
); | ||
if (mode === 1) { | ||
log.info('Syncing upwards.'); | ||
self.up(funcOrOpts, callback); | ||
} else { | ||
log.info('Syncing downwards.'); | ||
self.down(funcOrOpts, callback); | ||
} | ||
} | ||
else { | ||
log.info('Syncing downwards.'); | ||
self.down(funcOrOpts, callback); | ||
} | ||
}); | ||
); | ||
}, | ||
upToBy: function(partialName, count, callback) { | ||
upToBy: function (partialName, count, callback) { | ||
var self = this; | ||
Migration.loadFromFilesystem(self.migrationsDir, self.internals, function(err, allMigrations) { | ||
if (err) { callback(err); return; } | ||
Migration.loadFromFilesystem(self.migrationsDir, self.internals, function ( | ||
err, | ||
allMigrations | ||
) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
Migration.loadFromDatabase(self.migrationsDir, self._driver, self.internals, function(err, completedMigrations) { | ||
if (err) { callback(err); return; } | ||
var toRun = dbmUtil.filterUp(allMigrations, completedMigrations, partialName, count); | ||
Migration.loadFromDatabase( | ||
self.migrationsDir, | ||
self._driver, | ||
self.internals, | ||
function (err, completedMigrations) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
var toRun = dbmUtil.filterUp( | ||
allMigrations, | ||
completedMigrations, | ||
partialName, | ||
count | ||
); | ||
if (toRun.length === 0) { | ||
log.info('No migrations to run'); | ||
callback(null); | ||
return; | ||
} | ||
if (toRun.length === 0) { | ||
log.info('No migrations to run'); | ||
callback(null); | ||
return; | ||
} | ||
return Promise.resolve(toRun).each(function(migration) { | ||
return Promise.resolve(toRun) | ||
.each(function (migration) { | ||
log.verbose('preparing to run up migration:', migration.name); | ||
log.verbose('preparing to run up migration:', migration.name); | ||
return self.driver | ||
.startMigration() | ||
.then(function () { | ||
var setup = migration.setup(); | ||
return self.driver.startMigration() | ||
.then(function() { | ||
if (typeof setup === 'function') { | ||
setup(self.internals.migrationOptions, self.seedLink); | ||
} | ||
var setup = migration.setup(); | ||
return self.up(migration.up.bind(migration)); | ||
}) | ||
.then(function () { | ||
if (self.seedLink && self.seedLink.links.length) { | ||
log.info('Calling linked seeds'); | ||
if(typeof(setup) === 'function') | ||
setup(self.internals.migrationOptions, self.seedLink); | ||
return self.up(migration.up.bind(migration)); | ||
}) | ||
.then(function() { | ||
if( self.seedLink && self.seedLink.links.length ) { | ||
log.info('Calling linked seeds'); | ||
return self.seedLink.process(); | ||
} | ||
return; | ||
}) | ||
.then(function() { | ||
return (Promise.promisify(self.writeMigrationRecord.bind(self)))(migration); | ||
}) | ||
.then(self.driver.endMigration.bind(self.driver)); | ||
}) | ||
.nodeify(callback); | ||
}); | ||
return self.seedLink.process(); | ||
} | ||
}) | ||
.then(function () { | ||
return Promise.promisify( | ||
self.writeMigrationRecord.bind(self) | ||
)(migration); | ||
}) | ||
.then(self.driver.endMigration.bind(self.driver)); | ||
}) | ||
.nodeify(callback); | ||
} | ||
); | ||
}); | ||
}, | ||
downToBy: function(partialName, count, callback) { | ||
downToBy: function (partialName, count, callback) { | ||
var self = this; | ||
Migration.loadFromDatabase(self.migrationsDir, self._driver, self.internals, function(err, completedMigrations) { | ||
if (err) { return callback(err); } | ||
Migration.loadFromDatabase( | ||
self.migrationsDir, | ||
self._driver, | ||
self.internals, | ||
function (err, completedMigrations) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
var toRun = dbmUtil.filterDown(completedMigrations, partialName, count); | ||
var toRun = dbmUtil.filterDown(completedMigrations, partialName, count); | ||
if (toRun.length === 0) { | ||
log.info('No migrations to run'); | ||
callback(null); | ||
return; | ||
} | ||
if (toRun.length === 0) { | ||
log.info('No migrations to run'); | ||
callback(null); | ||
return; | ||
} | ||
return Promise.resolve(toRun).each(function(migration) { | ||
return Promise.resolve(toRun) | ||
.each(function (migration) { | ||
log.verbose('preparing to run down migration:', migration.name); | ||
log.verbose('preparing to run down migration:', migration.name); | ||
return self.driver | ||
.startMigration() | ||
.then(function () { | ||
var setup = migration.setup(); | ||
return self.driver.startMigration() | ||
.then(function() { | ||
var setup = migration.setup(); | ||
if (typeof setup === 'function') { | ||
setup(self.internals.migrationOptions, self.seedLink); | ||
} | ||
if(typeof(setup) === 'function') | ||
setup(self.internals.migrationOptions, self.seedLink); | ||
return self.down(migration.down.bind(migration)); | ||
}) | ||
.then(function () { | ||
if (self.seedLink && self.seedLink.links.length) { | ||
log.info('Calling linked seeds'); | ||
return self.down(migration.down.bind(migration)); | ||
}) | ||
.then(function() { | ||
if( self.seedLink && self.seedLink.links.length ) { | ||
log.info('Calling linked seeds'); | ||
return self.seedLink.process(); | ||
} | ||
return; | ||
}) | ||
.then(function() { | ||
return (Promise.promisify(self.deleteMigrationRecord.bind(self)))(migration); | ||
}) | ||
.then(self.driver.endMigration.bind(self.driver)); | ||
}) | ||
.nodeify(callback); | ||
}); | ||
return self.seedLink.process(); | ||
} | ||
}) | ||
.then(function () { | ||
return Promise.promisify( | ||
self.deleteMigrationRecord.bind(self) | ||
)(migration); | ||
}) | ||
.then(self.driver.endMigration.bind(self.driver)); | ||
}) | ||
.nodeify(callback); | ||
} | ||
); | ||
} | ||
@@ -253,0 +278,0 @@ }; |
@@ -1,5 +0,5 @@ | ||
var fs = require('fs'), | ||
log = require('db-migrate-shared').log; | ||
var fs = require('fs'); | ||
var log = require('db-migrate-shared').log; | ||
function Relation() { | ||
function Relation () { | ||
this.relations = {}; | ||
@@ -9,38 +9,30 @@ } | ||
Relation.prototype = { | ||
addRelation: function (table, column, relatedTable, relatedColumn) { | ||
this.relations[table] = this.relations[table] || {}; | ||
this.relations[table][column] = relatedColumn; | ||
}, | ||
addRelation: function(table, column, relatedTable, relatedColumn) { | ||
getRelation: function (table, column) { | ||
return this.relations[table][column]; | ||
}, | ||
this.relations[table] = this.relations[table] || {}; | ||
this.relations[table][column] = relatedColumn; | ||
fromJson: function (file) { | ||
// Relation = require(file); | ||
}, | ||
log.info('Read Relations from file ' + file); | ||
}, | ||
getRelation: function(table, column) { | ||
toJson: function (file) { | ||
fs.writeFile(file, JSON.stringify(this.relations), function (err) { | ||
if (err) { | ||
throw err; | ||
} | ||
return this.relations[table][column]; | ||
}, | ||
log.info('Wrote Relations to file ' + file); | ||
}); | ||
}, | ||
fromJson: function(file) { | ||
//Relation = require(file); | ||
log.info( 'Read Relations from file ' + file ); | ||
}, | ||
toJson: function(file) { | ||
fs.writeFile(file, JSON.stringify(this.relations), function(err) { | ||
if(err) { | ||
throw err; | ||
} | ||
log.info( 'Wrote Relations to file ' + file ); | ||
}); | ||
}, | ||
clearRelations: function() { | ||
this.relations = {}; | ||
} | ||
clearRelations: function () { | ||
this.relations = {}; | ||
} | ||
}; |
162
lib/seed.js
@@ -7,4 +7,3 @@ var fs = require('fs'); | ||
var Seed = Skeleton.extend({ | ||
init: function() { | ||
init: function () { | ||
if (arguments.length >= 3) { | ||
@@ -28,81 +27,65 @@ this.title = arguments[0]; | ||
up: function(db, static) { | ||
if(static) { | ||
up: function (db, isStatic) { | ||
if (isStatic) { | ||
var seed = require(this.path); | ||
var cb_executed = false; | ||
var cbExecuted = false; | ||
return new Promise(function(resolve, reject) { | ||
var r = function( err ) { | ||
if ( cb_executed === false ) { | ||
return new Promise( | ||
function (resolve, reject) { | ||
var r = function (err) { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
cb_executed = true; | ||
if( err ) { | ||
log.error('Error while truncating static seed.'); | ||
reject( err ); | ||
if (err) { | ||
log.error('Error while truncating static seed.'); | ||
reject(err); | ||
} else resolve(); | ||
} | ||
else | ||
resolve(); | ||
} | ||
}; | ||
}; | ||
Promise.resolve(seed.truncate.apply(this, [ db, r ])) | ||
.then(function( Promise ) { | ||
if( Promise !== undefined && cb_executed === false ) { | ||
Promise.resolve(seed.truncate.apply(this, [db, r])) | ||
.then(function (Promise) { | ||
if (Promise !== undefined && cbExecuted === false) { | ||
cbExecuted = true; | ||
resolve(); | ||
} | ||
}) | ||
.catch(function (err) { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
reject(err); | ||
} | ||
}); | ||
}.bind(this) | ||
).then(function () { | ||
var seedExecuted = false; | ||
cb_executed = true; | ||
resolve(); | ||
} | ||
}).catch(function(err) { | ||
return new Promise(function (resolve, reject) { | ||
var r = function (err) { | ||
if (seedExecuted === false) { | ||
seedExecuted = true; | ||
if ( cb_executed === false ) { | ||
cb_executed = true; | ||
reject( err ); | ||
if (err) { | ||
log.error('Error while seeding static seed.'); | ||
reject(err); | ||
} else resolve(); | ||
} | ||
}); | ||
}; | ||
}.bind(this)).then(function() { | ||
var seed_executed = false; | ||
return new Promise(function(resolve, reject) { | ||
var r = function( err ) { | ||
if ( seed_executed === false ) { | ||
seed_executed = true; | ||
if( err ) { | ||
log.error('Error while seeding static seed.'); | ||
reject( err ); | ||
} | ||
else | ||
resolve(); | ||
} | ||
}; | ||
Promise.resolve(seed.seed.apply( this, [ db, r ] )) | ||
.then(function( Promise ) { | ||
if( Promise !== undefined && seed_executed === false ) { | ||
seed_executed = true; | ||
Promise.resolve(seed.seed.apply(this, [db, r])) | ||
.then(function (Promise) { | ||
if (Promise !== undefined && seedExecuted === false) { | ||
seedExecuted = true; | ||
resolve(); | ||
} | ||
}).catch(function(err) { | ||
if ( seed_executed === false ) { | ||
seed_executed = true; | ||
reject( err ); | ||
}) | ||
.catch(function (err) { | ||
if (seedExecuted === false) { | ||
seedExecuted = true; | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
}.bind(this)); | ||
} | ||
else { | ||
}); | ||
}); | ||
} else { | ||
return this._up(db); | ||
@@ -112,4 +95,3 @@ } | ||
down: function(db) { | ||
down: function (db) { | ||
return this._down(db); | ||
@@ -119,12 +101,13 @@ } | ||
Seed.loadFromFilesystem = function(dir, internals, callback) { | ||
Seed.loadFromFilesystem = function (dir, internals, callback) { | ||
log.verbose('loading seeds from dir', dir); | ||
fs.readdir(dir, function(err, files) { | ||
if (err) { callback(err); return; } | ||
var coffeeWarn = true; | ||
files = files.filter(function(file) { | ||
fs.readdir(dir, function (err, files) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
files = files.filter(function (file) { | ||
return internals.parser.filesRegEx.test(file); | ||
}); | ||
var seeds = files.sort().map(function(file) { | ||
var seeds = files.sort().map(function (file) { | ||
return new Seed(path.join(dir, file), internals); | ||
@@ -136,14 +119,21 @@ }); | ||
Seed.loadFromDatabase = function(dir, driver, internals, callback) { | ||
Seed.loadFromDatabase = function (dir, driver, internals, callback) { | ||
log.verbose('loading seeds from database'); | ||
driver.allLoadedSeeds(function(err, dbResults) { | ||
if (err && !internals.dryRun) { callback(err); return; } | ||
else if (err && internals.dryRun) { | ||
driver.allLoadedSeeds(function (err, dbResults) { | ||
if (err && !internals.dryRun) { | ||
callback(err); | ||
return; | ||
} else if (err && internals.dryRun) { | ||
dbResults = []; | ||
} | ||
var seeds = dbResults.filter(function(result) { | ||
return result.name.substr(0,result.name.lastIndexOf('/')) === internals.matching; | ||
}).map(function(result) { | ||
return new Seed(path.join(dir, result.name), internals); | ||
}); | ||
var seeds = dbResults | ||
.filter(function (result) { | ||
return ( | ||
result.name.substr(0, result.name.lastIndexOf('/')) === | ||
internals.matching | ||
); | ||
}) | ||
.map(function (result) { | ||
return new Seed(path.join(dir, result.name), internals); | ||
}); | ||
@@ -150,0 +140,0 @@ callback(null, seeds); |
@@ -5,11 +5,12 @@ var Seed = require('./seed'); | ||
var Promise = require('bluebird'); | ||
var SeederInterface = require( './interface/seederInterface.js'); | ||
var SeederInterface = require('./interface/seederInterface.js'); | ||
var internals = {}; | ||
function MigrationLink(driver, internals) { | ||
function MigrationLink (driver, internals) { | ||
this.migrator = require('./migrator.js')( | ||
driver, internals.migrationsDir, null, internals | ||
driver, | ||
internals.migrationsDir, | ||
null, | ||
internals | ||
); | ||
@@ -20,10 +21,7 @@ this.links = []; | ||
MigrationLink.prototype = { | ||
link: function( partialName ) { | ||
this.links.push( partialName ); | ||
link: function (partialName) { | ||
this.links.push(partialName); | ||
}, | ||
migrate: function( partialName ) { | ||
migrate: function (partialName) { | ||
var reset = !internals.notransactions; | ||
@@ -33,19 +31,18 @@ | ||
return new Promise( function( resolve, reject ) { | ||
this.migrator.up( partialName, function( err ) { | ||
if( reset ) | ||
return new Promise(function (resolve, reject) { | ||
this.migrator.up(partialName, function (err) { | ||
if (reset) { | ||
internals.notransactions = false; | ||
} | ||
if ( err ) | ||
reject( err ); | ||
else | ||
resolve( err ); | ||
} ); | ||
} ); | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(err); | ||
} | ||
}); | ||
}); | ||
}, | ||
process: function() { | ||
process: function () { | ||
var reset = !internals.notransactions; | ||
@@ -55,43 +52,41 @@ | ||
return new Promise(function(resolve, reject) { | ||
return new Promise( | ||
function (resolve, reject) { | ||
var keys = Object.keys(this.links); | ||
var i = 0; | ||
var keys = Object.keys( this.links ), | ||
i = 0; | ||
var migrate = function(i, cb) { | ||
if(i < keys.length) { | ||
if ( reset ) | ||
internals.notransactions = false; | ||
resolve(); | ||
this.clear(); | ||
} | ||
this.migrator.up( { | ||
destination: this.links[ keys[ i ] ] | ||
}, function( err ) { | ||
if( err ) { | ||
if ( reset ) | ||
var migrate = function (i) { | ||
if (i < keys.length) { | ||
if (reset) { | ||
internals.notransactions = false; | ||
} | ||
reject( err ); | ||
resolve(); | ||
this.clear(); | ||
} | ||
else { | ||
cb(++i, migrate); | ||
} | ||
} ); | ||
}.bind(this); | ||
this.migrator.up( | ||
{ | ||
destination: this.links[keys[i]] | ||
}, | ||
function (err) { | ||
if (err) { | ||
if (reset) { | ||
internals.notransactions = false; | ||
} | ||
migrate(i, migrate); | ||
}.bind(this)); | ||
reject(err); | ||
} else { | ||
migrate(++i); | ||
} | ||
} | ||
); | ||
}.bind(this); | ||
migrate(i); | ||
}.bind(this) | ||
); | ||
}, | ||
clear: function() { | ||
clear: function () { | ||
this.links = []; | ||
@@ -103,3 +98,3 @@ } | ||
SeederInterface.extending = intern.interfaces.SeederInterface; | ||
this.driver = dbmUtil.reduceToInterface( driver, SeederInterface ); | ||
this.driver = dbmUtil.reduceToInterface(driver, SeederInterface); | ||
this._driver = driver; | ||
@@ -109,4 +104,3 @@ this.seedDir = seedsDir; | ||
if(intern.linked === false) { | ||
if (intern.linked === false) { | ||
intern.linked = true; | ||
@@ -121,4 +115,3 @@ this.migrationLink = new MigrationLink(driver, intern); | ||
Seeder.prototype = { | ||
createSeedsTable: function(callback) { | ||
createSeedsTable: function (callback) { | ||
this._driver.createSeedsTable(callback); | ||
@@ -128,10 +121,10 @@ }, | ||
seed: function (argv, callback) { | ||
if (this.isVC) | ||
if (this.isVC) { | ||
this.up(argv, callback); | ||
else | ||
} else { | ||
this._staticSeed(argv.destination, callback); | ||
} | ||
}, | ||
up: function(funcOrOpts, callback) { | ||
up: function (funcOrOpts, callback) { | ||
if (dbmUtil.isFunction(funcOrOpts)) { | ||
@@ -144,3 +137,3 @@ return funcOrOpts(this.driver, false, callback); | ||
down: function(funcOrOpts, callback) { | ||
down: function (funcOrOpts, callback) { | ||
if (dbmUtil.isFunction(funcOrOpts)) { | ||
@@ -173,9 +166,9 @@ return funcOrOpts(this.driver, callback); | ||
_staticSeed: function (partialName, callback) { | ||
var self = this; | ||
return Seed.loadFromFilesystem(self.seedDir, self.internals, function(err, allSeeds) { | ||
return Seed.loadFromFilesystem(self.seedDir, self.internals, function ( | ||
err, | ||
allSeeds | ||
) { | ||
if (err) { | ||
callback(err); | ||
@@ -193,29 +186,30 @@ return; | ||
return Promise.resolve(toRun).each(function(seeder) { | ||
log.verbose('preparing to run up seeder:', seeder.name); | ||
return Promise.resolve(toRun) | ||
.each(function (seeder) { | ||
log.verbose('preparing to run up seeder:', seeder.name); | ||
var setup = seeder.setup(); | ||
if(typeof(setup) === 'function') | ||
setup(self.internals.seederOptions); | ||
var setup = seeder.setup(); | ||
if (typeof setup === 'function') { | ||
setup(self.internals.seederOptions); | ||
} | ||
return self._driver.startMigration() | ||
.catch(callback) | ||
.then(function() { | ||
return seeder.up(self.driver, true); | ||
}); | ||
}) | ||
.then(self._driver.endMigration.bind(self.driver)) | ||
.then(function() { | ||
callback(); | ||
}) | ||
.catch(function(e) { | ||
throw e; | ||
}); | ||
return self._driver | ||
.startMigration() | ||
.catch(callback) | ||
.then(function () { | ||
return seeder.up(self.driver, true); | ||
}); | ||
}) | ||
.then(self._driver.endMigration.bind(self.driver)) | ||
.then(function () { | ||
callback(); | ||
}) | ||
.catch(function (e) { | ||
throw e; | ||
}); | ||
}); | ||
}, | ||
writeSeedRecord: function(seed, callback) { | ||
function onComplete(err) { | ||
writeSeedRecord: function (seed, callback) { | ||
function onComplete (err) { | ||
if (err) { | ||
@@ -228,7 +222,10 @@ log.error(seed.name, err); | ||
} | ||
this._driver.addSeedRecord(this.internals.matching + '/' + seed.name, onComplete); | ||
this._driver.addSeedRecord( | ||
this.internals.matching + '/' + seed.name, | ||
onComplete | ||
); | ||
}, | ||
deleteSeedRecord: function(seed, callback) { | ||
function onComplete(err) { | ||
deleteSeedRecord: function (seed, callback) { | ||
function onComplete (err) { | ||
if (err) { | ||
@@ -241,78 +238,96 @@ log.error(seed.name, err); | ||
} | ||
this._driver.deleteSeed(this.internals.matching + '/' + seed.name, function(err) { | ||
this._driver.deleteSeed( | ||
this.internals.matching + '/' + seed.name, | ||
function (err) { | ||
if (!this.internals.matching) { | ||
this._driver.deleteSeed(seed.name, onComplete); | ||
} else { | ||
onComplete.apply(err); | ||
} | ||
}.bind(this) | ||
); | ||
}, | ||
if(!this.internals.matching) { | ||
upToBy: function (partialName, count, callback) { | ||
var self = this; | ||
this._driver.deleteSeed(seed.name, onComplete); | ||
return Seed.loadFromFilesystem(self.seedDir, self.internals, function ( | ||
err, | ||
allMigrations | ||
) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
else { | ||
onComplete.apply(err); | ||
} | ||
}.bind(this)); | ||
}, | ||
return Seed.loadFromDatabase( | ||
self.seedDir, | ||
self._driver, | ||
self.internals, | ||
function (err, completedSeeds) { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
var toRun = dbmUtil.filterUp( | ||
allMigrations, | ||
completedSeeds, | ||
partialName, | ||
count | ||
); | ||
upToBy: function(partialName, count, callback) { | ||
if (toRun.length === 0) { | ||
log.info('No seeds to run'); | ||
callback(null); | ||
return; | ||
} | ||
var self = this; | ||
return Promise.resolve(toRun) | ||
.each(function (seeder) { | ||
log.verbose('preparing to run up seeder:', seeder.name); | ||
return Seed.loadFromFilesystem(self.seedDir, self.internals, function(err, allMigrations) { | ||
return self._driver | ||
.startMigration() | ||
.then(function () { | ||
var setup = seeder.setup(); | ||
if (typeof setup === 'function') { | ||
setup(self.internals.seederOptions, self.migrationLink); | ||
} | ||
if (err) { callback(err); return; } | ||
return self.up(seeder.up.bind(seeder)); | ||
}) | ||
.then(function () { | ||
if (self.seedLink && self.seedLink.links.length) { | ||
log.info('Calling linked migrations'); | ||
return Seed.loadFromDatabase(self.seedDir, self._driver, self.internals, function(err, completedSeeds) { | ||
if (err) { callback(err); return; } | ||
var toRun = dbmUtil.filterUp(allMigrations, completedSeeds, partialName, count); | ||
if (toRun.length === 0) { | ||
log.info('No seeds to run'); | ||
callback(null); | ||
return; | ||
return self.seedLink.process(self.migrationLink); | ||
} | ||
}) | ||
.then(function () { | ||
return Promise.promisify( | ||
self.writeSeedRecord.bind(self) | ||
)(seeder); | ||
}) | ||
.then(self._driver.endMigration.bind(self.driver)) | ||
.catch(function (e) { | ||
throw e; | ||
}); | ||
}) | ||
.then(function () { | ||
callback(); | ||
}); | ||
} | ||
return Promise.resolve(toRun).each(function(seeder) { | ||
log.verbose('preparing to run up seeder:', seeder.name); | ||
return self._driver.startMigration() | ||
.then(function() { | ||
var setup = seeder.setup(); | ||
if(typeof(setup) === 'function') | ||
setup(self.internals.seederOptions, self.migrationLink); | ||
return self.up(seeder.up.bind(seeder)); | ||
}) | ||
.then(function() { | ||
if( self.seedLink && self.seedLink.links.length ) { | ||
log.info('Calling linked migrations'); | ||
return self.seedLink.process( self.migrationLink ); | ||
} | ||
return; | ||
}) | ||
.then(function() { | ||
return (Promise.promisify(self.writeSeedRecord.bind(self)))(seeder); | ||
}) | ||
.then(self._driver.endMigration.bind(self.driver)) | ||
.catch(function(e) { | ||
throw e; | ||
}); | ||
}) | ||
.then(function() { | ||
callback(); | ||
}); | ||
}); | ||
); | ||
}); | ||
}, | ||
downToBy: function(count, callback) { | ||
downToBy: function (count, callback) { | ||
var self = this; | ||
Seed.loadFromDatabase(self.seedDir, self._driver, self.internals, function(err, completedSeeds) { | ||
if (err) { return callback(err); } | ||
Seed.loadFromDatabase(self.seedDir, self._driver, self.internals, function ( | ||
err, | ||
completedSeeds | ||
) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
@@ -327,39 +342,37 @@ var toRun = dbmUtil.filterDown(completedSeeds, count); | ||
return Promise.resolve(toRun).each(function(seeder) { | ||
return Promise.resolve(toRun) | ||
.each(function (seeder) { | ||
log.verbose('preparing to run down seeder:', seeder.name); | ||
log.verbose('preparing to run down seeder:', seeder.name); | ||
return self._driver | ||
.startMigration() | ||
.then(function () { | ||
var setup = seeder.setup(); | ||
return self._driver.startMigration() | ||
.then(function() { | ||
if (typeof setup === 'function') { | ||
setup(self.internals.seederOptions, self.migrationLink); | ||
} | ||
var setup = seeder.setup(); | ||
return self.down(seeder.down.bind(seeder)); | ||
}) | ||
.then(function () { | ||
if (self.seedLink && self.seedLink.links.length) { | ||
log.info('Calling linked migrations'); | ||
if(typeof(setup) === 'function') | ||
setup(self.internals.seederOptions, self.migrationLink); | ||
return self.down(seeder.down.bind(seeder)); | ||
}) | ||
.then(function() { | ||
if( self.seedLink && self.seedLink.links.length ) { | ||
log.info('Calling linked migrations'); | ||
return self.seedLink.process(); | ||
} | ||
return; | ||
}) | ||
.then(function() { | ||
return (Promise.promisify(self.deleteSeedRecord.bind(self)))(seeder); | ||
}) | ||
.then(self._driver.endMigration.bind(self.driver)) | ||
.catch(function(e) { | ||
throw e; | ||
}); | ||
}) | ||
.then(function() { | ||
callback(); | ||
}); | ||
return self.seedLink.process(); | ||
} | ||
}) | ||
.then(function () { | ||
return Promise.promisify( | ||
self.deleteSeedRecord.bind(self) | ||
)(seeder); | ||
}) | ||
.then(self._driver.endMigration.bind(self.driver)) | ||
.catch(function (e) { | ||
throw e; | ||
}); | ||
}) | ||
.then(function () { | ||
callback(); | ||
}); | ||
}); | ||
@@ -366,0 +379,0 @@ } |
@@ -7,17 +7,21 @@ var path = require('path'); | ||
function isPromise( probe ) { | ||
return probe instanceof Promise || ( probe && probe.then && | ||
probe.constructor && probe.constructor.name === 'Promise' ); | ||
function isPromise (probe) { | ||
return ( | ||
probe instanceof Promise || | ||
(probe && | ||
probe.then && | ||
probe.constructor && | ||
probe.constructor.name === 'Promise') | ||
); | ||
} | ||
function formatPath(dir, name) { | ||
function formatPath (dir, name) { | ||
return path.join(dir, name); | ||
} | ||
function formatName(title, date) { | ||
function formatName (title, date) { | ||
return formatDate(date) + '-' + formatTitle(title); | ||
} | ||
function formatDate(date) { | ||
function formatDate (date) { | ||
return [ | ||
@@ -33,9 +37,9 @@ date.getUTCFullYear(), | ||
function formatTitle(title) { | ||
function formatTitle (title) { | ||
return inflection.dasherize(title); | ||
} | ||
function parseDate(name) { | ||
function parseDate (name) { | ||
var date = new Date(); | ||
var match = name.match(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})-[^\.]+/); | ||
var match = name.match(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})-[^.]+/); | ||
date.setUTCFullYear(match[1]); | ||
@@ -50,4 +54,4 @@ date.setUTCDate(match[3]); | ||
function parseTitle(name) { | ||
var match = name.match(/\d{14}-([^\.]+)/); | ||
function parseTitle (name) { | ||
var match = name.match(/\d{14}-([^.]+)/); | ||
var dashed = match[1]; | ||
@@ -58,108 +62,105 @@ return inflection.humanize(dashed, true); | ||
var Skeleton = Class.extend({ | ||
init: function(intern) { | ||
init: function (intern) { | ||
this.internals = intern; | ||
}, | ||
_up: function() { | ||
_up: function () { | ||
var params = arguments; | ||
var cb_executed = false; | ||
var cbExecuted = false; | ||
return new Promise(function(resolve, reject) { | ||
var migration, | ||
r = function( err ) { | ||
if ( cb_executed === false ) { | ||
return new Promise( | ||
function (resolve, reject) { | ||
var migration; | ||
var r = function (err) { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
cb_executed = true; | ||
if( err ) | ||
reject( err ); | ||
else | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
} | ||
}; | ||
params[ params.length++ ] = r; | ||
params[params.length++] = r; | ||
migration = require(this.path).up.apply(this, params); | ||
migration = require(this.path).up.apply(this, params); | ||
if( migration === null ) migration = Promise.resolve(); | ||
if( isPromise( migration ) ) { | ||
migration | ||
.then(function() { | ||
if( cb_executed === false ) { | ||
cb_executed = true; | ||
resolve(); | ||
} | ||
}).catch(function(err) { | ||
if ( cb_executed === false ) { | ||
cb_executed = true; | ||
reject( err ); | ||
} | ||
}); | ||
} | ||
}.bind(this)); | ||
if (migration === null) migration = Promise.resolve(); | ||
if (isPromise(migration)) { | ||
migration | ||
.then(function () { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
resolve(); | ||
} | ||
}) | ||
.catch(function (err) { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
reject(err); | ||
} | ||
}); | ||
} | ||
}.bind(this) | ||
); | ||
}, | ||
_down: function() { | ||
_down: function () { | ||
var params = arguments; | ||
var cb_executed = false; | ||
var cbExecuted = false; | ||
return new Promise(function(resolve, reject) { | ||
var migration, | ||
r = function( err ) { | ||
if ( cb_executed === false ) { | ||
return new Promise( | ||
function (resolve, reject) { | ||
var migration; | ||
var r = function (err) { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
cb_executed = true; | ||
if( err ) | ||
reject( err ); | ||
else | ||
resolve(); | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
}; | ||
params[ params.length++ ] = r; | ||
migration = require(this.path).down.apply(this, params); | ||
if( migration === null ) migration = Promise.resolve(); | ||
if( isPromise( migration ) ) { | ||
migration | ||
.then(function() { | ||
if( cb_executed === false ) { | ||
cb_executed = true; | ||
resolve(); | ||
} | ||
}).catch(function(err) { | ||
}; | ||
if ( cb_executed === false ) { | ||
params[params.length++] = r; | ||
migration = require(this.path).down.apply(this, params); | ||
cb_executed = true; | ||
reject( err ); | ||
} | ||
}); | ||
} | ||
}.bind(this)); | ||
if (migration === null) migration = Promise.resolve(); | ||
if (isPromise(migration)) { | ||
migration | ||
.then(function () { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
resolve(); | ||
} | ||
}) | ||
.catch(function (err) { | ||
if (cbExecuted === false) { | ||
cbExecuted = true; | ||
reject(err); | ||
} | ||
}); | ||
} | ||
}.bind(this) | ||
); | ||
}, | ||
up: function(db) { | ||
up: function (db) { | ||
return this._up(db); | ||
}, | ||
down: function(db) { | ||
down: function (db) { | ||
return this._down(db); | ||
}, | ||
setup: function() { | ||
setup: function () { | ||
return require(this.path).setup; | ||
}, | ||
parseName: function(path) { | ||
parseName: function (path) { | ||
var match = path.match(/(\d{14}-[^.]+)(?:\.*?)?/); | ||
@@ -174,5 +175,4 @@ return match[1]; | ||
formatName: formatName | ||
}); | ||
module.exports = Skeleton; |
@@ -10,8 +10,7 @@ | ||
transition: function() { | ||
transition: function () { | ||
}, | ||
message: function() { | ||
message: function () { | ||
console.log('Congratulations!\n\n' + | ||
@@ -18,0 +17,0 @@ 'You just migrated from protocol 0 to 1!\n' + |
var prompt = require('prompt'); | ||
function ask(schema, callback) { | ||
function ask (schema, callback) { | ||
console.log('Starting transition helper...\n'); | ||
@@ -9,15 +8,11 @@ | ||
prompt.get(schema, function(err, result) { | ||
if(err) { | ||
prompt.get(schema, function (err, result) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
if(result.safe === 'n') { | ||
if (result.safe === 'n') { | ||
console.log('Aborted transition helper!'); | ||
callback(new Error('Aborted transition.')); | ||
} | ||
else { | ||
} else { | ||
callback(null, result); | ||
@@ -24,0 +19,0 @@ } |
@@ -7,4 +7,3 @@ var Migration = require('../migration.js'); | ||
module.exports = function(internals) { | ||
module.exports = function (internals) { | ||
ask( | ||
@@ -14,11 +13,11 @@ { | ||
safe: { | ||
description: 'This process is going to alter your migrations. We ' + | ||
'highly recommend you to backup your migrations or even better safe ' + | ||
'the current state with git versioning.\nPlease make sure you don\'t ' + | ||
'blow up yourself.\n\nDo you want to continue? [y/n]', | ||
description: | ||
'This process is going to alter your migrations. We ' + | ||
'highly recommend you to backup your migrations or even better safe ' + | ||
"the current state with git versioning.\nPlease make sure you don't " + | ||
'blow up yourself.\n\nDo you want to continue? [y/n]', | ||
message: 'Invalid answer! Do you want to continue? [y/n]', | ||
type: 'string', | ||
default: 'n', | ||
conform: function(value) { | ||
conform: function (value) { | ||
return value === 'y' || value === 'n'; | ||
@@ -28,49 +27,55 @@ } | ||
} | ||
}, function(err) { | ||
}, | ||
function (err) { | ||
if (err) { | ||
return; | ||
} | ||
if(err) | ||
return; | ||
internals.parser = { | ||
filesRegEx: /\.js$/ | ||
}; | ||
internals.parser = { | ||
filesRegEx: /\.js$/ | ||
}; | ||
Migration.loadFromFilesystem('migrations/', internals, function ( | ||
err, | ||
migrations | ||
) { | ||
var messages = []; | ||
if (err) { | ||
return; | ||
} | ||
Migration.loadFromFilesystem('migrations/', internals, | ||
function(err, migrations) { | ||
migrations.forEach(function (migration) { | ||
var required = tryRequire(migration, internals); | ||
var version = | ||
required._meta && required._meta.version | ||
? required._meta.version | ||
: 0; | ||
var messages = []; | ||
if (version !== internals.migrationProtocol) { | ||
var i; | ||
migrations.forEach(function(migration) { | ||
for (i = 0; i < internals.migrationProtocol; ++i) { | ||
var transition = require('./' + (i + 1)); | ||
transition.transition(); | ||
messages[i + 1] = transition.message; | ||
var required = tryRequire(migration, internals); | ||
var version = (required._meta && required._meta.version) ? | ||
required._meta.version | ||
: 0; | ||
if(version !== internals.migrationProtocol) { | ||
var i; | ||
for(i = 0; i < internals.migrationProtocol; ++i) { | ||
var transition = require('./' + (i + 1)); | ||
transition.transition(); | ||
messages[i + 1] = transition.message; | ||
updateVersion(required, migration, internals, i + 1); | ||
log.info('Transitioned ' + migration.name + '.'); | ||
updateVersion(required, migration, internals, i + 1); | ||
log.info('Transitioned ' + migration.name + '.'); | ||
} | ||
} else { | ||
log.verbose( | ||
migration.name, | ||
'was already transitioned to version ' + | ||
internals.migrationProtocol + | ||
'.' | ||
); | ||
} | ||
} | ||
else { | ||
}); | ||
log.verbose(migration.name, 'was already transitioned to version ' + | ||
internals.migrationProtocol + '.'); | ||
} | ||
messages.forEach(function (message) { | ||
message(); | ||
}); | ||
}); | ||
messages.forEach(function(message) { | ||
message(); | ||
}); | ||
}); | ||
}); | ||
} | ||
); | ||
}; |
var log = require('db-migrate-shared').log; | ||
var path = require('path'); | ||
var fs = require('fs'); | ||
@@ -10,19 +11,18 @@ var cp = require('child_process'); | ||
'async is not defined': globalHandler, | ||
'Cannot find module \'db-migrate\'': missingDBMigrate, | ||
'Cannot find module \'async\'': installAsync | ||
"Cannot find module 'db-migrate'": missingDBMigrate, | ||
"Cannot find module 'async'": installAsync | ||
}; | ||
function missingDBMigrate(migration, retry) { | ||
function missingDBMigrate (migration, retry) { | ||
return globalHandler(migration.path, retry); | ||
} | ||
function installAsync(migration, retry) { | ||
function installAsync (migration, retry) { | ||
var cmd = ['install', '--save', 'async']; | ||
var cmd = [ 'install', '--save', 'async' ]; | ||
if(installed) | ||
if (installed) { | ||
retry(); | ||
else | ||
} else { | ||
installed = true; | ||
} | ||
@@ -38,3 +38,3 @@ log.info('Installing async...'); | ||
function globalHandler(migration, retry) { | ||
function globalHandler (migration, retry) { | ||
var data = fs.readFileSync(migration, 'utf8'); | ||
@@ -51,18 +51,16 @@ data = data.replace( | ||
if(data.indexOf('async = async || require') !== -1) { | ||
if (data.indexOf('async = async || require') !== -1) { | ||
handled = true; | ||
data = data.replace( | ||
/^async = async \|\| require\((?!\s)?'async'(?!\s)?\)/m, | ||
'var async = require( \'async\' )' | ||
"var async = require( 'async' )" | ||
); | ||
} | ||
data = data.replace( | ||
/^var type = dbm.dataType/m, | ||
'var type' | ||
); | ||
data = data.replace(/^var type = dbm.dataType/m, 'var type'); | ||
if(data.indexOf('exports.setup = ') === -1) { | ||
var snippet = fs.readFileSync(__dirname + '/snippets/setup.sjs', 'utf8'); | ||
if (data.indexOf('exports.setup = ') === -1) { | ||
var snippet = fs.readFileSync( | ||
path.join(__dirname, '/snippets/setup.sjs'), | ||
'utf8' | ||
); | ||
data = data.replace(/exports.up/, snippet + '\nexports.up'); | ||
@@ -76,20 +74,12 @@ } | ||
function tryRequire(migration) { | ||
function tryRequire (migration) { | ||
try { | ||
if(handled && !installed) { | ||
return installAsync( | ||
migration, | ||
tryRequire.bind(this, migration) | ||
); | ||
if (handled && !installed) { | ||
return installAsync(migration, tryRequire.bind(this, migration)); | ||
} | ||
return require(migration.internals.cwd + '/' + migration.path); | ||
} | ||
catch(ex) { | ||
if(ex instanceof ReferenceError) { | ||
if(removedGlobals[ex.message]) { | ||
} catch (ex) { | ||
if (ex instanceof ReferenceError) { | ||
if (removedGlobals[ex.message]) { | ||
log.info(ex.message, 'Initiating removal of old globals...'); | ||
@@ -100,5 +90,3 @@ return removedGlobals[ex.message]( | ||
); | ||
} | ||
else { | ||
} else { | ||
log.error( | ||
@@ -110,8 +98,8 @@ ex.stack, | ||
throw new Error('Unhandled ReferenceError while transition. Please ' + | ||
'fix the issues and rerun the transitioner again.'); | ||
throw new Error( | ||
'Unhandled ReferenceError while transition. Please ' + | ||
'fix the issues and rerun the transitioner again.' | ||
); | ||
} | ||
} | ||
else if(removedGlobals[ex.message]) { | ||
} else if (removedGlobals[ex.message]) { | ||
return removedGlobals[ex.message]( | ||
@@ -121,8 +109,8 @@ migration, | ||
); | ||
} | ||
else { | ||
} else { | ||
log.error(ex.stack, migration); | ||
throw new Error('Unhandled Error while transition. Please ' + | ||
'fix the issues and rerun the transitioner again.'); | ||
throw new Error( | ||
'Unhandled Error while transition. Please ' + | ||
'fix the issues and rerun the transitioner again.' | ||
); | ||
} | ||
@@ -129,0 +117,0 @@ } |
var balanced = require('balanced-match'); | ||
var fs = require('fs'); | ||
function updateVersion(required, migration, internals, version) { | ||
function updateVersion (required, migration, internals, version) { | ||
var data = fs.readFileSync(migration.path, 'utf8'); | ||
@@ -11,5 +10,7 @@ var searchString = 'exports.down'; | ||
var plus = 1; | ||
var sub; | ||
if(required._meta) | ||
if (required._meta) { | ||
searchString = 'exports._meta'; | ||
} | ||
@@ -20,21 +21,24 @@ metaIndex = data.indexOf(searchString); | ||
if(sub[balance.end + 1] === ';') | ||
if (sub[balance.end + 1] === ';') { | ||
++plus; | ||
} | ||
sub = sub.substring(0, balanced.end); | ||
if(required._meta) { | ||
if (required._meta) { | ||
required._meta.version = version; | ||
data = data.substring(0, metaIndex) + sub.replace( | ||
sub.substring(balance.start, balance.end + 1), | ||
JSON.stringify(required._meta, null, 2) | ||
) + data.substring(metaIndex + balance.end + plus); | ||
} | ||
else { | ||
data = data.substring(0, metaIndex + balance.end + plus) + | ||
data = | ||
data.substring(0, metaIndex) + | ||
sub.replace( | ||
sub.substring(balance.start, balance.end + 1), | ||
JSON.stringify(required._meta, null, 2) | ||
) + | ||
data.substring(metaIndex + balance.end + plus); | ||
} else { | ||
data = | ||
data.substring(0, metaIndex + balance.end + plus) + | ||
'\n\nexports._meta = ' + | ||
JSON.stringify({ version: version }, null, 2) + ';' + | ||
JSON.stringify({ version: version }, null, 2) + | ||
';' + | ||
data.substring(metaIndex + balance.end + plus); | ||
@@ -41,0 +45,0 @@ } |
@@ -34,3 +34,3 @@ { | ||
], | ||
"version": "0.10.0-beta.24", | ||
"version": "0.10.0", | ||
"engines": { | ||
@@ -71,2 +71,8 @@ "node": ">=0.6.0" | ||
"db-migrate-sqlite3": "^0.1.9", | ||
"eslint": "^4.10.0", | ||
"eslint-config-standard": "^10.2.1", | ||
"eslint-plugin-import": "^2.8.0", | ||
"eslint-plugin-node": "^5.2.1", | ||
"eslint-plugin-promise": "^3.6.0", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"lab": "^11.1.0", | ||
@@ -73,0 +79,0 @@ "proxyquire": "^1.4.0", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
121455
52
3399
15
40