node-pg-migrate
Advanced tools
+3
-4
@@ -9,8 +9,7 @@ /* | ||
| var connection_string = process.env.DATABASE_URL; | ||
| var client; | ||
| var client_active = false; | ||
| module.exports.init = function(conenction_string){ | ||
| client = new pg.Client(connection_string); | ||
| module.exports.init = function(connection_string){ | ||
| client = new pg.Client(connection_string || process.env.DATABASE_URL); | ||
| } | ||
@@ -47,2 +46,2 @@ | ||
| }); | ||
| } | ||
| } |
@@ -8,3 +8,3 @@ var utils = require('../utils'); | ||
| return _.map(extensions, function(extension){ | ||
| return utils.t('CREATE EXTENSION {extension};', { | ||
| return utils.t('CREATE EXTENSION \"{extension}\";', { | ||
| extension: extension | ||
@@ -18,3 +18,3 @@ }); | ||
| return _.map(extensions, function(extension){ | ||
| return utils.t('DROP EXTENSION {extension};', { | ||
| return utils.t('DROP EXTENSION \"{extension}\";', { | ||
| extension: extension | ||
@@ -27,2 +27,2 @@ }); | ||
| // setup reverse functions | ||
| ops.create.reverse = ops.drop; | ||
| ops.create.reverse = ops.drop; |
@@ -14,12 +14,11 @@ var utils = require('../utils'); | ||
| where - where clause | ||
| concurrently - | ||
| concurrently - | ||
| options.method - [ btree | hash | gist | spgist | gin ] | ||
| */ | ||
| options = options || {}; | ||
| if ( _.isArray(columns) ) columns = columns.join(', '); | ||
| var sql = utils.t('CREATE {unique} INDEX {concurrently}{index_name} ON {table_name}{method} ({columns}){where};', { | ||
| var sql = utils.t('CREATE {unique} INDEX {concurrently}{index_name} ON \"{table_name}\"{method} ({columns}){where};', { | ||
| table_name : table_name, | ||
| index_name : generateIndexName( table_name, columns, options ), | ||
| columns : columns, | ||
| columns : generateColumnsString(columns), | ||
| unique : options.unique ? ' UNIQUE ' : '', | ||
@@ -36,3 +35,3 @@ concurrently : options.concurrently ? ' CONCURRENTLY ' : '', | ||
| options = options || {}; | ||
| if (_.isArray(columns)) columns = columns.join(', '); | ||
| var index_name = generateIndexName( table_name, columns, options ); | ||
@@ -50,3 +49,4 @@ return utils.t('DROP INDEX {index};', { index: index_name } ); | ||
| var name = table_name; | ||
| name += '_' + columns.replace(/, /g, '_'); | ||
| if ( _.isArray(columns) ) name += '_' + columns.join('_'); | ||
| else name += '_' + columns; | ||
| if (options.unique) name += '_unique'; | ||
@@ -58,1 +58,6 @@ name += '_index'; | ||
| } | ||
| function generateColumnsString(columns){ | ||
| if ( _.isArray(columns) ) return columns = columns.map(function(name){return '"' + name + '"';}).join(', '); | ||
| if (/.+\(.*\)/.test(columns)) return columns; //expression | ||
| return columns = '"' + columns + '"'; //single column | ||
| } |
@@ -173,5 +173,11 @@ var utils = require('../utils'); | ||
| constraints.push('REFERENCES '+options.references); | ||
| if (options.onDelete){ | ||
| constraints.push('ON DELETE '+options.onDelete); | ||
| } | ||
| if (options.onUpdate){ | ||
| constraints.push('ON UPDATE '+options.onUpdate); | ||
| } | ||
| } | ||
| return utils.t('{column_name} {type}{default}{constraints}', { | ||
| return utils.t('\"{column_name}\" {type}{default}{constraints}', { | ||
| column_name: column_name, | ||
@@ -184,2 +190,2 @@ type: type, | ||
| }).join(", \n"); | ||
| } | ||
| } |
+47
-36
@@ -26,36 +26,54 @@ var async = require('async'); | ||
| }, | ||
| function determineMigrationsToRun(err, result){ | ||
| if (err) return callback(err); | ||
| if (!result || !result.rows) return callback(new Error('Unable to fetch migrations from '+options.migrations_table+' table')); | ||
| function determineMigrationsToRun(err, result) { | ||
| if(err) return callback(err); | ||
| if(!result || !result.rows) return callback(new Error('Unable to fetch migrations from pgmigrations table')); | ||
| // TODO: handle merging of migrations that are out of order better | ||
| // show a warning and add an option to apply missing migraitons | ||
| //store done migration names | ||
| var runNames = result.rows.map(function(row) { | ||
| return row.name; | ||
| }); | ||
| // go through each existing migration and verify the file exists | ||
| // store the index so we know where we are starting | ||
| for (var i=0; i<result.rows.length; i++){ | ||
| // console.log( '"' + result.rows[i].name + '" -- "' + migrations[i].name + '"' ); | ||
| if ( result.rows[i].name !== migrations[i].name ){ | ||
| return callback(new Error('Migration file missing for already ran migration: '+result.rows[i].name)) | ||
| var doneMigrations = []; | ||
| var runMigrations = []; | ||
| //filter out undone and done migrations from list of files | ||
| for(var i = 0; i < migrations.length; i++) { | ||
| if(runNames.indexOf(migrations[i].name) < 0) { | ||
| //if specific migration file is requested | ||
| if(options.file && options.file == migrations[i].name) { | ||
| runMigrations = [migrations[i]]; | ||
| break; | ||
| } | ||
| runMigrations.push(migrations[i]); | ||
| } else { | ||
| doneMigrations.push(migrations[i]) | ||
| } | ||
| if (options.file && options.file == migrations[i].name){ | ||
| migrate_to_index = i; | ||
| } | ||
| } | ||
| current_index = result.rows.length; | ||
| if (options.count){ | ||
| //final selection will go here | ||
| var to_run; | ||
| //down gets by default one migration at the time, if not set otherwise | ||
| if(options.direction == 'down') { | ||
| to_run = doneMigrations.slice(-1); | ||
| //up gets all undone migrations by default | ||
| } else { | ||
| to_run = runMigrations; | ||
| } | ||
| //if specific count of migrations is requested | ||
| if(options.count) { | ||
| // infinity is set in the bin file | ||
| if (options.count == Infinity){ | ||
| migrate_to_index = migrations.length; | ||
| } else { | ||
| // users can also specify the number of migrations to move up and down | ||
| migrate_to_index = current_index + options.count * (options.direction=='up' ?1:-1); | ||
| if(options.count !== Infinity) { | ||
| if(options.direction == 'up') { | ||
| to_run = runMigrations.slice(0, options.count); | ||
| } else { | ||
| to_run = doneMigrations.slice(options.count * -1); | ||
| } | ||
| } | ||
| } | ||
| // 0 is a clean slate (no migrations run) | ||
| if (migrate_to_index < 0) return callback(new Error('cannot migrate past the starting position')); | ||
| if (migrate_to_index > migrations.length ) return callback(new Error('Cannot migrate past the last migration defined')); | ||
| if (current_index == migrate_to_index) { | ||
| if(!to_run.length) { | ||
| console.log('No migrations to run!'); | ||
@@ -65,15 +83,8 @@ return callback(); | ||
| var to_run; | ||
| if (options.direction == 'up'){ | ||
| to_run = migrations.slice(current_index, migrate_to_index); | ||
| } else { | ||
| to_run = migrations.slice(migrate_to_index, current_index); | ||
| to_run = to_run.reverse(); | ||
| // TODO: add some fancy colors to logging | ||
| console.log('> Migrating files:'); | ||
| for(var i in to_run) { | ||
| console.log('> - ' + to_run[i].name); | ||
| } | ||
| // TODO: add some fancy colors to logging | ||
| var current_state_name = current_index == 0 ? 'CLEAN SLATE' : migrations[current_index-1].name; | ||
| var new_state_name = migrate_to_index == 0 ? 'CLEAN SLATE' : migrations[migrate_to_index-1].name; | ||
| console.log('> Migrating from '+current_state_name + ' >to> ' + new_state_name ); | ||
| this(null, to_run); | ||
@@ -80,0 +91,0 @@ }, |
+13
-11
| { | ||
| "name": "node-pg-migrate", | ||
| "description": "Node.js database migration management for Postgresql", | ||
| "description": "Postgresql database migration management tool for node.js", | ||
| "author": "Theo Ephraim", | ||
@@ -18,3 +18,3 @@ "bin": { | ||
| ], | ||
| "version": "0.0.9", | ||
| "version": "0.0.10", | ||
| "engines": { | ||
@@ -32,8 +32,7 @@ "node": ">=0.6.0" | ||
| "dependencies": { | ||
| "async": "^0.2.10", | ||
| "dotenv": "^0.5.1", | ||
| "lodash": "~2.4.1", | ||
| "mkdirp": "~0.3.4", | ||
| "optimist": "~0.3.7", | ||
| "pg": "^3.4.1", | ||
| "async": "^0.9.2", | ||
| "dotenv": "^1.1.0", | ||
| "lodash": "~3.9.1", | ||
| "mkdirp": "~0.5.1", | ||
| "optimist": "~0.6.1", | ||
| "pkginfo": "~0.3.0", | ||
@@ -43,6 +42,9 @@ "step": "0.0.5" | ||
| "devDependencies": { | ||
| "mocha": "^2.2.1", | ||
| "rewire": "^2.1.2", | ||
| "sinon": "^1.11.1" | ||
| "mocha": "^2.2.5", | ||
| "rewire": "^2.3.3", | ||
| "sinon": "^1.14.1" | ||
| }, | ||
| "peerDependencies": { | ||
| "pg": "^4.3.0" | ||
| }, | ||
| "scripts": { | ||
@@ -49,0 +51,0 @@ "test": "./node_modules/.bin/mocha test" |
+3
-1
@@ -42,3 +42,3 @@ # pg-migrate | ||
| **IMPORTANT** | ||
| Calling the migration functions on `pgm` doesn't actually migrate your database. These functions just add sql commands to a stack that is is run. | ||
| Calling the migration functions on `pgm` doesn't actually migrate your database. These functions just add sql commands to a stack that is run. | ||
@@ -282,2 +282,4 @@ #### Automatic Down Migrations | ||
| - `references` _[string]_ - a table name that this column is a foreign key to | ||
| - `onDelete` _[string]_ - adds ON DELETE constraint for a reference column | ||
| - `onUpdate` _[string]_ - adds ON UPDATE constraint for a reference column | ||
@@ -284,0 +286,0 @@ #### Data types & Convenience Shorthand |
Network access
Supply chain riskThis module accesses the network.
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
40541
0.31%618
3%311
0.65%5
25%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated