sql-ddl-sync
Advanced tools
Comparing version 0.1.1 to 0.1.2
@@ -159,5 +159,6 @@ var SQL = require("../SQL"); | ||
exports.addIndex = function (db, name, collection, columns, cb) { | ||
exports.addIndex = function (db, name, unique, collection, columns, cb) { | ||
return db.query(SQL.CREATE_INDEX({ | ||
name : name, | ||
unique : unique, | ||
collection : collection, | ||
@@ -303,3 +304,4 @@ columns : columns | ||
indexes[rows[i].Key_name] = { | ||
columns : [] | ||
columns : [], | ||
unique : (rows[i].Non_unique == 0) | ||
}; | ||
@@ -306,0 +308,0 @@ } |
@@ -170,3 +170,3 @@ var util = require("util"); | ||
exports.getCollectionIndexes = function (db, name, cb) { | ||
db.query("SELECT t.relname, i.relname, a.attname " + | ||
db.query("SELECT t.relname, i.relname, a.attname, ix.indisunique, ix.indisprimary " + | ||
"FROM pg_class t, pg_class i, pg_index ix, pg_attribute a " + | ||
@@ -184,5 +184,6 @@ "WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid " + | ||
exports.addIndex = function (db, name, collection, columns, cb) { | ||
exports.addIndex = function (db, name, unique, collection, columns, cb) { | ||
return db.query(SQL.CREATE_INDEX({ | ||
name : name, | ||
unique : unique, | ||
collection : collection, | ||
@@ -335,3 +336,3 @@ columns : columns | ||
for (var i = 0; i < rows.length; i++) { | ||
if (rows[i].relname.match(/.+_pkey$/)) { | ||
if (rows[i].indisprimary) { | ||
continue; | ||
@@ -342,3 +343,4 @@ } | ||
indexes[rows[i].relname] = { | ||
columns : [] | ||
columns : [], | ||
unique : rows[i].indisunique | ||
}; | ||
@@ -345,0 +347,0 @@ } |
@@ -43,3 +43,3 @@ exports.CREATE_TABLE = function (options, dialect) { | ||
exports.CREATE_INDEX = function (options, dialect) { | ||
var sql = "CREATE INDEX " + dialect.escapeId(options.name) + | ||
var sql = "CREATE" + (options.unique ? " UNIQUE" : "") + " INDEX " + dialect.escapeId(options.name) + | ||
" ON " + dialect.escapeId(options.collection) + | ||
@@ -46,0 +46,0 @@ " (" + options.columns.map(function (col) { return dialect.escapeId(col); }) + ")"; |
108
lib/Sync.js
@@ -12,2 +12,3 @@ var Queue = require("./Queue").Queue; | ||
var collections = []; | ||
var total_changes; | ||
@@ -76,2 +77,4 @@ var processCollection = function (collection, cb) { | ||
total_changes += 1; | ||
return nextBefore(); | ||
@@ -109,2 +112,4 @@ }; | ||
total_changes += 1; | ||
if (col.before) { | ||
@@ -133,2 +138,4 @@ queue.add(col, function (col, next) { | ||
total_changes += 1; | ||
if (col.before) { | ||
@@ -157,2 +164,5 @@ queue.add(col, function (col, next) { | ||
debug("Dropping column " + collection.name + "." + k); | ||
total_changes += 1; | ||
return Dialect.dropCollectionColumn(db, collection.name, k, next); | ||
@@ -179,30 +189,61 @@ }); | ||
for (var k in collection.properties) { | ||
if (!collection.properties[k].hasOwnProperty("index") || !collection.properties[k].index) { | ||
continue; | ||
} | ||
if (!Array.isArray(collection.properties[k].index)) { | ||
collection.properties[k].index = [ collection.properties[k].index ]; | ||
} | ||
if (collection.properties[k].unique) { | ||
if (!Array.isArray(collection.properties[k].unique)) { | ||
collection.properties[k].unique = [ collection.properties[k].unique ]; | ||
} | ||
for (var i = 0; i < collection.properties[k].index.length; i++) { | ||
if (collection.properties[k].index[i] === true) { | ||
indexes.push({ | ||
name : k + "_index", | ||
columns : [ k ] | ||
}); | ||
} else { | ||
found = false; | ||
for (var i = 0; i < collection.properties[k].unique.length; i++) { | ||
if (collection.properties[k].unique[i] === true) { | ||
indexes.push({ | ||
name : k + "_unique", | ||
unique : true, | ||
columns : [ k ] | ||
}); | ||
} else { | ||
found = false; | ||
for (var j = 0; j < indexes.length; j++) { | ||
if (indexes[j].name == collection.properties[k].index[i]) { | ||
found = true; | ||
indexes[j].columns.push(k); | ||
break; | ||
for (var j = 0; j < indexes.length; j++) { | ||
if (indexes[j].name == collection.properties[k].unique[i]) { | ||
found = true; | ||
indexes[j].columns.push(k); | ||
break; | ||
} | ||
} | ||
if (!found) { | ||
indexes.push({ | ||
name : collection.properties[k].unique[i], | ||
unique : true, | ||
columns : [ k ] | ||
}); | ||
} | ||
} | ||
if (!found) { | ||
} | ||
} | ||
if (collection.properties[k].index) { | ||
if (!Array.isArray(collection.properties[k].index)) { | ||
collection.properties[k].index = [ collection.properties[k].index ]; | ||
} | ||
for (var i = 0; i < collection.properties[k].index.length; i++) { | ||
if (collection.properties[k].index[i] === true) { | ||
indexes.push({ | ||
name : collection.properties[k].index[i], | ||
name : k + "_index", | ||
columns : [ k ] | ||
}); | ||
} else { | ||
found = false; | ||
for (var j = 0; j < indexes.length; j++) { | ||
if (indexes[j].name == collection.properties[k].index[i]) { | ||
found = true; | ||
indexes[j].columns.push(k); | ||
break; | ||
} | ||
} | ||
if (!found) { | ||
indexes.push({ | ||
name : collection.properties[k].index[i], | ||
columns : [ k ] | ||
}); | ||
} | ||
} | ||
@@ -229,6 +270,20 @@ } | ||
debug("Adding index " + name + "." + indexes[i].name + " (" + indexes[i].columns.join(", ") + ")"); | ||
total_changes += 1; | ||
queue.add(indexes[i], function (index, next) { | ||
return Dialect.addIndex(db, index.name, name, index.columns, next); | ||
return Dialect.addIndex(db, index.name, index.unique, name, index.columns, next); | ||
}); | ||
continue; | ||
} else if (!db_indexes[indexes[i].name].unique != !indexes[i].unique) { | ||
debug("Replacing index " + name + "." + indexes[i].name); | ||
total_changes += 1; | ||
queue.add(indexes[i], function (index, next) { | ||
return Dialect.removeIndex(db, index.name, name, next); | ||
}); | ||
queue.add(indexes[i], function (index, next) { | ||
return Dialect.addIndex(db, index.name, index.unique, name, index.columns, next); | ||
}); | ||
} | ||
@@ -240,2 +295,5 @@ delete db_indexes[indexes[i].name]; | ||
debug("Removing index " + name + "." + i); | ||
total_changes += 1; | ||
queue.add(i, function (index, next) { | ||
@@ -289,3 +347,5 @@ return Dialect.removeIndex(db, index, name, next); | ||
if (i >= collections.length) { | ||
return cb(); | ||
return cb(null, { | ||
changes : total_changes | ||
}); | ||
} | ||
@@ -304,2 +364,4 @@ | ||
total_changes = 0; | ||
return processNext(); | ||
@@ -306,0 +368,0 @@ } |
{ | ||
"author" : "Diogo Resende <dresende@thinkdigital.pt>", | ||
"name" : "sql-ddl-sync", | ||
"description" : "NodeJS SQL DDL Synchronization", | ||
"keywords" : [ | ||
"sql", | ||
"ddl", | ||
"sync", | ||
"mysql", | ||
"postgres", | ||
"sqlite" | ||
], | ||
"version" : "0.1.1", | ||
"license" : "MIT", | ||
"repository" : "http://github.com/dresende/node-sql-ddl-sync.git", | ||
"main" : "./lib/Sync", | ||
"scripts" : { | ||
"test" : "make test" | ||
}, | ||
"engines" : { | ||
"node" : "*" | ||
}, | ||
"analyse" : false, | ||
"dependencies": { | ||
"lodash" : "2.0.0" | ||
}, | ||
"devDependencies": { | ||
"mocha" : "1.12.1", | ||
"should" : "1.2.2" | ||
} | ||
"author" : "Diogo Resende <dresende@thinkdigital.pt>", | ||
"name" : "sql-ddl-sync", | ||
"description" : "NodeJS SQL DDL Synchronization", | ||
"keywords" : [ "sql", "ddl", "sync", "mysql", "postgres", "sqlite" ], | ||
"version" : "0.1.2", | ||
"license" : "MIT", | ||
"repository" : "http://github.com/dresende/node-sql-ddl-sync.git", | ||
"main" : "./lib/Sync", | ||
"scripts" : { "test": "make test" }, | ||
"engines" : { "node": "*" }, | ||
"analyse" : false, | ||
"dependencies" : { | ||
"lodash" : "2.0.0" | ||
}, | ||
"devDependencies" : { | ||
"mocha" : "1.12.1", | ||
"should" : "1.2.2", | ||
"commander" : "~2.0.0" | ||
} | ||
} |
@@ -70,1 +70,30 @@ ## NodeJS SQL DDL Synchronization | ||
``` | ||
## Test | ||
To test, first make sure you have development dependencies installed. Go to the root folder and do: | ||
```sh | ||
npm install | ||
``` | ||
Then, just run the tests. | ||
```sh | ||
npm test | ||
``` | ||
If you have a supported database server and want to test against it, first install the module: | ||
```sh | ||
# if you have a mysql server | ||
npm install mysql | ||
# if you have a postgresql server | ||
npm install pg | ||
``` | ||
And then run: | ||
```sh | ||
node test/run-db --uri 'mysql://username:password@localhost/database' | ||
``` |
@@ -0,1 +1,4 @@ | ||
exports.dialect = null; | ||
exports.table = "sql_ddl_sync_test_table"; | ||
exports.fakeDialect = { | ||
@@ -6,1 +9,65 @@ escapeId : function (id) { | ||
}; | ||
exports.dropColumn = function (column) { | ||
return function (done) { | ||
switch (exports.dialect) { | ||
case "mysql": | ||
return exports.db.query("ALTER TABLE ?? DROP ??", [ exports.table, column ], done); | ||
case "postgresql": | ||
return exports.db.query("ALTER TABLE " + exports.table + " DROP " + column, done); | ||
} | ||
return done(unknownProtocol()); | ||
}; | ||
}; | ||
exports.addColumn = function (column) { | ||
return function (done) { | ||
switch (exports.dialect) { | ||
case "mysql": | ||
return exports.db.query("ALTER TABLE ?? ADD ?? INTEGER NOT NULL", [ exports.table, column ], done); | ||
case "postgresql": | ||
return exports.db.query("ALTER TABLE " + exports.table + " ADD " + column + " INTEGER NOT NULL", done); | ||
} | ||
return done(unknownProtocol()); | ||
}; | ||
}; | ||
exports.changeColumn = function (column) { | ||
return function (done) { | ||
switch (exports.dialect) { | ||
case "mysql": | ||
return exports.db.query("ALTER TABLE ?? MODIFY ?? INTEGER NOT NULL", [ exports.table, column ], done); | ||
case "postgresql": | ||
return exports.db.query("ALTER TABLE " + exports.table + " ALTER " + column + " TYPE DOUBLE PRECISION", done); | ||
} | ||
return done(unknownProtocol()); | ||
}; | ||
}; | ||
exports.addIndex = function (name, column, unique) { | ||
return function (done) { | ||
switch (exports.dialect) { | ||
case "mysql": | ||
return exports.db.query("CREATE " + (unique ? "UNIQUE" : "") + " INDEX ?? ON ?? (??)", [ name, exports.table, column ], done); | ||
case "postgresql": | ||
return exports.db.query("CREATE " + (unique ? "UNIQUE" : "") + " INDEX " + exports.table + "_" + name + " ON " + exports.table + " (" + column + ")", done); | ||
} | ||
return done(unknownProtocol()); | ||
}; | ||
}; | ||
exports.dropIndex = function (name) { | ||
return function (done) { | ||
switch (exports.dialect) { | ||
case "mysql": | ||
return exports.db.query("DROP INDEX ?? ON ??", [ name, exports.table ], done); | ||
case "postgresql": | ||
return exports.db.query("DROP INDEX " + exports.table + "_" + name, done); | ||
} | ||
return done(unknownProtocol()); | ||
}; | ||
}; | ||
function unknownProtocol() { | ||
return new Error("Unknown protocol - " + exports.dialect); | ||
} |
@@ -88,1 +88,35 @@ var common = require("../common"); | ||
}); | ||
describe("SQL.CREATE_INDEX", function () { | ||
it("should return an CREATE INDEX", function (done) { | ||
SQL.CREATE_INDEX({ | ||
name : "fake_index", | ||
collection : "fake_table", | ||
columns : [ "my_fake_column" ] | ||
}, Dialect).should.equal("CREATE INDEX $$fake_index$$ ON $$fake_table$$ ($$my_fake_column$$)"); | ||
return done(); | ||
}); | ||
it("should return an CREATE UNIQUE INDEX if unique passed", function (done) { | ||
SQL.CREATE_INDEX({ | ||
name : "fake_index", | ||
collection : "fake_table", | ||
unique : true, | ||
columns : [ "my_fake_column" ] | ||
}, Dialect).should.equal("CREATE UNIQUE INDEX $$fake_index$$ ON $$fake_table$$ ($$my_fake_column$$)"); | ||
return done(); | ||
}); | ||
}); | ||
describe("SQL.DROP_INDEX", function () { | ||
it("should return an DROP INDEX", function (done) { | ||
SQL.DROP_INDEX({ | ||
name : "fake_index", | ||
collection : "fake_table" | ||
}, Dialect).should.equal("DROP INDEX $$fake_index$$ ON $$fake_table$$"); | ||
return done(); | ||
}); | ||
}); |
@@ -12,3 +12,6 @@ var common = require("./common"); | ||
fs.readdirSync(location).filter(function (file) { | ||
return file.substr(-3) === '.js'; | ||
if (file == "db.js") { | ||
return false; | ||
} | ||
return (file.substr(-3) === '.js'); | ||
}).forEach(function (file) { | ||
@@ -15,0 +18,0 @@ mocha.addFile( |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
52804
18
1593
99
0
3