diff --git a/api.js b/api.js index 455d5bad..da18a4f8 100644 --- a/api.js +++ b/api.js @@ -15,8 +15,8 @@ var dotenv = require('dotenv'); //global declaration for detection like it's done in umigrate //deprecated -dbm = require( './' ); //deprecated -async = require( 'async' ); //deprecated +dbm = require('./'); //deprecated +async = require('async'); //deprecated var internals = {}; @@ -28,44 +28,48 @@ function dbmigrate(isModule, options, callback) { }; internals = this.internals; - if(typeof(callback) === 'function') + if (typeof(callback) === 'function') this.internals.onComplete = callback; - else if(typeof(options) === 'function') + else if (typeof(options) === 'function') this.internals.onComplete = options; this.dataType = dbm.dataType; this.version = dbm.version; - dotenv.load({ silent: true }); + dotenv.load({ + silent: true + }); registerEvents(); - if(typeof(options) === 'object') { + if (typeof(options) === 'object') { - if(typeof(options.config) === 'string') + if (typeof(options.config) === 'string') internals.configFile = options.string; - if(typeof(options.cwd) === 'string') + if (typeof(options.cwd) === 'string') internals.cwd = options.cwd; else internals.cwd = process.cwd(); - } - else + } else internals.cwd = process.cwd(); - if(typeof(isModule) === 'function') - { + if (typeof(isModule) === 'function') { this.internals.onComplete = isModule; setDefaultArgv(this.internals); - } - else + } else setDefaultArgv(this.internals, isModule); loadConfig(); index.exportInternals(internals); internals.dbm = dbm; global.dbm = dbm; //deprecated - internals.migrationOptions = { dbmigrate: internals.dbm }; - internals.seederOptions = { dbmigrate: internals.dbm }; + internals.migrationOptions = { + dbmigrate: internals.dbm, + ignoreOnInit: internals['argv']['ignore-on-init'] + }; + internals.seederOptions = { + dbmigrate: internals.dbm + }; } function registerEvents() { @@ -84,16 +88,16 @@ function registerEvents() { dbmigrate.prototype = { /** - * Add a global defined variable to db-migrate, to enable access from - * local migrations without configuring pathes. - * - * @return boolean - */ + * Add a global defined variable to db-migrate, to enable access from + * local migrations without configuring pathes. + * + * @return boolean + */ addGlobal: function(library) { try { require(library); - } catch(e) { + } catch (e) { return false; } @@ -103,21 +107,21 @@ dbmigrate.prototype = { _internals: internals, /** - * Add a configuration option to dbmigrate. - * - * @return boolean - */ + * Add a configuration option to dbmigrate. + * + * @return boolean + */ addConfiguration: function(description, args, type) { var name = args.shift(); this.internals.argv.describe(name, description); - for(var i = 0; i < args.length; ++i) { + for (var i = 0; i < args.length; ++i) { this.internals.argv.alias(args[i], name); } - switch(type) { + switch (type) { case 'string': this.internals.argv.string(name); @@ -136,127 +140,123 @@ dbmigrate.prototype = { /** - * Resets and sets argv to a specified new argv. - */ + * Resets and sets argv to a specified new argv. + */ resetConfiguration: function(argv) { this.internals.argv = argv; }, /** - * Executes up a given number of migrations or a specific one. - * - * Defaults to up all migrations if no count is given. - */ + * Executes up a given number of migrations or a specific one. + * + * Defaults to up all migrations if no count is given. + */ up: function(specification, scope, callback) { - if(arguments.length > 0) - { - if(typeof(specification) === 'string') { + if (arguments.length > 0) { + if (typeof(specification) === 'string') { this.internals.argv.destination = specification; - } - else if(typeof(specification) === 'number') { + } else if (typeof(specification) === 'number') { this.internals.argv.count = specification; } - if(scope) { + if (scope) { this.internals.migrationMode = scope; } } - executeUp( this.internals, callback ); + executeUp(this.internals, callback); }, /** - * Executes up a given number of migrations or a specific one. - * - * Defaults to up all migrations if no count is given. - */ + * Executes up a given number of migrations or a specific one. + * + * Defaults to up all migrations if no count is given. + */ down: function(specification, scope, callback) { - if(arguments.length > 0) - { - if(typeof(arguments[0]) === 'number') { + if (arguments.length > 0) { + if (typeof(arguments[0]) === 'number') { this.internals.argv.count = arguments[0]; } - if(scope) { + if (scope) { this.internals.migrationMode = scope; } } - executeDown( this.internals, callback ); + executeDown(this.internals, callback); }, /** - * Executes down for all currently migrated migrations. - */ + * Executes down for all currently migrated migrations. + */ reset: function(scope, callback) { - if(scope) { + if (scope) { this.internals.migrationMode = scope; } this.internals.argv.count = Number.MAX_VALUE; - executeDown( this.internals, callback ); + executeDown(this.internals, callback); }, /** - * Silence the log output completely. - */ + * Silence the log output completely. + */ silence: function(isSilent) { return log.silence(isSilent); }, /** - * Creates a correctly formatted migration - */ + * Creates a correctly formatted migration + */ create: function(migrationName, scope, callback) { - if( typeof( scope ) === 'function' ) { + if (typeof(scope) === 'function') { callback = scope; - } - else if(scope) { + } else if (scope) { this.internals.migrationMode = scope; } this.internals.argv._.push(migrationName); - executeCreateMigration( this.internals, callback ); + executeCreateMigration(this.internals, callback); }, /** - * Creates a database of the given dbname. - */ + * Creates a database of the given dbname. + */ createDatabase: function(dbname, callback) { this.internals.argv._.push(dbname); this.internals.mode = 'create'; - executeDB( this.internals, callback ); + executeDB(this.internals, callback); }, /** - * Drops a database of the given dbname. - */ + * Drops a database of the given dbname. + */ dropDatabase: function(dbname, callback) { this.internals.argv._.push(dbname); this.internals.mode = 'drop'; - executeDB( this.internals, callback ); + executeDB(this.internals, callback); }, /** - * Sets a config variable to the given value. - * - * @return value - */ + * Sets a config variable to the given value. + * + * @return value + */ setConfigParam: function(param, value) { return (this.internals.argv[param] = value); @@ -264,54 +264,52 @@ dbmigrate.prototype = { /** - * Sets the callback to the default onComplete - */ + * Sets the callback to the default onComplete + */ setDefaultCallback: function() { this.internals.onComplete = onComplete; }, /** - * Let's the user customize the callback, which gets called after all - * migrations have been done. - */ + * Let's the user customize the callback, which gets called after all + * migrations have been done. + */ setCustomCallback: function(callback) { this.internals.onComplete = callback; }, /** - * Seeds either the static or version controlled seeders, controlled by - * the passed mode. - */ + * Seeds either the static or version controlled seeders, controlled by + * the passed mode. + */ seed: function(mode, scope, callback) { - if(scope) { + if (scope) { this.internals.migrationMode = scope; } this.internals.mode = mode || 'vc'; - executeSeed( this.internals, callback ); + executeSeed(this.internals, callback); }, /** - * Execute the down function of currently executed seeds. - */ - undoSeed: function( specification, scope, callback ) { + * Execute the down function of currently executed seeds. + */ + undoSeed: function(specification, scope, callback) { - if(arguments.length > 0) - { - if(typeof(specification) === 'number') { + if (arguments.length > 0) { + if (typeof(specification) === 'number') { this.internals.argv.count = specification; - if(scope) { + if (scope) { this.internals.migrationMode = scope; } - } - else if( typeof(specification) === 'string' ) { + } else if (typeof(specification) === 'string') { this.internals.migrationMode = scope; } @@ -319,11 +317,11 @@ dbmigrate.prototype = { }, /** - * Executes the default routine. - */ + * Executes the default routine. + */ run: function() { - run( this.internals ); + run(this.internals); } @@ -332,83 +330,96 @@ dbmigrate.prototype = { function setDefaultArgv(internals, isModule) { internals.argv = optimist - .default({ - verbose: false, - table: 'migrations', - 'seeds-table': 'seeds', - 'force-exit': false, - 'sql-file': false, - 'non-transactional': false, - config: internals.configFile || internals.cwd + '/database.json', - 'migrations-dir': internals.cwd + '/migrations', - 'vcseeder-dir': internals.cwd + '/VCSeeder', - 'staticseeder-dir': internals.cwd + '/Seeder', - 'ignore-completed-migrations': false}) - .usage('Usage: db-migrate [up|down|reset|create|db|seed] [[dbname/]migrationName|all] [options]') - - .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.') - .alias('m', 'migrations-dir') - .string('m') - - .describe('count', 'Max number of migrations to run.') - .alias('c', 'count') - .string('c') - - .describe('dry-run', 'Prints the SQL but doesn\'t run it.') - .boolean('dry-run') - - .describe('force-exit', 'Forcibly exit the migration process on completion.') - .boolean('force-exit') - - .describe('verbose', 'Verbose mode.') - .alias('v', 'verbose') - .boolean('v') - - .alias('h', 'help') - .alias('h', '?') - .boolean('h') - - .describe('version', 'Print version info.') - .alias('i', 'version') - .boolean('version') - - .describe('config', 'Location of the database.json file.') - .string('config') - - .describe('sql-file', 'Automatically create two sql files for up and down statements in /sqls and generate the javascript code that loads them.') - .boolean('sql-file') - - .describe('coffee-file', 'Create a coffeescript migration file') - .boolean('coffee-file') - - .describe('migration-table', 'Set the name of the migration table, which stores the migration history.') - .alias('table', 'migration-table') - .alias('t', 'table') - .string('t') - - .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.') - .string('vcseeder-dir') - - .describe('staticseeder-dir', 'Set the path to the Seeder directory.') - .string('staticseeder-dir') - - .describe('non-transactional', 'Explicitly disable transactions') - .boolean('non-transactional') - - .describe('ignore-completed-migrations', 'Start at the first migration') - .boolean('ignore-completed-migrations') - - .describe('log-level', 'Set the log-level, for example sql|warn') - .string('log-level') - - .argv; + .default({ + verbose: false, + table: 'migrations', + 'seeds-table': 'seeds', + 'force-exit': false, + 'sql-file': false, + 'non-transactional': false, + config: internals.configFile || internals.cwd + '/database.json', + 'migrations-dir': internals.cwd + '/migrations', + 'vcseeder-dir': internals.cwd + '/VCSeeder', + 'staticseeder-dir': internals.cwd + '/Seeder', + 'ignore-completed-migrations': false + }) + .usage( + 'Usage: db-migrate [up|down|reset|create|db|seed] [[dbname/]migrationName|all] [options]' + ) + + .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.') + .alias('m', 'migrations-dir') + .string('m') + + .describe('count', 'Max number of migrations to run.') + .alias('c', 'count') + .string('c') + + .describe('dry-run', 'Prints the SQL but doesn\'t run it.') + .boolean('dry-run') + + .describe('force-exit', 'Forcibly exit the migration process on completion.') + .boolean('force-exit') + + .describe('verbose', 'Verbose mode.') + .alias('v', 'verbose') + .boolean('v') + + .alias('h', 'help') + .alias('h', '?') + .boolean('h') + + .describe('version', 'Print version info.') + .alias('i', 'version') + .boolean('version') + + .describe('config', 'Location of the database.json file.') + .string('config') + + .describe('sql-file', + 'Automatically create two sql files for up and down statements in /sqls and generate the javascript code that loads them.' + ) + .boolean('sql-file') + + .describe('coffee-file', 'Create a coffeescript migration file') + .boolean('coffee-file') + .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', + 'Set the name of the migration table, which stores the migration history.' + ) + .alias('table', 'migration-table') + .alias('t', 'table') + .string('t') + + .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.') + .string('vcseeder-dir') + + .describe('staticseeder-dir', 'Set the path to the Seeder directory.') + .string('staticseeder-dir') + + .describe('non-transactional', 'Explicitly disable transactions') + .boolean('non-transactional') + + .describe('ignore-completed-migrations', 'Start at the first migration') + .boolean('ignore-completed-migrations') + + .describe('log-level', 'Set the log-level, for example sql|warn') + .string('log-level') + + .argv; if (internals.argv.version) { console.log(dbm.version); @@ -420,9 +431,9 @@ function setDefaultArgv(internals, isModule) { process.exit(1); } - if( internals.argv['log-level'] ) { + if (internals.argv['log-level']) { - log.setLogLevel( internals.argv['log-level'] ); + log.setLogLevel(internals.argv['log-level']); } internals.ignoreCompleted = internals.argv['ignore-completed-migrations']; @@ -435,7 +446,7 @@ function setDefaultArgv(internals, isModule) { internals.dryRun = internals.argv['dry-run']; global.dryRun = internals.dryRun; - if(internals.dryRun) { + if (internals.dryRun) { log.info('dry run'); } @@ -457,7 +468,7 @@ function loadConfig() { } else { config.load(internals.argv.config, internals.argv.env); } - if(internals.verbose) { + if (internals.verbose) { var current = config.getCurrent(); var s = JSON.parse(JSON.stringify(current.settings)); @@ -468,10 +479,10 @@ function loadConfig() { } } -function executeCreateMigration( internals, callback ) { +function executeCreateMigration(internals, callback) { var migrationsDir = internals.argv['migrations-dir']; - if( internals.migrationMode && internals.migrationMode !== 'all' ) { + if (internals.migrationMode && internals.migrationMode !== 'all') { migrationsDir = internals.argv['migrations-dir'] + '/' + internals.migrationMode; @@ -479,7 +490,7 @@ function executeCreateMigration( internals, callback ) { var folder, path; - if(internals.argv._.length === 0) { + if (internals.argv._.length === 0) { log.error('\'migrationName\' is required.'); optimist.showHelp(); process.exit(1); @@ -487,7 +498,8 @@ function executeCreateMigration( internals, callback ) { createMigrationDir(migrationsDir, function(err) { if (err) { - log.error('Failed to create migration directory at ', migrationsDir, err); + log.error('Failed to create migration directory at ', migrationsDir, + err); process.exit(1); } @@ -497,11 +509,11 @@ function executeCreateMigration( internals, callback ) { internals.argv.title = folder[folder.length - 2] || folder[0]; path = migrationsDir; - if(folder.length > 1) { + if (folder.length > 1) { path += '/'; - for(var i = 0; i < folder.length - 1; ++i) { + for (var i = 0; i < folder.length - 1; ++i) { path += folder[i] + '/'; } @@ -510,25 +522,28 @@ function executeCreateMigration( internals, callback ) { var templateType = Migration.TemplateType.DEFAULT_JS; if (shouldCreateSqlFiles() && shouldCreateCoffeeFile()) { templateType = Migration.TemplateType.COFFEE_SQL_FILE_LOADER; + } else if (shouldCreateSqlFiles() && shouldIgnoreOnInitFiles()) { + templateType = Migration.TemplateType.SQL_FILE_LOADER_IGNORE_ON_INIT; } else if (shouldCreateSqlFiles()) { templateType = Migration.TemplateType.SQL_FILE_LOADER; } else if (shouldCreateCoffeeFile()) { templateType = Migration.TemplateType.DEFAULT_COFFEE; } - var migration = new Migration(internals.argv.title + (shouldCreateCoffeeFile() ? '.coffee' : '.js'), path, new Date(), templateType); + var migration = new Migration(internals.argv.title + ( + shouldCreateCoffeeFile() ? '.coffee' : '.js'), path, new Date(), + templateType); index.createMigration(migration, function(err, migration) { - if ( _assert( err, callback ) ) { + if (_assert(err, callback)) { log.info(util.format('Created migration at %s', migration.path)); } }); }); - if (shouldCreateSqlFiles( internals )) { - createSqlFiles( internals, callback ); - } - else { - if( typeof(callback) === 'function' ) { + if (shouldCreateSqlFiles(internals)) { + createSqlFiles(internals, callback); + } else { + if (typeof(callback) === 'function') { callback(); } @@ -539,14 +554,19 @@ function shouldCreateSqlFiles() { return internals.argv['sql-file'] || config['sql-file']; } +function shouldIgnoreOnInitFiles() { + return internals.argv['ignore-on-init'] || config[ + 'ignore-on-init']; +} + function shouldCreateCoffeeFile() { return internals.argv['coffee-file'] || config['coffee-file']; } -function createSqlFiles( internals, callback ) { +function createSqlFiles(internals, callback) { var migrationsDir = internals.argv['migrations-dir']; - if( internals.migrationMode && internals.migrationMode !== 'all' ) { + if (internals.migrationMode && internals.migrationMode !== 'all') { migrationsDir = internals.argv['migrations-dir'] + '/' + internals.migrationMode; @@ -557,29 +577,33 @@ function createSqlFiles( internals, callback ) { if (err) { log.error('Failed to create migration directory at ', sqlDir, err); - if( typeof(callback) !== 'function' ) { + if (typeof(callback) !== 'function') { process.exit(1); - } - else { + } else { - return callback( err ); + return callback(err); } } var templateTypeDefaultSQL = Migration.TemplateType.DEFAULT_SQL; - var migrationUpSQL = new Migration(internals.argv.title + '-up.sql', sqlDir, new Date(), templateTypeDefaultSQL); + var migrationUpSQL = new Migration(internals.argv.title + '-up.sql', + sqlDir, new Date(), templateTypeDefaultSQL); index.createMigration(migrationUpSQL, function(err, migration) { - if( _assert( err, callback ) ) { + if (_assert(err, callback)) { - log.info(util.format('Created migration up sql file at %s', migration.path)); + log.info(util.format('Created migration up sql file at %s', + migration.path)); - var migrationDownSQL = new Migration(internals.argv.title + '-down.sql', sqlDir, new Date(), templateTypeDefaultSQL); + var migrationDownSQL = new Migration(internals.argv.title + + '-down.sql', sqlDir, new Date(), templateTypeDefaultSQL); index.createMigration(migrationDownSQL, function(err, migration) { - if( _assert( err, callback ) ) { + if (_assert(err, callback)) { - log.info(util.format('Created migration down sql file at %s', migration.path)); - if( typeof( callback ) === 'function' ) + log.info(util.format( + 'Created migration down sql file at %s', + migration.path)); + if (typeof(callback) === 'function') callback(); } }); @@ -588,15 +612,14 @@ function createSqlFiles( internals, callback ) { }); } -function _assert( err, callback ) { - if ( err ) { +function _assert(err, callback) { + if (err) { if (typeof(callback) === 'function') { callback(err); return false; - } - else { + } else { assert.ifError(err); return false; @@ -606,126 +629,124 @@ function _assert( err, callback ) { return true; } -function executeUp( internals, callback ) { +function executeUp(internals, callback) { - if(!internals.argv.count) { + if (!internals.argv.count) { internals.argv.count = Number.MAX_VALUE; } index.connect({ - config: config.getCurrent().settings, - internals: internals - }, Migrator, function(err, migrator) { + config: config.getCurrent().settings, + internals: internals + }, Migrator, function(err, migrator) { assert.ifError(err); - if(internals.locTitle) - migrator.migrationsDir = path.resolve(internals.argv['migrations-dir'], internals.locTitle); + if (internals.locTitle) + migrator.migrationsDir = path.resolve(internals.argv['migrations-dir'], + internals.locTitle); else migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); migrator.driver.createMigrationsTable(function(err) { assert.ifError(err); log.verbose('migration table created'); - migrator.up(internals.argv, internals.onComplete.bind(this, migrator, callback)); + migrator.up(internals.argv, internals.onComplete.bind(this, + migrator, callback)); }); }); } -function executeDown( internals, callback ) { +function executeDown(internals, callback) { - if(!internals.argv.count) { + 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) { + config: config.getCurrent().settings, + internals: internals + }, Migrator, function(err, migrator) { assert.ifError(err); migrator.migrationsDir = path.resolve(internals.argv['migrations-dir']); migrator.driver.createMigrationsTable(function(err) { assert.ifError(err); - migrator.down(internals.argv, internals.onComplete.bind(this, migrator, callback)); + migrator.down(internals.argv, internals.onComplete.bind(this, + migrator, callback)); }); }); } -function executeDB( internals, callback ) { +function executeDB(internals, callback) { - if(internals.argv._.length > 0) { + if (internals.argv._.length > 0) { internals.argv.dbname = internals.argv._.shift().toString(); - } - else { + } else { log.info('Error: You must enter a database name!'); return; } - index.driver(config.getCurrent().settings, function(err, db) - { - if(internals.mode === 'create') - { - db.createDatabase(internals.argv.dbname, { ifNotExists: true }, function() - { - if(err) { + index.driver(config.getCurrent().settings, function(err, db) { + if (internals.mode === 'create') { + db.createDatabase(internals.argv.dbname, { + ifNotExists: true + }, function() { + if (err) { log.info('Error: Failed to create database!'); - } - else { + } else { log.info('Created database "' + internals.argv.dbname + '"'); } db.close(); callback(); }); - } - else if(internals.mode === 'drop') - { - db.dropDatabase(internals.argv.dbname, { ifExists: true }, function() - { - if(err) { + } else if (internals.mode === 'drop') { + db.dropDatabase(internals.argv.dbname, { + ifExists: true + }, function() { + if (err) { log.info('Error: Failed to drop database!'); - } - else { + } else { log.info('Deleted database "' + internals.argv.dbname + '"'); } db.close(); callback(); }); - } - else + } else return; }); } -function executeSeed( internals, callback ) { +function executeSeed(internals, callback) { - if(internals.argv._.length > 0) { + if (internals.argv._.length > 0) { internals.argv.destination = internals.argv._.shift().toString(); } index.connect({ - config: config.getCurrent().settings, - internals: internals - }, Seeder, function(err, seeder) - { + 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']); + seeder.seedDir = path.resolve(internals.argv[(internals.mode !== + 'static') ? 'vcseeder-dir' : 'staticseeder-dir']); - if(internals.mode === 'static') { + if (internals.mode === 'static') { - seeder.seed(internals.argv, internals.onComplete.bind(this, seeder, callback)); - } - else { + seeder.seed(internals.argv, internals.onComplete.bind(this, seeder, + callback)); + } else { seeder.createSeedsTable(function(err) { - if( _assert( err, callback ) ) { + if (_assert(err, callback)) { - seeder.seed(internals.argv, internals.onComplete.bind(this, seeder, callback)); + seeder.seed(internals.argv, internals.onComplete.bind(this, + seeder, callback)); } }); } @@ -736,17 +757,19 @@ internals.onComplete = onComplete; function onComplete(migrator, callback, originalErr) { - if( typeof(callback) !== 'function' ) { + if (typeof(callback) !== 'function') { originalErr = originalErr || callback; } migrator.driver.close(function(err) { - if( ( err || originalErr ) && typeof(callback) === 'function' ) { + if ((err || originalErr) && typeof(callback) === 'function') { - callback({ err: err, originalErr: originalErr }); + callback({ + err: err, + originalErr: originalErr + }); return; - } - else { + } else { assert.ifError(originalErr); assert.ifError(err); @@ -758,67 +781,66 @@ function onComplete(migrator, callback, originalErr) { process.exit(0); } - if( typeof( callback ) === 'function' ) { + if (typeof(callback) === 'function') { callback(); } }); } -function run( internals ) { +function run(internals) { var action = internals.argv._.shift(), - folder = action.split(':'); + folder = action.split(':'); action = folder[0]; - switch(action) { + switch (action) { case 'create': - if(folder[1]) - { + if (folder[1]) { internals.matching = folder[1]; internals.migrationMode = folder[1]; } - executeCreateMigration( internals ); + executeCreateMigration(internals); break; case 'up': case 'down': case 'reset': - if(action === 'reset') + if (action === 'reset') internals.argv.count = Number.MAX_VALUE; - if(internals.argv._.length > 0) { + if (internals.argv._.length > 0) { if (action === 'down') { - log.info('Ignoring migration name for down migrations. Use --count to control how many down migrations are run.'); + log.info( + 'Ignoring migration name for down migrations. Use --count to control how many down migrations are run.' + ); internals.argv.destination = null; } else { internals.argv.destination = internals.argv._.shift().toString(); } } - if(folder[1]) - { + if (folder[1]) { internals.matching = folder[1]; internals.migrationMode = folder[1]; } - if(action == 'up') { - executeUp( internals ); + if (action == 'up') { + executeUp(internals); } else { - executeDown( internals ); + executeDown(internals); } break; case 'db': - if(folder.length < 1) { + if (folder.length < 1) { log.info('Please enter a valid command, i.e. db:create|db:drop'); - } - else { + } else { internals.mode = folder[1]; - executeDB( internals ); + executeDB(internals); } break; case 'seed': @@ -826,13 +848,12 @@ function run( internals ) { internals.mode = folder[1] || 'vc'; internals.migrationMode = folder[2]; - if( internals.argv._[0] === 'down' ) { + if (internals.argv._[0] === 'down') { - internals.argv._.shift(); - } - else { + internals.argv._.shift(); + } else { - executeSeed( internals ); + executeSeed(internals); } break; diff --git a/lib/migration.js b/lib/migration.js index 152bbf90..2db3ebda 100644 --- a/lib/migration.js +++ b/lib/migration.js @@ -17,12 +17,13 @@ try { var internals = {}; function writeMigrationRecord(db, migration, callback) { - db._runSql('INSERT INTO ' + internals.migrationTable + ' (name, run_on) VALUES (?, ?)', [migration.name, new Date()], 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) { this.title = arguments[0]; this.date = arguments[2]; @@ -121,7 +122,8 @@ Migration.prototype.sqlFileLoaderTemplate = function() { "};", "", "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');", " fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", " if (err) return callback(err);", " console.log('received data: ' + data);", @@ -134,7 +136,69 @@ Migration.prototype.sqlFileLoaderTemplate = function() { "};", "", "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');", + " fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", + " if (err) return callback(err);", + " console.log('received data: ' + data);", + "", + " db.runSql(data, function(err) {", + " if (err) return callback(err);", + " callback();", + " });", + " });", + "};", + "" + ].join("\n"); +}; + +Migration.prototype.sqlFileLoaderIgnoreOnInitTemplate = function() { + return [ + "'use strict';", + "", + "var dbm;", + "var type;", + "var seed;", + "var fs = require('fs');", + "var path = require('path');", + "var ignoreOnInit = false;", + + + "", + "/**", + " * We receive the dbmigrate dependency from dbmigrate initially.", + " * This enables us to not have to rely on NODE_PATH.", + " */", + "exports.setup = function(options, seedLink) {", + " dbm = options.dbmigrate;", + " ignoreOnInit = options.ignoreOnInit", + " type = dbm.dataType;", + " seed = seedLink;", + "};", + "", + "exports.up = function(db, callback) {", + " var filePath = path.join(__dirname + '/sqls/" + this.name.replace( + '.js', '') + "-up.sql');", + " if (!ignoreOnInit) {", + " fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", + " if (err) return callback(err);", + " console.log('received data: ' + data);", + "", + " db.runSql(data, function(err) {", + " if (err) return callback(err);", + " callback();", + " });", + " });", + " }", + " else {", + " console.log('ignoring on init: ' + filePath)", + " callback();", + "}", + "};", + "", + "exports.down = function(db, callback) {", + " var filePath = path.join(__dirname + '/sqls/" + this.name.replace( + '.js', '') + "-down.sql');", " fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){", " if (err) return callback(err);", " console.log('received data: ' + data);", @@ -170,14 +234,16 @@ Migration.prototype.coffeeSqlFileLoaderTemplate = function() { "", "", "exports.up = (db, callback) ->", - " filePath = path.join \"#{__dirname}/sqls/"+this.name.replace('.coffee', '')+"-up.sql\"", + " filePath = path.join \"#{__dirname}/sqls/" + this.name.replace( + '.coffee', '') + "-up.sql\"", " fs.readFile filePath, {encoding: 'utf-8'}, (err,data) ->", " return callback err if err", "", " db.runSql data, callback", "", "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) ->", " return callback err if err", @@ -192,7 +258,8 @@ Migration.TemplateType = { DEFAULT_SQL: 1, SQL_FILE_LOADER: 2, DEFAULT_COFFEE: 3, - COFFEE_SQL_FILE_LOADER: 4 + COFFEE_SQL_FILE_LOADER: 4, + SQL_FILE_LOADER_IGNORE_ON_INIT: 5 }; Migration.prototype.getTemplate = function() { @@ -205,6 +272,8 @@ Migration.prototype.getTemplate = function() { return this.defaultCoffeeTemplate(); case Migration.TemplateType.COFFEE_SQL_FILE_LOADER: return this.coffeeSqlFileLoaderTemplate(); + case Migration.TemplateType.SQL_FILE_LOADER_IGNORE_ON_INIT: + return this.sqlFileLoaderIgnoreOnInitTemplate(); case Migration.TemplateType.DEFAULT_JS: default: return this.defaultJsTemplate(); @@ -218,7 +287,10 @@ Migration.prototype.write = function(callback) { Migration.loadFromFilesystem = function(dir, internals, callback) { log.verbose('loading migrations from dir', dir); fs.readdir(dir, function(err, files) { - if (err) { callback(err); return; } + if (err) { + callback(err); + return; + } var coffeeWarn = true; files = files.filter(function(file) { if (coffeeWarn && !coffeeSupported && /\.coffee$/.test(file)) { @@ -238,17 +310,19 @@ Migration.loadFromDatabase = function(dir, driver, internals, callback) { if (internals.ignoreCompleted) { callback(null, []); - } - else { + } else { log.verbose('loading migrations from database'); driver.allLoadedMigrations(function(err, dbResults) { - if (err && !internals.dryRun) { callback(err); return; } - else if (err && internals.dryRun) { + if (err && !internals.dryRun) { + callback(err); + return; + } else if (err && internals.dryRun) { dbResults = [] } var migrations = dbResults.filter(function(result) { - return result.name.substr(0,result.name.lastIndexOf('/')) === internals.matching; + return result.name.substr(0, result.name.lastIndexOf('/')) === + internals.matching; }).map(function(result) { return new Migration(path.join(dir, result.name), internals); });