Skip to content

Commit 2ad22b1

Browse files
committed
feat(plugins): add basic support for plugins and improve performance
Some libraries have been changed to be delay loaded. DB-Migrate is back to the minimal load time possible again, if no command at all is entered. Basic plugin support and the first hook, in this case of the type overwrite has been added. An functional example of a yaml config plugin has been published. Also some old functions have been cleaned up which are not necessary any more. refers to #397
1 parent 3480e7a commit 2ad22b1

File tree

6 files changed

+187
-43
lines changed

6 files changed

+187
-43
lines changed

api.js

+79-10
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,70 @@ var path = require('path');
44
var util = require('util');
55
var mkdirp = require('mkdirp');
66
var optimist = require('optimist');
7-
var index = require('./connect');
8-
var Migration = require('./lib/migration.js');
9-
var Seeder = require('./lib/seeder.js');
10-
var Migrator = require('./lib/migrator.js');
117
var log = require('db-migrate-shared').log;
128
var pkginfo = require('pkginfo')(module, 'version'); // jshint ignore:line
139
var dotenv = require('dotenv');
14-
var Promise = require('bluebird');
10+
var Promise = Promise;
1511

16-
function dbmigrate(isModule, options, callback) {
12+
function registerPluginLoader(plugins) {
13+
14+
return {
15+
16+
overwrite: function(name) {
17+
18+
if(plugins[name] && plugins[name].length) {
19+
20+
var plugin = plugins[name];
21+
22+
if(plugin.length !== 1) {
23+
log.warn(
24+
'Attention, multiple overwrites registered for %s, we are ' +
25+
'only loading the first plugin %s!',
26+
name,
27+
plugin.name
28+
);
29+
}
30+
31+
plugin = plugin[0];
32+
if(typeof(plugin.loadPlugin) === 'function')
33+
plugin.loadPlugin();
34+
35+
return plugin;
36+
}
37+
38+
return false;
39+
},
40+
41+
hook: function(name) {
42+
43+
if(plugins[name] && plugins[name].length) {
44+
45+
var plugin = plugins[name];
46+
47+
plugin.map(function(plugin) {
48+
49+
if(typeof(plugin.loadPlugin) === 'function')
50+
plugin.loadPlugin();
51+
});
52+
53+
return plugin;
54+
}
55+
56+
return false;
57+
}
58+
};
59+
}
60+
61+
function dbmigrate(plugins, isModule, options, callback) {
1762

1863
this.internals = {
1964

2065
onComplete: onComplete
2166
};
2267
var internals = this.internals;
2368

69+
this.internals.plugins = registerPluginLoader(plugins);
70+
2471
if (typeof(callback) === 'function')
2572
this.internals.onComplete = callback;
2673
else if (typeof(options) === 'function')
@@ -60,8 +107,8 @@ function dbmigrate(isModule, options, callback) {
60107

61108
this.config = loadConfig( require('./lib/config.js'), this.internals );
62109

63-
index.exportInternals(internals);
64-
110+
//delayed loading of bluebird
111+
Promise = require('bluebird');
65112
this.internals.migrationOptions = {
66113
dbmigrate: this.internals.dbm,
67114
ignoreOnInit: this.internals.argv['ignore-on-init'],
@@ -411,7 +458,7 @@ function setDefaultArgv(internals, isModule) {
411458
'force-exit': false,
412459
'sql-file': false,
413460
'non-transactional': false,
414-
config: internals.configFile || internals.cwd + '/database.json',
461+
config: internals.configFile || 'database.json',
415462
'migrations-dir': internals.cwd + '/migrations',
416463
'vcseeder-dir': internals.cwd + '/VCSeeder',
417464
'staticseeder-dir': internals.cwd + '/Seeder',
@@ -545,7 +592,7 @@ function loadConfig( config, internals ) {
545592
} else if (internals.configObject) {
546593
out = config.loadObject(internals.configObject, currentEnv);
547594
} else {
548-
out = config.loadFile(internals.argv.config, currentEnv);
595+
out = config.loadFile(internals.argv.config, currentEnv, internals.plugins);
549596
}
550597
if (internals.verbose) {
551598
var current = out.getCurrent();
@@ -579,6 +626,10 @@ function executeCreateMigration(internals, config, callback) {
579626
}
580627

581628
createMigrationDir(migrationsDir, function(err) {
629+
630+
var index = require('./connect');
631+
var Migration = require('./lib/migration.js');
632+
582633
if (err) {
583634
log.error('Failed to create migration directory at ', migrationsDir,
584635
err);
@@ -661,6 +712,10 @@ function createSqlFiles(internals, config, callback) {
661712

662713
var sqlDir = migrationsDir + '/sqls';
663714
createMigrationDir(sqlDir, function(err) {
715+
716+
var index = require('./connect');
717+
var Migration = require('./lib/migration.js');
718+
664719
if (err) {
665720
log.error('Failed to create migration directory at ', sqlDir, err);
666721

@@ -718,6 +773,9 @@ function _assert(err, callback) {
718773

719774
function executeUp(internals, config, callback) {
720775

776+
var Migrator = require('./lib/migrator.js');
777+
var index = require('./connect');
778+
721779
if (!internals.argv.count) {
722780
internals.argv.count = Number.MAX_VALUE;
723781
}
@@ -747,6 +805,9 @@ function executeUp(internals, config, callback) {
747805

748806
function executeDown(internals, config, callback) {
749807

808+
var Migrator = require('./lib/migrator.js');
809+
var index = require('./connect');
810+
750811
if (!internals.argv.count) {
751812
log.info('Defaulting to running 1 down migration.');
752813
internals.argv.count = 1;
@@ -770,6 +831,8 @@ function executeDown(internals, config, callback) {
770831

771832
function executeDB(internals, config, callback) {
772833

834+
var index = require('./connect');
835+
773836
if (internals.argv._.length > 0) {
774837
internals.argv.dbname = internals.argv._.shift().toString();
775838
} else {
@@ -819,6 +882,9 @@ function executeDB(internals, config, callback) {
819882

820883
function executeSeed(internals, config, callback) {
821884

885+
var index = require('./connect');
886+
var Seeder = require('./lib/seeder.js');
887+
822888
if (internals.argv._.length > 0) {
823889
internals.argv.destination = internals.argv._.shift().toString();
824890
}
@@ -850,6 +916,9 @@ function executeSeed(internals, config, callback) {
850916

851917
function executeUndoSeed(internals, config, callback) {
852918

919+
var index = require('./connect');
920+
var Seeder = require('./lib/seeder.js');
921+
853922
if (!internals.argv.count) {
854923
log.info('Defaulting to running 1 down seed.');
855924
internals.argv.count = 1;

bin/db-migrate

+20-19
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,34 @@ var resolve = require( 'resolve' );
44
var log = require('db-migrate-shared').log;
55

66
process.title = 'db-migrate';
7-
8-
if ( process.argv.indexOf( '--verbose' ) !== -1 || process.argv.indexOf( '-v' ) !== -1 )
7+
if ( process.argv.indexOf( '--verbose' ) !== -1 ||
8+
process.argv.indexOf( '-v' ) !== -1
9+
)
910
global.verbose = true;
1011

1112
resolve( 'db-migrate', {
1213

13-
basedir: process.cwd()
14+
basedir: process.cwd()
1415
}, function ( error, localModule ) {
1516

16-
var DBMigrate, dbmigrate;
17+
var DBMigrate, dbmigrate;
1718

18-
if ( error ) {
19-
DBMigrate = require( '../' );
20-
}
21-
else {
22-
DBMigrate = require( localModule );
23-
log.verbose( 'Detected and using the projects local version of db-migrate. ' +
24-
'\'' + localModule + '\'');
25-
}
19+
if ( error ) {
20+
DBMigrate = require( '../' );
21+
}
22+
else {
23+
DBMigrate = require( localModule );
24+
log.verbose( 'Detected and using the projects local version of db-migrate. ' +
25+
'\'' + localModule + '\'');
26+
}
2627

27-
if ( typeof( DBMigrate.getInstance ) !== 'function' ) {
28-
DBMigrate = require( '../' );
28+
if ( typeof( DBMigrate.getInstance ) !== 'function' ) {
29+
DBMigrate = require( '../' );
2930

30-
log.warn( 'Using global instead of local detected version as you have a ' +
31-
'version older than 0.10.0 in your projects package.json!' );
32-
}
31+
log.warn( 'Using global instead of local detected version as you have a ' +
32+
'version older than 0.10.0 in your projects package.json!' );
33+
}
3334

34-
dbmigrate = DBMigrate.getInstance();
35-
dbmigrate.run();
35+
dbmigrate = DBMigrate.getInstance();
36+
dbmigrate.run();
3637
} );

connect.js

-10
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,3 @@ exports.createMigration = function(migration, callback) {
138138
callback(null, migration);
139139
});
140140
};
141-
142-
exports.exportInternals = function( intern ) {
143-
144-
internals = intern;
145-
};
146-
147-
exports.importInternals = function() {
148-
149-
return internals;
150-
};

index.js

+61-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,70 @@
11
var pkginfo = require('pkginfo')(module, 'version'); // jshint ignore:line
2+
var fs = require('fs');
3+
var path = require('path');
24

35
exports.dataType = require('db-migrate-shared').dataType;
46

7+
function loadPluginList() {
8+
9+
var plugins = JSON.parse(fs.readFileSync(
10+
path.join(process.cwd(), 'package.json'),
11+
'utf-8'
12+
)
13+
),
14+
targets = [];
15+
16+
plugins = Object.assign(plugins.dependencies, plugins.devDependencies);
17+
18+
for(var plugin in plugins) {
19+
20+
if(plugin.startsWith('db-migrate-plugin'))
21+
targets.push(plugin);
22+
}
23+
24+
return targets;
25+
}
26+
27+
function loadPlugins() {
28+
29+
var plugins = loadPluginList(),
30+
i = 0,
31+
length = plugins.length,
32+
hooks = {};
33+
34+
for(; i < length; ++i) {
35+
36+
var plugin = require(plugins[i]);
37+
if(typeof(plugin.name) !== 'string' || !plugin.hooks || !plugin.loadPlugin)
38+
continue;
39+
40+
plugin.hooks.map(function(hook) {
41+
42+
hooks[hook] = hooks[hook] || [];
43+
hooks[hook].push(plugin);
44+
});
45+
}
46+
47+
return hooks;
48+
}
49+
550
module.exports.getInstance = function(isModule, options, callback) {
651

752
delete require.cache[require.resolve('./api.js')];
853
delete require.cache[require.resolve('optimist')];
9-
var mod = require( './api.js' );
10-
return new mod(isModule, options, callback);
54+
var mod = require('./api.js'),
55+
plugins = {};
56+
57+
try {
58+
59+
if(!options || !options.noPlugins)
60+
plugins = loadPlugins();
61+
}
62+
catch(ex) {}
63+
64+
if(options && options.plugins) {
65+
66+
plugins = Object.assign(plugins, options.plugins);
67+
}
68+
69+
return new mod(plugins, isModule, options, callback);
1170
};

lib/config.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var fs = require('fs');
22
var path = require('path');
33
var parseDatabaseUrl = require('parse-database-url');
44
var dbmUtil = require('db-migrate-shared').util;
5+
var log = require('db-migrate-shared').log;
56

67
var setCurrent = exports.setCurrent = function (env) {
78
env = dbmUtil.isArray(env) ? env : [env];
@@ -36,7 +37,7 @@ exports.load = function(config, currentEnv) {
3637
}
3738
};
3839

39-
exports.loadFile = function(fileName, currentEnv) {
40+
exports.loadFile = function(fileName, currentEnv, plugins) {
4041
var config;
4142

4243
try {
@@ -46,7 +47,30 @@ exports.loadFile = function(fileName, currentEnv) {
4647
}
4748

4849
try {
49-
config = require(fileName);
50+
51+
var plugin = false;
52+
53+
if(plugins)
54+
plugin = plugins.overwrite('init:config:overwrite:require');
55+
56+
if(plugin !== false) {
57+
58+
try {
59+
60+
config = plugin['init:config:overwrite:require'](fileName);
61+
}
62+
catch(ex) {
63+
64+
log.warn('Plugin failure "' + plugin.name +
65+
'", falling back to default behavior!');
66+
log.verbose(ex);
67+
68+
config = require(fileName);
69+
}
70+
}
71+
else
72+
config = require(fileName);
73+
5074
} catch(e) {
5175
// distinguish broken files from missing ones
5276
if (e instanceof SyntaxError){

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"url": "https://github.com/db-migrate/node-db-migrate.git"
4545
},
4646
"dependencies": {
47+
"db-migrate-plugin-test": "1.0.0",
4748
"bluebird": "^3.1.1",
4849
"db-migrate-shared": "^1.0.2",
4950
"dotenv": "^2.0.0",

0 commit comments

Comments
 (0)