Skip to content

Commit 77490da

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 b1381e5 commit 77490da

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'],
@@ -420,7 +467,7 @@ function setDefaultArgv(internals, isModule) {
420467
'force-exit': false,
421468
'sql-file': false,
422469
'non-transactional': false,
423-
config: internals.configFile || internals.cwd + '/database.json',
470+
config: internals.configFile || 'database.json',
424471
'migrations-dir': internals.cwd + '/migrations',
425472
'vcseeder-dir': internals.cwd + '/VCSeeder',
426473
'staticseeder-dir': internals.cwd + '/Seeder',
@@ -554,7 +601,7 @@ function loadConfig( config, internals ) {
554601
} else if (internals.configObject) {
555602
out = config.loadObject(internals.configObject, currentEnv);
556603
} else {
557-
out = config.loadFile(internals.argv.config, currentEnv);
604+
out = config.loadFile(internals.argv.config, currentEnv, internals.plugins);
558605
}
559606
if (internals.verbose) {
560607
var current = out.getCurrent();
@@ -588,6 +635,10 @@ function executeCreateMigration(internals, config, callback) {
588635
}
589636

590637
createMigrationDir(migrationsDir, function(err) {
638+
639+
var index = require('./connect');
640+
var Migration = require('./lib/migration.js');
641+
591642
if (err) {
592643
log.error('Failed to create migration directory at ', migrationsDir,
593644
err);
@@ -670,6 +721,10 @@ function createSqlFiles(internals, config, callback) {
670721

671722
var sqlDir = migrationsDir + '/sqls';
672723
createMigrationDir(sqlDir, function(err) {
724+
725+
var index = require('./connect');
726+
var Migration = require('./lib/migration.js');
727+
673728
if (err) {
674729
log.error('Failed to create migration directory at ', sqlDir, err);
675730

@@ -727,6 +782,9 @@ function _assert(err, callback) {
727782

728783
function executeUp(internals, config, callback) {
729784

785+
var Migrator = require('./lib/migrator.js');
786+
var index = require('./connect');
787+
730788
if (!internals.argv.count) {
731789
internals.argv.count = Number.MAX_VALUE;
732790
}
@@ -756,6 +814,9 @@ function executeUp(internals, config, callback) {
756814

757815
function executeDown(internals, config, callback) {
758816

817+
var Migrator = require('./lib/migrator.js');
818+
var index = require('./connect');
819+
759820
if (!internals.argv.count) {
760821
log.info('Defaulting to running 1 down migration.');
761822
internals.argv.count = 1;
@@ -779,6 +840,8 @@ function executeDown(internals, config, callback) {
779840

780841
function executeDB(internals, config, callback) {
781842

843+
var index = require('./connect');
844+
782845
if (internals.argv._.length > 0) {
783846
internals.argv.dbname = internals.argv._.shift().toString();
784847
} else {
@@ -828,6 +891,9 @@ function executeDB(internals, config, callback) {
828891

829892
function executeSeed(internals, config, callback) {
830893

894+
var index = require('./connect');
895+
var Seeder = require('./lib/seeder.js');
896+
831897
if (internals.argv._.length > 0) {
832898
internals.argv.destination = internals.argv._.shift().toString();
833899
}
@@ -859,6 +925,9 @@ function executeSeed(internals, config, callback) {
859925

860926
function executeUndoSeed(internals, config, callback) {
861927

928+
var index = require('./connect');
929+
var Seeder = require('./lib/seeder.js');
930+
862931
if (!internals.argv.count) {
863932
log.info('Defaulting to running 1 down seed.');
864933
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)