diff --git a/README.MD b/README.MD index ed63e8f..e1582fa 100644 --- a/README.MD +++ b/README.MD @@ -37,10 +37,37 @@ var connection = mysql.createPool({ migration.init(connection, __dirname + '/migrations'); ``` +### Advanced Setup +If you want to execute something at the end of any migration, you can add third parameter as callback function. Example: + +``` +# migration.js +var mysql = require('mysql'); +var migration = require('mysql-migrations'); + +var connection = mysql.createPool({ + connectionLimit : 10, + host : 'localhost', + user : 'root', + password : 'password', + database : 'your_database' +}); + +migration.init(connection, __dirname + '/migrations', function() { + console.log("finished running migrations"); +}); +``` + ## Adding Migrations ### Initiate a migration -Run `node migration.js add migration create_table_users`. Now open the migrations folder. Locate the newest file with greatest timestamp as it predecessor. The file will have the name which was specified in the command such as `12213545345_create_table_users.js` +Run + +``` +node migration.js add migration create_table_users +``` + +Now open the migrations folder. Locate the newest file with greatest timestamp as it predecessor. The file will have the name which was specified in the command such as `12213545345_create_table_users.js` ### Add migrations Write the query in `up` key of the json created for the forward migration. As a part of good practice, also write the script to rollback the migration in `down` key. Ex. @@ -53,7 +80,11 @@ module.exports = { ``` ### Add seed -Run `node migration.js add seed create_table_users` to add a seed. +Run +``` +node migration.js add seed create_table_users +``` +to add a seed. ``` module.exports = { @@ -64,7 +95,11 @@ module.exports = { ### Initate and Add migration in single command -Run `node migration.js add migration create_table_users "CREATE TABLE mysql_migrations_347ertt3e (user_id INT NOT NULL, UNIQUE KEY user_id (user_id) )"`. Locate the newest file with greatest timestamp as it predecessor and open it. Query will be automatically added as `up` key. However `down` key needs to be filled manually. +Run +``` +node migration.js add migration create_table_users "CREATE TABLE mysql_migrations_347ertt3e (user_id INT NOT NULL, UNIQUE KEY user_id (user_id) )" +``` +Locate the newest file with greatest timestamp as it predecessor and open it. Query will be automatically added as `up` key. However `down` key needs to be filled manually. ### Custom migrations You may initiate the migration file and add a function. @@ -88,6 +123,15 @@ There are few ways to run migrations. 3. Run `node migration.js down`. Runs only 1 `down` migrations. 4. Run `node migration.js refresh`. Runs all down migrations followed by all up. +Example Output: + +``` +UP: "CREATE TABLE users2 (user_id INT NOT NULL, UNIQUE KEY user_id (user_id), name TEXT )" +UP: "CREATE TABLE users (user_id INT NOT NULL, UNIQUE KEY user_id (user_id), name TEXT )" +UP: "CREATE TABLE users1 (user_id INT NOT NULL, UNIQUE KEY user_id (user_id), name TEXT )" +No more "UP" migrations to run +``` + ### Execute anonymous migrations At times, few migrations need to run again or anonymously. There could be variety of reasons old migrations need to be executed or rollbacked. It can be done this way. @@ -103,12 +147,83 @@ node migration.js run 1500891087394_create_table_users.js down >> Since these are anonymous executions, no records are maintained for any executions. +## Executing backdated migrations +Suppose there are few migrations which were merged late into the main branch. Technically, they should not run because they are old migrations and should already have been run, but it happens that someone has been working on a branch for long and once merged into master, the older migrations do not work because the latest migration timestamp is greater. There is a flag which can help in running those migrations. There are two ways: +1. Single Run +``` +node migration.js up --migrate-all +``` +2. For all runs, you can configure in the init part itself. +``` +# migration.js +var mysql = require('mysql'); +var migration = require('mysql-migrations'); + +var connection = mysql.createPool({ + connectionLimit : 10, + host : 'localhost', + user : 'root', + password : 'password', + database : 'your_database' +}); + +migration.init(connection, __dirname + '/migrations', function() {}, ["--migrate-all"]); +``` +and then run migrations normally + +``` +node migration.js up +``` + +## Saving Schema and Loading from Schema +Having schema.sql is good because it will help you review the schema changes in PR itself. The schema is stored in migrations folder under the file name `schema.sql`. There are two ways to generate schema. +1. Single Run +``` +node migration.js up --update-schema +``` +2. For all runs, you can configure in the init part itself. +``` +# migration.js +var mysql = require('mysql'); +var migration = require('mysql-migrations'); + +var connection = mysql.createPool({ + connectionLimit : 10, + host : 'localhost', + user : 'root', + password : 'password', + database : 'your_database' +}); + +migration.init(connection, __dirname + '/migrations', function() {}, ["--update-schema"]); +``` +and then run migrations normally + +``` +node migration.js up +node migration.js down 2 +.. +``` + +Updated Schema will be stored in migrations folder after each run. + +### Loading Directly from Schema +Suppose you setup your project and you want to avoid running the entire migrations and simply want to load it from schema generated in the above process. You can do it via: + +``` +node migration.js load-from-schema +``` + +The above command will create all the tables and make entry in the logs table. It is helpful when setting up projects for newbies or environments without running entire migration process. + +## Pending +>>Test cases: Will pick up when I get time. + ## Help and Support Will be more than happy to improve upon this version. This is an over night build and needs to be improved certainly. Will welcome everyone who wants to contribute. ## Credits and other stuff It is my first contribution to npm and I am sort of happy over it. I made this when I was really looking for a suitable tool with barebone settings allowing me to maintain database structure. I could not find a basic one and hence wrote my own and finally decided to publish. It took me around 2 hours to write the first version which barely works. But it still does my job. ->>Credits to [ramnique](https://github.com/ramnique/) (I worked with him at Stayzilla and he is a great mentor). +>>Credits to my parents. ->>And of course to my parents. diff --git a/core_functions.js b/core_functions.js index d2f5086..b724cdf 100644 --- a/core_functions.js +++ b/core_functions.js @@ -2,6 +2,8 @@ var fs = require("fs"); var fileFunctions = require('./file'); var queryFunctions = require('./query'); +var colors = require('colors'); +var exec = require('child_process').exec; var table = require('./config')['table']; function add_migration(argv, path, cb) { @@ -32,6 +34,33 @@ function add_migration(argv, path, cb) { } function up_migrations(conn, max_count, path, cb) { + queryFunctions.run_query(conn, "SELECT timestamp FROM " + table + " ORDER BY timestamp DESC LIMIT 1", function (results) { + var file_paths = []; + var max_timestamp = 0; + if (results.length) { + max_timestamp = results[0].timestamp; + } + + fileFunctions.readFolder(path, function (files) { + files.forEach(function (file) { + var timestamp_split = file.split("_", 1); + if (timestamp_split.length) { + var timestamp = parseInt(timestamp_split[0]); + if (Number.isInteger(timestamp) && timestamp.toString().length == 13 && timestamp > max_timestamp) { + file_paths.push({ timestamp : timestamp, file_path : file}); + } + } else { + throw new Error('Invalid file ' + file); + } + }); + + var final_file_paths = file_paths.sort(function(a, b) { return (a.timestamp - b.timestamp)}).slice(0, max_count); + queryFunctions.execute_query(conn, path, final_file_paths, 'up', cb); + }); + }); +} + +function up_migrations_all(conn, max_count, path, cb) { queryFunctions.run_query(conn, "SELECT timestamp FROM " + table, function (results) { var file_paths = []; var timestamps = results.map(r => parseInt(r.timestamp)); @@ -85,9 +114,96 @@ function run_migration_directly(file, type, conn, path, cb) { queryFunctions.run_query(conn, query, cb); } +function update_schema(conn, path, cb) { + var conn_config = conn.config.connectionConfig; + var filePath = path + '/' + 'schema.sql'; + fs.unlink(filePath, function() { + var cmd = "mysqldump --no-data "; + if (conn_config.host) { + cmd = cmd + " -h " + conn_config.host; + } + + if (conn_config.port) { + cmd = cmd + " --port=" + conn_config.port; + } + + if (conn_config.user) { + cmd = cmd + " --user=" + conn_config.user; + } + + if (conn_config.password) { + cmd = cmd + " --password=" + conn_config.password; + } + + cmd = cmd + " " + conn_config.database; + exec(cmd, function(error, stdout, stderr) { + fs.writeFile(filePath, stdout, function(err) { + if (err) { + console.log(colors.red("Could not save schema file")); + } + cb(); + }); + }); + }); +} + +function createFromSchema(conn, path, cb) { + var conn_config = conn.config.connectionConfig; + var filePath = path + '/' + 'schema.sql'; + if (fs.existsSync(filePath)) { + var cmd = "mysql "; + if (conn_config.host) { + cmd = cmd + " -h " + conn_config.host; + } + + if (conn_config.port) { + cmd = cmd + " --port=" + conn_config.port; + } + + if (conn_config.user) { + cmd = cmd + " --user=" + conn_config.user; + } + + if (conn_config.password) { + cmd = cmd + " --password=" + conn_config.password; + } + + cmd = cmd + " " + conn_config.database; + cmd = cmd + " < " + filePath; + exec(cmd, function(error, stdout, stderr) { + if (error) { + console.log(colors.red("Could not load from Schema: " + error)); + cb(); + } else { + var file_paths = []; + fileFunctions.readFolder(path, function (files) { + files.forEach(function (file) { + var timestamp_split = file.split("_", 1); + var timestamp = parseInt(timestamp_split[0]); + if (timestamp_split.length) { + file_paths.push({ timestamp : timestamp, file_path : file}); + } else { + throw new Error('Invalid file ' + file); + } + }); + + var final_file_paths = file_paths.sort(function(a, b) { return (a.timestamp - b.timestamp)}).slice(0, 9999999); + queryFunctions.execute_query(conn, path, final_file_paths, 'up', cb, false); + }); + } + }); + } else { + console.log(colors.red("Schema Missing: " + filePath)); + cb(); + } +} + module.exports = { add_migration: add_migration, up_migrations: up_migrations, + up_migrations_all: up_migrations_all, down_migrations: down_migrations, - run_migration_directly: run_migration_directly + run_migration_directly: run_migration_directly, + update_schema: update_schema, + createFromSchema: createFromSchema }; diff --git a/file.js b/file.js index d81bf69..b7ebaff 100644 --- a/file.js +++ b/file.js @@ -13,6 +13,10 @@ function readFolder(path, cb) { throw err; } + var schemaPath = files.indexOf("schema.sql"); + if (schemaPath > -1) { + files.splice(schemaPath, 1); + } cb(files); }); } diff --git a/index.js b/index.js index 466e593..71e1195 100644 --- a/index.js +++ b/index.js @@ -2,17 +2,40 @@ var fs = require("fs"); var coreFunctions = require('./core_functions'); var queryFunctions = require('./query'); - var config = require('./config'); var table = config['table']; var migrations_types = config['migrations_types']; -function migration(conn, path, cb) { +var updateSchema = false; +var migrate_all = false; +function migration(conn, path, cb, options) { if(cb == null) cb = () => {}; + argv = process.argv; + var updateSchemaIndex = argv.indexOf("--update-schema"); + if (updateSchemaIndex > -1) { + updateSchema = true; + argv.splice(updateSchemaIndex, 1); + } + + var migrate_index = argv.indexOf("--migrate-all"); + if (migrate_index > -1) { + migrate_all = true; + argv.splice(migrate_index, 1); + } + + if (options instanceof Array) { + if (options.indexOf("--migrate-all") > -1) { + migrate_all = true; + } + + if (options.indexOf("--update-schema") > -1) { + updateSchema = true; + } + } queryFunctions.run_query(conn, "CREATE TABLE IF NOT EXISTS `" + table + "` (`timestamp` varchar(254) NOT NULL UNIQUE)", function (res) { - handle(process.argv, conn, path, cb); + handle(argv, conn, path, cb); }); } @@ -30,37 +53,60 @@ function handle(argv, conn, path, cb) { } else { count = 999999; } - coreFunctions.up_migrations(conn, count, path, function () { - conn.end(); - cb(); - }); + if (migrate_all) { + coreFunctions.up_migrations_all(conn, count, path, function () { + updateSchemaAndEnd(conn, path); + cb(); + }); + } else { + coreFunctions.up_migrations(conn, count, path, function () { + updateSchemaAndEnd(conn, path); + cb(); + }); + } } else if (argv[2] == 'down') { var count = null; if (argv.length > 3) { count = parseInt(argv[3]); } else count = 1; coreFunctions.down_migrations(conn, count, path, function () { - conn.end(); + updateSchemaAndEnd(conn, path); cb(); }); } else if (argv[2] == 'refresh') { coreFunctions.down_migrations(conn, 999999, path, function () { coreFunctions.up_migrations(conn, 999999, path, function () { - conn.end(); + updateSchemaAndEnd(conn, path); cb(); }); }); } else if (argv[2] == 'run' && migrations_types.indexOf(argv[4]) > -1) { coreFunctions.run_migration_directly(argv[3], argv[4], conn, path, function () { + updateSchemaAndEnd(conn, path); + cb(); + }); + } else if (argv[2] == 'load-from-schema') { + coreFunctions.createFromSchema(conn, path, function () { conn.end(); cb(); }); - } else { + } + else { throw new Error('command not found : ' + argv.join(" ")); } } } +function updateSchemaAndEnd(conn, path) { + if (updateSchema) { + coreFunctions.update_schema(conn, path, function() { + conn.end(); + }) + } else { + conn.end(); + } +} + module.exports = { init: migration } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..efba11c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,403 @@ +{ + "name": "mysql-migrations", + "version": "1.0.6", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "dev": true, + "requires": { + "assertion-error": "^1.0.1", + "deep-eql": "^0.1.3", + "type-detect": "^1.0.0" + } + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + } + } + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "dev": true, + "requires": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + }, + "type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json index bc6d057..bfaab24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mysql-migrations", - "version": "1.0.6", + "version": "1.0.7", "description": "A tool to use with mysql package to maintain migrations", "main": "index.js", "scripts": { @@ -23,7 +23,9 @@ "url": "https://github.com/kawadhiya21/mysql-migrations/issues" }, "homepage": "https://github.com/kawadhiya21/mysql-migrations#readme", - "dependencies": {}, + "dependencies": { + "colors": "^1.4.0" + }, "devDependencies": { "chai": "^3.5.0", "mocha": "^3.2.0", diff --git a/query.js b/query.js index 0a3d9e0..9ea29d1 100644 --- a/query.js +++ b/query.js @@ -1,37 +1,50 @@ var table = require('./config')['table']; var fileFunctions = require('./file'); +var colors = require('colors'); -function run_query(conn, query, cb) { - conn.getConnection(function(err, connection) { - if (err) { - throw err; - } +function run_query(conn, query, cb, run) { + if (run == null) { + run = true; + } - connection.query(query, function (error, results, fields) { - connection.release(); - if (error) { - throw error; + if (run) { + conn.getConnection(function(err, connection) { + if (err) { + throw err; } - cb(results); + + connection.query(query, function (error, results, fields) { + connection.release(); + if (error) { + throw error; + } + cb(results); + }); }); - }); + } else { + cb({}); + } } -function execute_query(conn, path, final_file_paths, type, cb) { +function execute_query(conn, path, final_file_paths, type, cb, run) { + if (run == null) { + run = true; + } + if (final_file_paths.length) { var file_name = final_file_paths.shift()['file_path']; var current_file_path = path + "/" + file_name; var queries = require(current_file_path); - console.info(`${type.toUpperCase()}: "${ queries[type] }"`); + console.info(colors.green("Run: " + run + " Type: " + type.toUpperCase() + ": " +queries[type])); var timestamp_val = file_name.split("_", 1)[0]; if (typeof(queries[type]) == 'string') { run_query(conn, queries[type], function (res) { updateRecords(conn, type, table, timestamp_val, function () { - execute_query(conn, path, final_file_paths, type, cb); + execute_query(conn, path, final_file_paths, type, cb, run); }); - }); + }, run); } else if (typeof(queries[type]) == 'function') { console.info(`${type.toUpperCase()} Function: "${ queries[type].toString() }"`); @@ -43,7 +56,7 @@ function execute_query(conn, path, final_file_paths, type, cb) { } } else { - console.info(`No more "${type.toUpperCase()}" migrations to run`); + console.info(colors.blue("No more " + type.toUpperCase() + " migrations to run")); cb(); } }