Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sql-ddl-sync

Package Overview
Dependencies
Maintainers
2
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sql-ddl-sync - npm Package Compare versions

Comparing version 0.1.4 to 0.3.11

Changelog.md

208

lib/Dialects/mysql.js

@@ -9,4 +9,4 @@ var SQL = require("../SQL");

exports.hasCollection = function (db, name, cb) {
db.query("SHOW TABLES LIKE ?", [ name ], function (err, rows) {
exports.hasCollection = function (driver, name, cb) {
driver.execQuery("SHOW TABLES LIKE ?", [ name ], function (err, rows) {
if (err) return cb(err);

@@ -18,4 +18,24 @@

exports.getCollectionProperties = function (db, name, cb) {
db.query("SHOW COLUMNS FROM ??", [ name ], function (err, cols) {
exports.addPrimaryKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? ADD CONSTRAINT ?? PRIMARY KEY(??);"
return driver.execQuery(sql, [tableName, columnName + "PK", columnName] , cb);
};
exports.dropPrimaryKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? DROP PRIMARY KEY;";
return driver.execQuery(sql, [tableName], cb);
};
exports.addForeignKey = function(driver, tableName, options, cb){
var sql = " ALTER TABLE ?? ADD CONSTRAINT ?? FOREIGN KEY(??) REFERENCES ??(??)";
return driver.execQuery(sql, [tableName, options.name + "_fk", options.name, options.references.table, options.references.column], cb);
};
exports.dropForeignKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE " + tableName + " DROP FOREIGN KEY "+ columnName + "_fk;";
return driver.execQuery(sql, [tableName, columnName + '_fk'], cb);
};
exports.getCollectionProperties = function (driver, name, cb) {
driver.execQuery("SHOW COLUMNS FROM ??", [ name ], function (err, cols) {
if (err) return cb(err);

@@ -60,4 +80,3 @@

case "INT":
column.type = "number";
column.rational = false;
column.type = "integer";
column.size = 4; // INT

@@ -86,4 +105,3 @@ for (var k in columnSizes.integer) {

} else {
column.type = "number";
column.rational = false;
column.type = "integer";
}

@@ -128,18 +146,18 @@ break;

exports.createCollection = function (db, name, columns, primary, cb) {
return db.query(SQL.CREATE_TABLE({
exports.createCollection = function (driver, name, columns, keys, cb) {
return driver.execQuery(SQL.CREATE_TABLE({
name : name,
columns : columns,
primary : primary
}, exports), cb);
keys : keys
}, driver), cb);
};
exports.dropCollection = function (db, name, cb) {
return db.query(SQL.DROP_TABLE({
exports.dropCollection = function (driver, name, cb) {
return driver.execQuery(SQL.DROP_TABLE({
name : name
}, exports), cb);
}, driver), cb);
};
exports.addCollectionColumn = function (db, name, column, after_column, cb) {
return db.query(SQL.ALTER_TABLE_ADD_COLUMN({
exports.addCollectionColumn = function (driver, name, column, after_column, cb) {
return driver.execQuery(SQL.ALTER_TABLE_ADD_COLUMN({
name : name,

@@ -149,21 +167,30 @@ column : column,

first : !after_column
}, exports), cb);
}, driver), cb);
};
exports.modifyCollectionColumn = function (db, name, column, cb) {
return db.query(SQL.ALTER_TABLE_MODIFY_COLUMN({
exports.renameCollectionColumn = function (driver, name, oldColName, newColName, cb) {
return cb("MySQL doesn't support simple column rename");
};
exports.modifyCollectionColumn = function (driver, name, column, cb) {
return driver.execQuery(SQL.ALTER_TABLE_MODIFY_COLUMN({
name : name,
column : column
}, exports), cb);
}, driver), cb);
};
exports.dropCollectionColumn = function (db, name, column, cb) {
return db.query(SQL.ALTER_TABLE_DROP_COLUMN({
exports.dropCollectionColumn = function (driver, name, column, cb) {
return driver.execQuery(SQL.ALTER_TABLE_DROP_COLUMN({
name : name,
column : column
}, exports), cb);
}, driver), cb);
};
exports.getCollectionIndexes = function (db, name, cb) {
db.query("SHOW INDEX FROM ??", [ name ], function (err, rows) {
exports.getCollectionIndexes = function (driver, name, cb) {
var q = "";
q += "SELECT index_name, column_name, non_unique ";
q += "FROM information_schema.statistics ";
q += "WHERE table_schema = ? AND table_name = ?";
driver.execQuery(q, [driver.config.database, name], function (err, rows) {
if (err) return cb(err);

@@ -175,21 +202,27 @@

exports.addIndex = function (db, name, unique, collection, columns, cb) {
return db.query(SQL.CREATE_INDEX({
name : name,
exports.addIndex = function (driver, indexName, unique, collection, columns, cb) {
return driver.execQuery(SQL.CREATE_INDEX({
name : indexName,
unique : unique,
collection : collection,
columns : columns
}, exports), cb);
}, driver), cb);
};
exports.removeIndex = function (db, name, collection, cb) {
return db.query(SQL.DROP_INDEX({
exports.removeIndex = function (driver, collection, name, cb) {
return driver.execQuery(SQL.DROP_INDEX({
name : name,
collection : collection
}, exports), cb);
}, driver), cb);
};
exports.getType = function (collection, name, property) {
var type = false;
exports.getType = function (collection, property, driver) {
var type = false;
var customType = null;
if (property.type == 'number' && property.rational === false) {
property.type = 'integer';
delete property.rational;
}
switch (property.type) {

@@ -203,8 +236,7 @@ case "text":

break;
case "integer":
type = columnSizes.integer[property.size || 4];
break;
case "number":
if (property.rational) {
type = columnSizes.floating[property.size || 4];
} else {
type = columnSizes.integer[property.size || 4];
}
type = columnSizes.floating[property.size || 4];
break;

@@ -214,3 +246,3 @@ case "serial":

property.serial = true;
property.primary = true;
property.key = true;
type = "INT(11)";

@@ -237,3 +269,3 @@ break;

case "enum":
type = "ENUM (" + property.values.map(exports.escapeVal) + ")";
type = "ENUM (" + property.values.map(driver.query.escapeVal) + ")";
break;

@@ -243,2 +275,7 @@ case "point":

break;
default:
customType = driver.customTypes[property.type];
if (customType) {
type = customType.datastoreType()
}
}

@@ -259,3 +296,3 @@

if (property.hasOwnProperty("defaultValue")) {
type += " DEFAULT " + exports.escapeVal(property.defaultValue);
type += " DEFAULT " + driver.query.escapeVal(property.defaultValue);
}

@@ -269,55 +306,2 @@

exports.escapeId = function () {
return Array.prototype.slice.apply(arguments).map(function (el) {
return "`" + el.replace(/`/g, '``') + "`";
}).join(".");
};
exports.escapeVal = function (val, timeZone) {
if (val === undefined || val === null) {
return 'NULL';
}
if (Buffer.isBuffer(val)) {
return bufferToString(val);
}
if (Array.isArray(val)) {
return arrayToList(val, timeZone || "local");
}
if (util.isDate(val)) {
val = dateToString(val, timeZone || "local");
} else {
switch (typeof val) {
case 'boolean':
return (val) ? 'true' : 'false';
case 'number':
if (!isFinite(val)) {
val = val.toString();
break;
}
return val + '';
case "object":
return objectToValues(val, timeZone || "local");
case "function":
return val(exports);
}
}
val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
switch(s) {
case "\0": return "\\0";
case "\n": return "\\n";
case "\r": return "\\r";
case "\b": return "\\b";
case "\t": return "\\t";
case "\x1a": return "\\Z";
default: return "\\" + s;
}
});
return "'" + val + "'";
};
function convertIndexRows(rows) {

@@ -327,13 +311,13 @@ var indexes = {};

for (var i = 0; i < rows.length; i++) {
if (rows[i].Key_name == 'PRIMARY') {
if (rows[i].index_name == 'PRIMARY') {
continue;
}
if (!indexes.hasOwnProperty(rows[i].Key_name)) {
indexes[rows[i].Key_name] = {
if (!indexes.hasOwnProperty(rows[i].index_name)) {
indexes[rows[i].index_name] = {
columns : [],
unique : (rows[i].Non_unique == 0)
unique : (rows[i].non_unique == 0)
};
}
indexes[rows[i].Key_name].columns.push(rows[i].Column_name);
indexes[rows[i].index_name].columns.push(rows[i].column_name);
}

@@ -344,24 +328,2 @@

function objectToValues(object, timeZone) {
var values = [];
for (var key in object) {
var value = object[key];
if(typeof value === 'function') {
continue;
}
values.push(exports.escapeId(key) + ' = ' + exports.escapeVal(value, timeZone));
}
return values.join(', ');
}
function arrayToList(array, timeZone) {
return "(" + array.map(function(v) {
if (Array.isArray(v)) return arrayToList(v);
return exports.escapeVal(v, timeZone);
}).join(', ') + ")";
}
function bufferToString(buffer) {

@@ -368,0 +330,0 @@ var hex = '';

@@ -9,15 +9,14 @@ var util = require("util");

exports.hasCollection = function (db, name, cb) {
db.query("SELECT * FROM information_schema.tables WHERE table_name = $1", [ name ], function (err, result) {
exports.hasCollection = function (driver, name, cb) {
driver.execQuery("SELECT * FROM information_schema.tables WHERE table_name = ?", [ name ], function (err, rows) {
if (err) return cb(err);
return cb(null, result.rows.length > 0);
return cb(null, rows.length > 0);
});
};
exports.getCollectionProperties = function (db, name, cb) {
db.query("SELECT * FROM information_schema.columns WHERE table_name = $1", [ name ], function (err, result) {
exports.getCollectionProperties = function (driver, name, cb) {
driver.execQuery("SELECT * FROM information_schema.columns WHERE table_name = ?", [ name ], function (err, cols) {
if (err) return cb(err);
var cols = result.rows;
var columns = {}, m;

@@ -27,23 +26,27 @@

var column = {};
var dCol = cols[i];
if (cols[i].is_nullable.toUpperCase() == "NO") {
if (dCol.is_nullable.toUpperCase() == "NO") {
column.required = true;
}
if (cols[i].column_default !== null) {
m = cols[i].column_default.match(/^'(.+)'::/);
if (dCol.column_default !== null) {
m = dCol.column_default.match(/^'(.+)'::/);
if (m) {
column.defaultValue = m[1];
} else {
column.defaultValue = cols[i].column_default;
column.defaultValue = dCol.column_default;
}
}
switch (cols[i].data_type.toUpperCase()) {
switch (dCol.data_type.toUpperCase()) {
case "SMALLINT":
case "INTEGER":
case "BIGINT":
column.type = "number";
column.rational = false;
if (typeof dCol.column_default == 'string' && dCol.column_default.indexOf('nextval(') == 0) {
column.type = "serial";
} else {
column.type = "integer";
}
for (var k in columnSizes.integer) {
if (columnSizes.integer[k] == cols[i].data_type.toUpperCase()) {
if (columnSizes.integer[k] == dCol.data_type.toUpperCase()) {
column.size = k;

@@ -59,3 +62,3 @@ break;

for (var k in columnSizes.floating) {
if (columnSizes.floating[k] == cols[i].data_type.toUpperCase()) {
if (columnSizes.floating[k] == dCol.data_type.toUpperCase()) {
column.size = k;

@@ -77,10 +80,13 @@ break;

break;
case "TEXT":
column.type = "text";
break;
case "CHARACTER VARYING":
column.type = "text";
if (cols[i].character_maximum_length) {
column.size = cols[i].character_maximum_length;
if (dCol.character_maximum_length) {
column.size = dCol.character_maximum_length;
}
break;
case "USER-DEFINED":
if (cols[i].udt_name.match(/_enum_/)) {
if (dCol.udt_name.match(/_enum_/)) {
column.type = "enum";

@@ -91,34 +97,69 @@ column.values = [];

default:
console.log(cols[i]);
return cb(new Error("Unknown column type '" + cols[i].data_type + "'"));
return cb(new Error("Unknown column type '" + dCol.data_type + "'"));
}
columns[cols[i].column_name] = column;
columns[dCol.column_name] = column;
}
return checkColumnTypes(db, name, columns, cb);
return checkColumnTypes(driver, name, columns, cb);
});
};
exports.createCollection = function (db, name, columns, primary, cb) {
return db.query(SQL.CREATE_TABLE({
exports.createCollection = function (driver, name, columns, keys, cb) {
return driver.execQuery(SQL.CREATE_TABLE({
driver : driver,
name : name,
columns : columns,
primary : primary
}, exports), cb);
keys : keys
}, driver), cb);
};
exports.dropCollection = function (db, name, cb) {
return db.query(SQL.DROP_TABLE({
exports.dropCollection = function (driver, name, cb) {
return driver.execQuery(SQL.DROP_TABLE({
driver : driver,
name : name
}, exports), cb);
}, driver), cb);
};
exports.addCollectionColumn = function (db, name, column, after_column, cb) {
var sql = "ALTER TABLE " + exports.escapeId(name) + " ADD " + column;
exports.addPrimaryKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? ADD CONSTRAINT ?? PRIMARY KEY(??);"
return driver.execQuery(sql, [tableName, tableName + "_" + columnName + "_pk", columnName], cb);
};
return db.query(sql, cb);
exports.dropPrimaryKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? DROP CONSTRAINT ??;"
return driver.execQuery(sql, [tableName, tableName + "_" + columnName + "_pk"], cb);
};
exports.modifyCollectionColumn = function (db, name, column, cb) {
exports.addForeignKey = function(driver, tableName, options, cb){
var sql = "ALTER TABLE ?? ADD FOREIGN KEY(??) REFERENCES ?? (??);"
return driver.execQuery(sql, [tableName, options.name, options.references.table, options.references.column], cb);
};
exports.dropForeignKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? DROP CONSTRAINT ??;";
return driver.execQuery(sql, [tableName, tableName + '_' + columnName + '_fkey'], cb);
};
//exports.renameTable = function(driver, oldCollectionName, newCollectionName, cb) {
// return driver.execQuery(SQL.RENAME_TABLE({
// oldCollectionName : oldCollectionName,
// newCollectionName : newCollectionName
// }, driver), cb);
//}
exports.addCollectionColumn = function (driver, name, column, afterColumn, cb) {
var sql = "ALTER TABLE ?? ADD " + column + ";";
return driver.execQuery(sql, [name] , cb);
};
exports.renameCollectionColumn = function (driver, name, oldColName, newColName, cb) {
var sql = SQL.ALTER_TABLE_RENAME_COLUMN({
name: name, oldColName: oldColName, newColName: newColName
}, driver);
return driver.execQuery(sql , cb);
};
exports.modifyCollectionColumn = function (driver, name, column, cb) {
var p = column.indexOf(" ");

@@ -141,3 +182,3 @@ var col_name = column.substr(0, p);

queue.add(function (next) {
return db.query("ALTER TABLE " + name +
return driver.execQuery("ALTER TABLE " + name +
" ALTER " + col_name +

@@ -150,3 +191,3 @@ " TYPE " + col_type, next);

queue.add(function (next) {
return db.query("ALTER TABLE " + name +
return driver.execQuery("ALTER TABLE " + name +
" ALTER " + col_name +

@@ -157,3 +198,3 @@ " SET NOT NULL", next);

queue.add(function (next) {
return db.query("ALTER TABLE " + name +
return driver.execQuery("ALTER TABLE " + name +
" ALTER " + col_name +

@@ -166,3 +207,3 @@ " DROP NOT NULL", next);

queue.add(function (next) {
return db.query("ALTER TABLE " + name +
return driver.execQuery("ALTER TABLE " + name +
" ALTER " + col_name +

@@ -177,25 +218,27 @@ " SET DEFAULT " + m[1], next);

exports.dropCollectionColumn = function (db, name, column, cb) {
return db.query(SQL.ALTER_TABLE_DROP_COLUMN({
exports.dropCollectionColumn = function (driver, name, column, cb) {
return driver.execQuery(SQL.ALTER_TABLE_DROP_COLUMN({
driver : driver,
name : name,
column : column
}, exports), cb);
}, driver), cb);
};
exports.getCollectionIndexes = function (db, name, cb) {
db.query("SELECT t.relname, i.relname, a.attname, ix.indisunique, ix.indisprimary " +
exports.getCollectionIndexes = function (driver, name, cb) {
driver.execQuery("SELECT t.relname, i.relname, a.attname, ix.indisunique, ix.indisprimary " +
"FROM pg_class t, pg_class i, pg_index ix, pg_attribute a " +
"WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid " +
"AND a.attrelid = t.oid AND a.attnum = ANY(ix.indkey) " +
"AND t.relkind = 'r' AND t.relname = $1",
"AND t.relkind = 'r' AND t.relname = ?",
[ name ],
function (err, result) {
function (err, rows) {
if (err) return cb(err);
return cb(null, convertIndexRows(result.rows));
return cb(null, convertIndexRows(rows));
});
};
exports.addIndex = function (db, name, unique, collection, columns, cb) {
return db.query(SQL.CREATE_INDEX({
exports.addIndex = function (driver, name, unique, collection, columns, cb) {
return driver.execQuery(SQL.CREATE_INDEX({
driver : driver,
name : name,

@@ -205,7 +248,7 @@ unique : unique,

columns : columns
}, exports), cb);
}, driver), cb);
};
exports.removeIndex = function (db, name, collection, cb) {
return db.query("DROP INDEX " + exports.escapeId(name), cb);
exports.removeIndex = function (driver, collection, name, cb) {
return driver.execQuery("DROP INDEX " + driver.query.escapeId(name), cb);
};

@@ -221,6 +264,12 @@

exports.getType = function (collection, name, property) {
exports.getType = function (collection, property, driver) {
var type = false;
var before = false;
var customType = null;
if (property.type == 'number' && property.rational === false) {
property.type = 'integer';
delete property.rational;
}
if (property.serial) {

@@ -233,11 +282,11 @@ type = "SERIAL";

break;
case "integer":
type = columnSizes.integer[property.size || 4];
break;
case "number":
if (property.rational) {
type = columnSizes.floating[property.size || 4];
} else {
type = columnSizes.integer[property.size || 4];
}
type = columnSizes.floating[property.size || 4];
break;
case "serial":
property.serial = true;
property.key = true;
type = "SERIAL";

@@ -260,8 +309,8 @@ break;

case "enum":
type = collection + "_enum_" + name.toLowerCase();
before = function (db, cb) {
var type = collection + "_enum_" + name.toLowerCase();
type = collection + "_enum_" + property.mapsTo.toLowerCase();
before = function (driver, cb) {
var type = collection + "_enum_" + property.mapsTo.toLowerCase();
db.query("SELECT * FROM pg_catalog.pg_type WHERE typname = $1", [ type ], function (err, result) {
if (!err && result.rows.length) {
driver.execQuery("SELECT * FROM pg_catalog.pg_type WHERE typname = ?", [ type ], function (err, rows) {
if (!err && rows.length) {
return cb();

@@ -271,6 +320,6 @@ }

var values = property.values.map(function (val) {
return exports.escapeVal(val);
return driver.query.escapeVal(val);
});
return db.query("CREATE TYPE " + type + " " +
return driver.execQuery("CREATE TYPE " + type + " " +
"AS ENUM (" + values + ")", cb);

@@ -288,2 +337,7 @@ });

break;
default:
customType = driver.customTypes[property.type];
if (customType) {
type = customType.datastoreType()
}
}

@@ -297,3 +351,7 @@

if (property.hasOwnProperty("defaultValue")) {
type += " DEFAULT " + exports.escapeVal(property.defaultValue);
if (property.type == 'date' && property.defaultValue === Date.now ){
type += " DEFAULT now()";
} else {
type += " DEFAULT " + driver.query.escapeVal(property.defaultValue);
}
}

@@ -308,47 +366,2 @@ }

exports.escapeId = function () {
return Array.prototype.slice.apply(arguments).map(function (el) {
return el.split(".").map(function (ele) {
return "\"" + ele.replace(/\"/g, "\"\"") + "\"";
}).join(".");
}).join(".");
};
exports.escapeVal = function (val, timeZone) {
if (val === undefined || val === null) {
return 'NULL';
}
if (Array.isArray(val)) {
if (val.length === 1 && Array.isArray(val[0])) {
return "(" + val[0].map(exports.escapeVal.bind(this)) + ")";
}
return "(" + val.map(exports.escapeVal.bind(this)).join(", ") + ")";
}
if (util.isDate(val)) {
return "'" + dateToString(val, timeZone || "local") + "'";
}
if (Buffer.isBuffer(val)) {
return "'\\x" + val.toString("hex") + "'";
}
switch (typeof val) {
case "number":
if (!isFinite(val)) {
val = val.toString();
break;
}
return val;
case "boolean":
return val ? "true" : "false";
case "function":
return val(exports);
}
// No need to escape backslashes with default PostgreSQL 9.1+ config.
// Google 'postgresql standard_conforming_strings' for details.
return "'" + val.replace(/\'/g, "''") + "'";
};
function convertIndexRows(rows) {

@@ -375,3 +388,3 @@ var indexes = {};

function checkColumnTypes(db, collection, columns, cb) {
function checkColumnTypes(driver, collection, columns, cb) {
var queue = new Queue(function () {

@@ -386,11 +399,11 @@ return cb(null, columns);

db.query("SELECT t.typname, string_agg(e.enumlabel, '|' ORDER BY e.enumsortorder) AS enum_values " +
driver.execQuery("SELECT t.typname, string_agg(e.enumlabel, '|' ORDER BY e.enumsortorder) AS enum_values " +
"FROM pg_catalog.pg_type t JOIN pg_catalog.pg_enum e ON t.oid = e.enumtypid " +
"WHERE t.typname = $1 GROUP BY 1", [ col_name ],
function (err, result) {
"WHERE t.typname = ? GROUP BY 1", [ col_name ],
function (err, rows) {
if (err) {
return next(err);
}
if (result.rows.length) {
col.values = result.rows[0].enum_values.split("|");
if (rows.length) {
col.values = rows[0].enum_values.split("|");
}

@@ -397,0 +410,0 @@

@@ -5,4 +5,4 @@ var Queue = require("../Queue").Queue;

exports.hasCollection = function (db, name, cb) {
db.all("SELECT * FROM sqlite_master " +
exports.hasCollection = function (driver, name, cb) {
driver.execQuery("SELECT * FROM sqlite_master " +
"WHERE type = 'table' and name = ?",

@@ -17,4 +17,24 @@ [ name ],

exports.getCollectionProperties = function (db, name, cb) {
db.all("PRAGMA table_info(" + exports.escapeId(name) + ")", function (err, cols) {
exports.addPrimaryKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? ADD CONSTRAINT ?? PRIMARY KEY(??);";
return driver.execQuery(sql, [tableName, columnName + "PK", columnName], cb);
};
exports.dropPrimaryKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? DROP CONSTRAINT ??;"
return driver.execQuery(sql, [tableName, columnName + "PK"], cb);
};
exports.addForeignKey = function(driver, tableName, options, cb){
var sql = "ALTER TABLE ?? ADD FOREIGN KEY(??) REFERENCES ??(??);";
return driver.execQuery(sql, [tableName, options.name, options.references.table, options.references.column], cb);
};
exports.dropForeignKey = function(driver, tableName, columnName, cb){
var sql = "ALTER TABLE ?? DROP CONSTRAINT ??;"
return driver.execQuery(sql, [tableName, tableName + "_" + columnName + "_fkey"], cb);
};
exports.getCollectionProperties = function (driver, name, cb) {
driver.execQuery("PRAGMA table_info(??)", [name], function (err, cols) {
if (err) return cb(err);

@@ -26,12 +46,13 @@

var column = {};
var dCol = cols[i];
if (cols[i].pk) {
column.primary = true;
if (dCol.pk) {
column.key = true;
}
if (cols[i].notnull) {
if (dCol.notnull) {
column.required = true;
}
if (cols[i].dflt_value) {
m = cols[i].dflt_value.match(/^'(.*)'$/);
if (dCol.dflt_value) {
m = dCol.dflt_value.match(/^'(.*)'$/);
if (m) {

@@ -44,7 +65,16 @@ column.defaultValue = m[1];

switch (cols[i].type.toUpperCase()) {
switch (dCol.type.toUpperCase()) {
case "INTEGER":
column.type = "number";
column.rational = false;
// In sqlite land, integer primary keys are autoincrement by default
// weather you asked for this behaviour or not.
// http://www.sqlite.org/faq.html#q1
if (dCol.pk == 1) {
column.type = "serial";
} else {
column.type = "integer";
}
break;
case "INTEGER UNSIGNED":
column.type = "boolean";
break;
case "REAL":

@@ -66,6 +96,6 @@ column.type = "number";

default:
return cb(new Error("Unknown column type '" + cols[i].Type + "'"));
return cb(new Error("Unknown column type '" + dCol.type + "'"));
}
columns[cols[i].name] = column;
columns[dCol.name] = column;
}

@@ -77,33 +107,40 @@

exports.createCollection = function (db, name, columns, primary, cb) {
return db.all(SQL.CREATE_TABLE({
exports.createCollection = function (driver, name, columns, keys, cb) {
return driver.execQuery(SQL.CREATE_TABLE({
name : name,
columns : columns,
primary : primary
}, exports), cb);
keys : keys
}, driver), cb);
};
exports.dropCollection = function (db, name, cb) {
return db.query(SQL.DROP_TABLE({
exports.dropCollection = function (driver, name, cb) {
return driver.execQuery(SQL.DROP_TABLE({
name : name
}, exports), cb);
}, driver), cb);
};
exports.addCollectionColumn = function (db, name, column, after_column, cb) {
return db.all(SQL.ALTER_TABLE_ADD_COLUMN({
exports.addCollectionColumn = function (driver, name, column, after_column, cb) {
return driver.execQuery(SQL.ALTER_TABLE_ADD_COLUMN({
name : name,
column : column,
after : after_column,
first : !after_column
}, exports), cb);
after : after_column
}, driver), cb);
};
exports.modifyCollectionColumn = function (db, name, column, cb) {
return db.all(SQL.ALTER_TABLE_MODIFY_COLUMN({
exports.renameCollectionColumn = function (driver, name, oldColName, newColName, cb) {
var sql = SQL.ALTER_TABLE_RENAME_COLUMN({
name: name, oldColName: oldColName, newColName: newColName
}, driver);
return driver.execQuery(sql , cb);
};
exports.modifyCollectionColumn = function (driver, name, column, cb) {
return driver.execQuery(SQL.ALTER_TABLE_MODIFY_COLUMN({
name : name,
column : column
}, exports), cb);
}, driver), cb);
};
exports.dropCollectionColumn = function (db, name, column, cb) {
exports.dropCollectionColumn = function (driver, name, column, cb) {
// sqlite does not support dropping columns

@@ -113,4 +150,4 @@ return cb();

exports.getCollectionIndexes = function (db, name, cb) {
db.all("PRAGMA index_list(" + exports.escapeId(name) + ")", function (err, rows) {
exports.getCollectionIndexes = function (driver, name, cb) {
driver.execQuery("PRAGMA index_list(" + driver.query.escapeId(name) + ")", function (err, rows) {
if (err) return cb(err);

@@ -129,3 +166,3 @@

queue.add(k, function (k, next) {
db.all("PRAGMA index_info(" + exports.escapeVal(k) + ")", function (err, rows) {
driver.execQuery("PRAGMA index_info(" + driver.query.escapeVal(k) + ")", function (err, rows) {
if (err) return next(err);

@@ -146,4 +183,4 @@

exports.addIndex = function (db, name, unique, collection, columns, cb) {
return db.all(SQL.CREATE_INDEX({
exports.addIndex = function (driver, name, unique, collection, columns, cb) {
return driver.execQuery(SQL.CREATE_INDEX({
name : name,

@@ -153,15 +190,15 @@ unique : unique,

columns : columns
}, exports), cb);
}, driver), cb);
};
exports.removeIndex = function (db, name, collection, cb) {
return db.all("DROP INDEX IF EXISTS " + exports.escapeId(name), cb);
exports.removeIndex = function (driver, name, collection, cb) {
return driver.execQuery("DROP INDEX IF EXISTS " + driver.query.escapeId(name), cb);
};
exports.checkPrimary = function (primary) {
if (primary.length === 1) {
exports.processKeys = function (keys) {
if (keys.length === 1) {
return [];
}
return primary;
return keys;
};

@@ -178,5 +215,11 @@

exports.getType = function (collection, name, property) {
var type = false;
exports.getType = function (collection, property, driver) {
var type = false;
var customType = null;
if (property.type == 'number' && property.rational === false) {
property.type = 'integer';
delete property.rational;
}
switch (property.type) {

@@ -186,16 +229,15 @@ case "text":

break;
case "integer":
type = "INTEGER";
break;
case "number":
if (property.rational) {
type = "REAL";
} else {
type = "INTEGER";
}
type = "REAL";
break;
case "serial":
property.serial = true;
property.primary = true;
property.key = true;
type = "INTEGER";
break;
case "boolean":
type = "INTEGER";
type = "INTEGER UNSIGNED";
break;

@@ -215,2 +257,7 @@ case "date":

break;
default:
customType = driver.customTypes[property.type];
if (customType) {
type = customType.datastoreType()
}
}

@@ -223,3 +270,3 @@

}
if (property.primary) {
if (property.key) {
if (!property.required) {

@@ -234,3 +281,3 @@ // append if not set

if (property.serial) {
if (!property.primary) {
if (!property.key) {
type += " PRIMARY KEY";

@@ -241,3 +288,3 @@ }

if (property.hasOwnProperty("defaultValue")) {
type += " DEFAULT " + exports.escapeVal(property.defaultValue);
type += " DEFAULT " + driver.query.escapeVal(property.defaultValue);
}

@@ -251,46 +298,2 @@

exports.escapeId = function () {
return Array.prototype.slice.apply(arguments).map(function (el) {
return "`" + el.replace(/`/g, '``') + "`";
}).join(".");
};
exports.escapeVal = function (val, timeZone) {
if (val === undefined || val === null) {
return 'NULL';
}
if (Array.isArray(val)) {
if (val.length === 1 && Array.isArray(val[0])) {
return "(" + val[0].map(exports.escapeVal.bind(this)) + ")";
}
return "(" + val.map(exports.escapeVal.bind(this)).join(", ") + ")";
}
if (util.isDate(val)) {
return "'" + dateToString(val, timeZone || "local") + "'";
}
if (Buffer.isBuffer(val)) {
return "X'" + val.toString("hex") + "'";
}
switch (typeof val) {
case "number":
if (!isFinite(val)) {
val = val.toString();
break;
}
return val;
case "boolean":
return val ? 1 : 0;
case "function":
return val(exports);
}
// No need to escape backslashes with default PostgreSQL 9.1+ config.
// Google 'postgresql standard_conforming_strings' for details.
return "'" + val.replace(/\'/g, "''") + "'";
};
function convertIndexRows(rows) {

@@ -297,0 +300,0 @@ var indexes = {};

@@ -1,7 +0,7 @@

exports.CREATE_TABLE = function (options, dialect) {
var sql = "CREATE TABLE " + dialect.escapeId(options.name) + " (" + options.columns.join(", ");
exports.CREATE_TABLE = function (options, driver) {
var sql = "CREATE TABLE " + driver.query.escapeId(options.name) + " (" + options.columns.join(", ");
if (options.primary && options.primary.length > 0) {
sql += ", PRIMARY KEY (" + options.primary.map(function (val) {
return dialect.escapeId(val);
if (options.keys && options.keys.length > 0) {
sql += ", PRIMARY KEY (" + options.keys.map(function (val) {
return driver.query.escapeId(val);
}).join(", ") + ")";

@@ -15,4 +15,4 @@ }

exports.DROP_TABLE = function (options, dialect) {
var sql = "DROP TABLE " + dialect.escapeId(options.name);
exports.DROP_TABLE = function (options, driver) {
var sql = "DROP TABLE " + driver.query.escapeId(options.name);

@@ -22,8 +22,8 @@ return sql;

exports.ALTER_TABLE_ADD_COLUMN = function (options, dialect) {
var sql = "ALTER TABLE " + dialect.escapeId(options.name) +
exports.ALTER_TABLE_ADD_COLUMN = function (options, driver) {
var sql = "ALTER TABLE " + driver.query.escapeId(options.name) +
" ADD " + options.column;
if (options.after) {
sql += " AFTER " + dialect.escapeId(options.after);
sql += " AFTER " + driver.query.escapeId(options.after);
} else if (options.first) {

@@ -36,4 +36,12 @@ sql += " FIRST";

exports.ALTER_TABLE_MODIFY_COLUMN = function (options, dialect) {
var sql = "ALTER TABLE " + dialect.escapeId(options.name) +
exports.ALTER_TABLE_RENAME_COLUMN = function (opts, driver) {
var eid = driver.query.escapeId;
var sql = "ALTER TABLE " + eid(opts.name) +
" RENAME COLUMN " + eid(opts.oldColName) + " TO " + eid(opts.newColName);
return sql;
}
exports.ALTER_TABLE_MODIFY_COLUMN = function (options, driver) {
var sql = "ALTER TABLE " + driver.query.escapeId(options.name) +
" MODIFY " + options.column;

@@ -44,5 +52,5 @@

exports.ALTER_TABLE_DROP_COLUMN = function (options, dialect) {
var sql = "ALTER TABLE " + dialect.escapeId(options.name) +
" DROP " + dialect.escapeId(options.column);
exports.ALTER_TABLE_DROP_COLUMN = function (options, driver) {
var sql = "ALTER TABLE " + driver.query.escapeId(options.name) +
" DROP " + driver.query.escapeId(options.column);

@@ -52,6 +60,6 @@ return sql;

exports.CREATE_INDEX = function (options, dialect) {
var sql = "CREATE" + (options.unique ? " UNIQUE" : "") + " INDEX " + dialect.escapeId(options.name) +
" ON " + dialect.escapeId(options.collection) +
" (" + options.columns.map(function (col) { return dialect.escapeId(col); }) + ")";
exports.CREATE_INDEX = function (options, driver) {
var sql = "CREATE" + (options.unique ? " UNIQUE" : "") + " INDEX " + driver.query.escapeId(options.name) +
" ON " + driver.query.escapeId(options.collection) +
" (" + options.columns.map(function (col) { return driver.query.escapeId(col); }) + ")";

@@ -61,7 +69,11 @@ return sql;

exports.DROP_INDEX = function (options, dialect) {
var sql = "DROP INDEX " + dialect.escapeId(options.name) +
" ON " + dialect.escapeId(options.collection);
exports.DROP_INDEX = function (options, driver) {
var sql = "DROP INDEX " + driver.query.escapeId(options.name) +
" ON " + driver.query.escapeId(options.collection);
return sql;
};
//exports.RENAME_TABLE = function(options, driver) {
// var sql = "ALTER TABLE " + options.oldCollectionName + " RENAME TO " + options.newCollectionName + " ;";
//}

@@ -8,5 +8,6 @@ var Queue = require("./Queue").Queue;

function Sync(options) {
var Dialect = require("./Dialects/" + options.dialect);
var debug = options.debug || noOp;
var db = options.db;
var driver = options.driver;
var Dialect = require("./Dialects/" + driver.dialect);
var suppressColumnDrop = options.suppressColumnDrop;
var collections = [];

@@ -17,3 +18,3 @@ var types = {};

var processCollection = function (collection, cb) {
Dialect.hasCollection(db, collection.name, function (err, has) {
Dialect.hasCollection(driver, collection.name, function (err, has) {
if (err) {

@@ -24,6 +25,13 @@ return cb(err);

if (!has) {
return createCollection(collection, cb);
return createCollection(collection, function (err) {
if (err) return cb(err);
return cb(null, true);
});
} else {
return cb(null, false);
}
Dialect.getCollectionProperties(db, collection.name, function (err, columns) {
// I have concerns about the data integrity of the automatic sync process.
// There has been lots of bugs and issues associated with it.
/*Dialect.getCollectionProperties(driver, collection.name, function (err, columns) {
if (err) {

@@ -34,3 +42,3 @@ return cb(err);

return syncCollection(collection, columns, cb);
});
});*/
});

@@ -41,7 +49,8 @@ };

var columns = [];
var primary = [];
var keys = [];
var before = [];
var nextBefore = function () {
if (before.length === 0) {
return Dialect.createCollection(db, collection.name, columns, primary, function () {
return Dialect.createCollection(driver, collection.name, columns, keys, function (err) {
if (err) return cb(err);
return syncIndexes(collection.name, getCollectionIndexes(collection), cb);

@@ -53,3 +62,3 @@ });

next(db, function (err) {
next(driver, function (err) {
if (err) {

@@ -64,4 +73,9 @@ return cb(err);

for (var k in collection.properties) {
var col = createColumn(collection.name, k, collection.properties[k]);
var prop, col;
prop = collection.properties[k];
prop.mapsTo = prop.mapsTo || k;
col = createColumn(collection.name, prop);
if (col === false) {

@@ -71,4 +85,4 @@ return cb(new Error("Unknown type for property '" + k + "'"));

if (collection.properties[k].primary) {
primary.push(k);
if (prop.key) {
keys.push(prop.mapsTo);
}

@@ -85,4 +99,4 @@

if (typeof Dialect.checkPrimary == "function") {
primary = Dialect.checkPrimary(primary);
if (typeof Dialect.processKeys == "function") {
keys = Dialect.processKeys(keys);
}

@@ -95,7 +109,11 @@

var createColumn = function (collection, name, property) {
var type = types.hasOwnProperty(property.type)
? types[property.type].datastoreType(property)
: Dialect.getType(collection, name, property);
var createColumn = function (collection, prop) {
var type;
if (types.hasOwnProperty(prop.type)) {
type = types[prop.type].datastoreType(prop);
} else {
type = Dialect.getType(collection, prop, driver);
}
if (type === false) {

@@ -108,4 +126,8 @@ return false;

if (prop.mapsTo === undefined) {
console.log("undefined prop.mapsTo", prop, (new Error()).stack)
}
return {
value : Dialect.escapeId(name) + " " + type.value,
value : driver.query.escapeId(prop.mapsTo) + " " + type.value,
before : type.before

@@ -123,3 +145,3 @@ };

if (!columns.hasOwnProperty(k)) {
var col = createColumn(collection.name, k, collection.properties[k]);
var col = createColumn(collection.name, collection.properties[k]);

@@ -136,7 +158,7 @@ if (col === false) {

queue.add(col, function (col, next) {
col.before(db, function (err) {
col.before(driver, function (err) {
if (err) {
return next(err);
}
return Dialect.addCollectionColumn(db, collection.name, col.value, last_k, next);
return Dialect.addCollectionColumn(driver, collection.name, col.value, last_k, next);
});

@@ -146,3 +168,3 @@ });

queue.add(function (next) {
return Dialect.addCollectionColumn(db, collection.name, col.value, last_k, next);
return Dialect.addCollectionColumn(driver, collection.name, col.value, last_k, next);
});

@@ -163,7 +185,7 @@ }

queue.add(col, function (col, next) {
col.before(db, function (err) {
col.before(driver, function (err) {
if (err) {
return next(err);
}
return Dialect.modifyCollectionColumn(db, collection.name, col.value, next);
return Dialect.modifyCollectionColumn(driver, collection.name, col.value, next);
});

@@ -173,3 +195,3 @@ });

queue.add(function (next) {
return Dialect.modifyCollectionColumn(db, collection.name, col.value, next);
return Dialect.modifyCollectionColumn(driver, collection.name, col.value, next);
});

@@ -182,13 +204,15 @@ }

for (var k in columns) {
if (!collection.properties.hasOwnProperty(k)) {
queue.add(function (next) {
debug("Dropping column " + collection.name + "." + k);
if ( !suppressColumnDrop ) {
for (var k in columns) {
if (!collection.properties.hasOwnProperty(k)) {
queue.add(function (next) {
debug("Dropping column " + collection.name + "." + k);
total_changes += 1;
total_changes += 1;
return Dialect.dropCollectionColumn(db, collection.name, k, next);
});
}
}
return Dialect.dropCollectionColumn(driver, collection.name, k, next);
});
}
}
}

@@ -206,16 +230,28 @@ var indexes = getCollectionIndexes(collection);

var getIndexName = function (collection, prop) {
var post = prop.unique ? 'unique' : 'index';
if (driver.dialect == 'sqlite') {
return collection.name + '_' + prop.name + '_' + post;
} else {
return prop.name + '_' + post;
}
};
var getCollectionIndexes = function (collection) {
var indexes = [];
var found;
var found, prop;
for (var k in collection.properties) {
if (collection.properties[k].unique) {
if (!Array.isArray(collection.properties[k].unique)) {
collection.properties[k].unique = [ collection.properties[k].unique ];
prop = collection.properties[k];
if (prop.unique) {
if (!Array.isArray(prop.unique)) {
prop.unique = [ prop.unique ];
}
for (var i = 0; i < collection.properties[k].unique.length; i++) {
if (collection.properties[k].unique[i] === true) {
for (var i = 0; i < prop.unique.length; i++) {
if (prop.unique[i] === true) {
indexes.push({
name : k + "_unique",
name : getIndexName(collection, prop),
unique : true,

@@ -228,3 +264,3 @@ columns : [ k ]

for (var j = 0; j < indexes.length; j++) {
if (indexes[j].name == collection.properties[k].unique[i]) {
if (indexes[j].name == prop.unique[i]) {
found = true;

@@ -237,3 +273,3 @@ indexes[j].columns.push(k);

indexes.push({
name : collection.properties[k].unique[i],
name : prop.unique[i],
unique : true,

@@ -246,11 +282,11 @@ columns : [ k ]

}
if (collection.properties[k].index) {
if (!Array.isArray(collection.properties[k].index)) {
collection.properties[k].index = [ collection.properties[k].index ];
if (prop.index) {
if (!Array.isArray(prop.index)) {
prop.index = [ prop.index ];
}
for (var i = 0; i < collection.properties[k].index.length; i++) {
if (collection.properties[k].index[i] === true) {
for (var i = 0; i < prop.index.length; i++) {
if (prop.index[i] === true) {
indexes.push({
name : k + "_index",
name : getIndexName(collection, prop),
columns : [ k ]

@@ -262,3 +298,3 @@ });

for (var j = 0; j < indexes.length; j++) {
if (indexes[j].name == collection.properties[k].index[i]) {
if (indexes[j].name == prop.index[i]) {
found = true;

@@ -271,3 +307,3 @@ indexes[j].columns.push(k);

indexes.push({
name : collection.properties[k].index[i],
name : prop.index[i],
columns : [ k ]

@@ -289,3 +325,5 @@ });

var syncIndexes = function (name, indexes, cb) {
Dialect.getCollectionIndexes(db, name, function (err, db_indexes) {
if (indexes.length == 0) return cb(null);
Dialect.getCollectionIndexes(driver, name, function (err, db_indexes) {
if (err) return cb(err);

@@ -302,3 +340,3 @@

queue.add(indexes[i], function (index, next) {
return Dialect.addIndex(db, index.name, index.unique, name, index.columns, next);
return Dialect.addIndex(driver, index.name, index.unique, name, index.columns, next);
});

@@ -312,6 +350,6 @@ continue;

queue.add(indexes[i], function (index, next) {
return Dialect.removeIndex(db, index.name, name, next);
return Dialect.removeIndex(driver, index.name, name, next);
});
queue.add(indexes[i], function (index, next) {
return Dialect.addIndex(db, index.name, index.unique, name, index.columns, next);
return Dialect.addIndex(driver, index.name, index.unique, name, index.columns, next);
});

@@ -328,3 +366,3 @@ }

queue.add(i, function (index, next) {
return Dialect.removeIndex(db, index, name, next);
return Dialect.removeIndex(driver, index, name, next);
});

@@ -352,3 +390,3 @@ }

}
if (property.required != column.required && !property.primary) {
if (property.required != column.required && !property.key) {
return true;

@@ -359,9 +397,6 @@ }

}
if (property.type == "number") {
if (property.type == "number" || property.type == "integer") {
if (column.hasOwnProperty("size") && (property.size || 4) != column.size) {
return true;
}
if (property.hasOwnProperty("rational") && property.rational != column.rational) {
return true;
}
}

@@ -368,0 +403,0 @@ if (property.type == "enum" && column.type == "enum") {

@@ -6,3 +6,3 @@ {

"keywords" : [ "sql", "ddl", "sync", "mysql", "postgres", "sqlite" ],
"version" : "0.1.4",
"version" : "0.3.11",
"license" : "MIT",

@@ -20,4 +20,5 @@ "repository" : "http://github.com/dresende/node-sql-ddl-sync.git",

"should" : "2.0.2",
"commander" : "~2.0.0"
"commander" : "~2.0.0",
"orm" : "2.1.23"
}
}

@@ -20,9 +20,9 @@ ## NodeJS SQL DDL Synchronization

This module is used by [ORM](http://dresende.github.com/node-orm2) to synchronize model tables in the different supported
dialects. Sorry there is no API documentation for now but there are a couple of tests you can read and find out how to use
it if you want.
This module is part of [ORM](http://dresende.github.com/node-orm2). It's used synchronize model tables in supported dialects.
Sorry there is no API documentation for now but there are a couple of tests you can read and find out how to use it if you want.
## Example
Install module and install `mysql`, create a file with the contents below and change line 2 to match valid credentials.
Install `orm` & the required driver (eg: `mysql`).
Create a file with the contents below and change insert your database credentials.
Run once and you'll see table `ddl_sync_test` appear in your database. Then make some changes to it (add/drop/change columns)

@@ -32,38 +32,42 @@ and run the code again. Your table should always return to the same structure.

```js
var mysql = require("mysql");
var db = mysql.createConnection("mysql://username:password@localhost/database");
var orm = require("orm");
var mysql = require("mysql");
var Sync = require("sql-ddl-sync").Sync;
var Sync = require("sql-ddl-sync").Sync;
var sync = new Sync({
dialect : "mysql",
db : db,
debug : function (text) {
console.log("> %s", text);
}
});
orm.connect("mysql://username:password@localhost/database", function (err, db) {
if (err) throw err;
var driver = db.driver;
sync.defineCollection("ddl_sync_test", {
id : { type : "number", primary: true, serial: true },
name : { type : "text", required: true },
age : { type : "number", rational: true },
male : { type : "boolean" },
born : { type : "date", time: true },
born2 : { type : "date" },
int2 : { type : "number", size: 2 },
int4 : { type : "number", size: 4 },
int8 : { type : "number", size: 8 },
float4 : { type : "number", rational: true, size: 4 },
float8 : { type : "number", rational: true, size: 8 },
type : { type : "enum", values: [ 'dog', 'cat'], defaultValue: 'dog', required: true },
photo : { type : "binary" }
});
var sync = new Sync({
dialect : "mysql",
driver : driver,
debug : function (text) {
console.log("> %s", text);
}
});
sync.sync(function (err) {
if (err) {
console.log("> Sync Error");
console.log(err);
} else {
console.log("> Sync Done");
}
process.exit(0);
sync.defineCollection("ddl_sync_test", {
id : { type: "serial", key: true, serial: true },
name : { type: "text", required: true },
age : { type: "integer" },
male : { type: "boolean" },
born : { type: "date", time: true },
born2 : { type: "date" },
int2 : { type: "integer", size: 2 },
int4 : { type: "integer", size: 4 },
int8 : { type: "integer", size: 8 },
float4 : { type: "number", size: 4 },
float8 : { type: "number", size: 8 },
photo : { type: "binary" }
});
sync.sync(function (err) {
if (err) {
console.log("> Sync Error");
console.log(err);
} else {
console.log("> Sync Done");
}
process.exit(0);
});
});

@@ -70,0 +74,0 @@

exports.dialect = null;
exports.table = "sql_ddl_sync_test_table";
exports.fakeDialect = {
escapeId : function (id) {
return "$$" + id + "$$";
exports.fakeDriver = {
query: {
escapeId : function (id) {
return "$$" + id + "$$";
},
escapeVal : function (val) {
return "^^" + val + "^^";
}
},
customTypes: {
json: {
datastoreType: function (prop) {
return 'JSON';
}
}
}

@@ -12,7 +24,6 @@ };

return function (done) {
switch (exports.dialect) {
switch (exports.driver.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 exports.driver.execQuery("ALTER TABLE ?? DROP ??", [ exports.table, column ], done);
}

@@ -25,9 +36,9 @@ return done(unknownProtocol());

return function (done) {
switch (exports.dialect) {
switch (exports.driver.dialect) {
case "mysql":
return exports.db.query("ALTER TABLE ?? ADD ?? INTEGER NOT NULL", [ exports.table, column ], done);
return exports.driver.execQuery("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 exports.driver.execQuery("ALTER TABLE " + exports.table + " ADD " + column + " INTEGER NOT NULL", done);
case "sqlite":
return exports.db.all("ALTER TABLE " + exports.table + " ADD " + column + " INTEGER", done);
return exports.driver.execQuery("ALTER TABLE " + exports.table + " ADD " + column + " INTEGER", done);
}

@@ -40,9 +51,9 @@ return done(unknownProtocol());

return function (done) {
switch (exports.dialect) {
switch (exports.driver.dialect) {
case "mysql":
return exports.db.query("ALTER TABLE ?? MODIFY ?? INTEGER NOT NULL", [ exports.table, column ], done);
return exports.driver.execQuery("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 exports.driver.execQuery("ALTER TABLE " + exports.table + " ALTER " + column + " TYPE DOUBLE PRECISION", done);
case "sqlite":
return exports.db.all("ALTER TABLE " + exports.table + " MODIFY " + column + " INTEGER NOT NULL", done);
return exports.driver.execQuery("ALTER TABLE " + exports.table + " MODIFY " + column + " INTEGER NOT NULL", done);
}

@@ -55,9 +66,9 @@ return done(unknownProtocol());

return function (done) {
switch (exports.dialect) {
switch (exports.driver.dialect) {
case "mysql":
return exports.db.query("CREATE " + (unique ? "UNIQUE" : "") + " INDEX ?? ON ?? (??)", [ name, exports.table, column ], done);
return exports.driver.execQuery("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 exports.driver.execQuery("CREATE " + (unique ? "UNIQUE" : "") + " INDEX " + exports.table + "_" + name + " ON " + exports.table + " (" + column + ")", done);
case "sqlite":
return exports.db.all("CREATE " + (unique ? "UNIQUE" : "") + " INDEX " + name + " ON " + exports.table + " (" + column + ")", done);
return exports.driver.execQuery("CREATE " + (unique ? "UNIQUE" : "") + " INDEX " + name + " ON " + exports.table + " (" + column + ")", done);
}

@@ -70,9 +81,9 @@ return done(unknownProtocol());

return function (done) {
switch (exports.dialect) {
switch (exports.driver.dialect) {
case "mysql":
return exports.db.query("DROP INDEX ?? ON ??", [ name, exports.table ], done);
return exports.driver.execQuery("DROP INDEX ?? ON ??", [ name, exports.table ], done);
case "postgresql":
return exports.db.query("DROP INDEX " + exports.table + "_" + name, done);
return exports.driver.execQuery("DROP INDEX " + exports.table + "_" + name, done);
case "sqlite":
return exports.db.all("DROP INDEX " + name, done);
return exports.driver.execQuery("DROP INDEX " + name, done);
}

@@ -83,4 +94,10 @@ return done(unknownProtocol());

exports.dropTable = function (name) {
return function (done) {
exports.driver.execQuery("DROP TABLE IF EXISTS ??", [exports.table], done);
};
}
function unknownProtocol() {
return new Error("Unknown protocol - " + exports.dialect);
return new Error("Unknown protocol - " + exports.driver.dialect);
}

@@ -5,6 +5,5 @@ var Sync = require("../../lib/Sync").Sync;

var sync = new Sync({
dialect : common.dialect,
db : common.db,
driver : common.driver,
debug : function (text) {
// console.log("> %s", text);
//console.log("> %s", text);
}

@@ -14,48 +13,27 @@ });

sync.defineCollection(common.table, {
id : { type: "number", primary: true, serial: true },
name : { type: "text", required: true, defaultValue: 'John' },
age : { type: "number", rational: true },
male : { type: "boolean" },
dttm : { type: "date", time: true, index: true },
dt : { type: "date" },
int2 : { type: "number", size: 2, index: [ "idx1", "idx2" ] },
int4 : { type: "number", size: 4 },
int8 : { type: "number", size: 8, index: [ "idx2" ] },
float4 : { type: "number", rational: true, size: 4 },
float8 : { type: "number", rational: true, size: 8 },
enm : { type: "enum", values: [ 'dog', 'cat'], defaultValue: 'dog', required: true },
binry : { type: "binary" }
id : { type: "serial", key: true, serial: true },
name : { type: "text", required: true },
age : { type: "integer" },
male : { type: "boolean" },
born : { type: "date", time: true },
born2 : { type: "date" },
int2 : { type: "integer", size: 2 },
int4 : { type: "integer", size: 4 },
int8 : { type: "integer", size: 8 },
float4 : { type: "number", size: 4 },
float8 : { type: "number", size: 8 },
photo : { type: "binary" }
});
describe("Synching", function () {
it("should create the table", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes");
// These will fail because autosync has been disabled pending data integrity concerns.
return done();
});
});
describe("db", function () {
before(common.dropTable());
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
return done();
});
});
});
if (common.dialect != "sqlite") {
describe("Dropping a column", function () {
before(common.dropColumn('dt'));
it("should recreate it on first call", function (done) {
describe("Synching", function () {
it("should create the table", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
info.should.have.property("changes");

@@ -77,10 +55,84 @@ return done();

describe("Dropping a column that has an index", function () {
before(common.dropColumn('dttm'));
if (common.dialect != "sqlite") {
describe("Dropping a column", function () {
before(common.dropColumn('born'));
it("should recreate column and index on first call", function (done) {
xit("should recreate it on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
return done();
});
});
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
return done();
});
});
});
xdescribe("Dropping a column that has an index", function () {
before(common.dropColumn('born2'));
it("should recreate column and index on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 2);
return done();
});
});
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
return done();
});
});
});
xdescribe("Adding a column", function () {
before(common.addColumn('unknown_col'));
it("should drop column on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
return done();
});
});
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
return done();
});
});
});
}
xdescribe("Changing a column", function () {
before(common.changeColumn('int4'));
it("should update column on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 2);
info.should.have.property("changes", 1);

@@ -102,6 +154,6 @@ return done();

describe("Adding a column", function () {
before(common.addColumn('unknown_col'));
xdescribe("Adding an index", function () {
before(common.addIndex('xpto', 'int4'));
it("should drop column on first call", function (done) {
it("should drop index on first call", function (done) {
sync.sync(function (err, info) {

@@ -126,102 +178,54 @@ should.not.exist(err);

});
}
describe("Changing a column", function () {
before(common.changeColumn('int4'));
xdescribe("Dropping an index", function () {
before(common.dropIndex('idx2'));
it("should update column on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
it("should drop index on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
return done();
return done();
});
});
});
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
return done();
return done();
});
});
});
});
describe("Adding an index", function () {
before(common.addIndex('xpto', 'dt'));
it("should drop index on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
return done();
xdescribe("Changing index to unique index", function () {
before(function (done) {
common.dropIndex('float8_index')(function () {
common.addIndex('float8_index', 'float8', true)(done);
});
});
});
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
it("should drop index and recreate it on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
return done();
return done();
});
});
});
});
describe("Dropping an index", function () {
before(common.dropIndex('idx2'));
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
it("should drop index on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
return done();
return done();
});
});
});
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
return done();
});
});
});
describe("Changing index to unique index", function () {
before(function (done) {
common.dropIndex('dttm_index')(function () {
common.addIndex('dttm_index', 'dttm', true)(done);
});
});
it("should drop index and recreate it on first call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 1);
return done();
});
});
it("should have no changes on second call", function (done) {
sync.sync(function (err, info) {
should.not.exist(err);
should.exist(info);
info.should.have.property("changes", 0);
return done();
});
});
});

@@ -0,11 +1,11 @@

var should = require("should");
var common = require("../common");
var Dialect = require("../../lib/Dialects/mysql");
var driver = common.fakeDriver;
var should = require("should");
describe("MySQL.getType", function () {
it("should detect text", function (done) {
Dialect.getType(null, null, { type: "text" }).value.should.equal("VARCHAR(255)");
Dialect.getType(null, null, { type: "text", size: 150 }).value.should.equal("VARCHAR(150)");
Dialect.getType(null, null, { type: "text", size: 1000 }).value.should.equal("VARCHAR(1000)");
Dialect.getType(null, { mapsTo: 'abc', type: "text" }, driver).value.should.equal("VARCHAR(255)");
Dialect.getType(null, { mapsTo: 'abc', type: "text", size: 150 }, driver).value.should.equal("VARCHAR(150)");
Dialect.getType(null, { mapsTo: 'abc', type: "text", size: 1000 }, driver).value.should.equal("VARCHAR(1000)");

@@ -16,6 +16,7 @@ return done();

it("should detect numbers", function (done) {
Dialect.getType(null, null, { type: "number" }).value.should.equal("INTEGER");
Dialect.getType(null, null, { type: "number", size: 4 }).value.should.equal("INTEGER");
Dialect.getType(null, null, { type: "number", size: 2 }).value.should.equal("SMALLINT");
Dialect.getType(null, null, { type: "number", size: 8 }).value.should.equal("BIGINT");
Dialect.getType(null, { mapsTo: 'abc', type: "integer" }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 4 }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 2 }, driver).value.should.equal("SMALLINT");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 8 }, driver).value.should.equal("BIGINT");
Dialect.getType(null, { mapsTo: 'abc', type: "number", rational: false }, driver).value.should.equal("INTEGER");

@@ -26,5 +27,5 @@ return done();

it("should detect rational numbers", function (done) {
Dialect.getType(null, null, { type: "number", rational: true }).value.should.equal("FLOAT");
Dialect.getType(null, null, { type: "number", rational: true, size: 4 }).value.should.equal("FLOAT");
Dialect.getType(null, null, { type: "number", rational: true, size: 8 }).value.should.equal("DOUBLE");
Dialect.getType(null, { mapsTo: 'abc', type: "number"}, driver).value.should.equal("FLOAT");
Dialect.getType(null, { mapsTo: 'abc', type: "number", size: 4 }, driver).value.should.equal("FLOAT");
Dialect.getType(null, { mapsTo: 'abc', type: "number", size: 8 }, driver).value.should.equal("DOUBLE");

@@ -35,3 +36,3 @@ return done();

it("should detect booleans", function (done) {
Dialect.getType(null, null, { type: "boolean" }).value.should.equal("TINYINT(1)");
Dialect.getType(null, { mapsTo: 'abc', type: "boolean" }, driver).value.should.equal("TINYINT(1)");

@@ -42,3 +43,3 @@ return done();

it("should detect dates", function (done) {
Dialect.getType(null, null, { type: "date" }).value.should.equal("DATE");
Dialect.getType(null, { mapsTo: 'abc', type: "date" }, driver).value.should.equal("DATE");

@@ -49,3 +50,3 @@ return done();

it("should detect dates with times", function (done) {
Dialect.getType(null, null, { type: "date", time: true }).value.should.equal("DATETIME");
Dialect.getType(null, { mapsTo: 'abc', type: "date", time: true }, driver).value.should.equal("DATETIME");

@@ -56,3 +57,3 @@ return done();

it("should detect binary", function (done) {
Dialect.getType(null, null, { type: "binary" }).value.should.equal("BLOB");
Dialect.getType(null, { mapsTo: 'abc', type: "binary" }, driver).value.should.equal("BLOB");

@@ -63,3 +64,3 @@ return done();

it("should detect big binary", function (done) {
Dialect.getType(null, null, { type: "binary", big: true }).value.should.equal("LONGBLOB");
Dialect.getType(null, { mapsTo: 'abc', type: "binary", big: true }, driver).value.should.equal("LONGBLOB");

@@ -69,4 +70,10 @@ return done();

it("should detect custom types", function (done) {
Dialect.getType(null, { mapsTo: 'abc', type: "json" }, driver).value.should.equal("JSON");
return done();
});
it("should detect required items", function (done) {
Dialect.getType(null, null, { type: "boolean", required: true }).value.should.match(/NOT NULL/);
Dialect.getType(null, { mapsTo: 'abc', type: "boolean", required: true }, driver).value.should.match(/NOT NULL/);

@@ -77,3 +84,3 @@ return done();

it("should detect default values", function (done) {
Dialect.getType(null, null, { type: "number", defaultValue: 3 }).value.should.match(/DEFAULT 3/);
Dialect.getType(null, { mapsTo: 'abc', type: "number", defaultValue: 3 }, driver).value.should.match(/DEFAULT \^\^3\^\^/);

@@ -84,6 +91,3 @@ return done();

it("should detect serial", function (done) {
var column = Dialect.getType(null, null, {
type : "number",
serial : true
}).value;
var column = Dialect.getType(null, { mapsTo: 'abc', type: "serial" }).value;

@@ -97,11 +101,1 @@ column.should.match(/INT/);

});
describe("MySQL.escapeId", function () {
it("should correctly escape identifiers", function (done) {
Dialect.escapeId("my_id").should.equal("`my_id`");
Dialect.escapeId("my_`id").should.equal("`my_``id`");
Dialect.escapeId("my_id", "sub").should.equal("`my_id`.`sub`");
return done();
});
});

@@ -0,11 +1,11 @@

var should = require("should");
var common = require("../common");
var Dialect = require("../../lib/Dialects/postgresql");
var driver = common.fakeDriver;
var should = require("should");
describe("PostgreSQL.getType", function () {
it("should detect text", function (done) {
Dialect.getType(null, null, { type: "text" }).value.should.equal("TEXT");
Dialect.getType(null, null, { type: "text", size: 150 }).value.should.equal("TEXT");
Dialect.getType(null, null, { type: "text", size: 1000 }).value.should.equal("TEXT");
Dialect.getType(null, { mapsTo: 'abc', type: "text" }, driver).value.should.equal("TEXT");
Dialect.getType(null, { mapsTo: 'abc', type: "text", size: 150 }, driver).value.should.equal("TEXT");
Dialect.getType(null, { mapsTo: 'abc', type: "text", size: 1000 }, driver).value.should.equal("TEXT");

@@ -16,6 +16,7 @@ return done();

it("should detect numbers", function (done) {
Dialect.getType(null, null, { type: "number" }).value.should.equal("INTEGER");
Dialect.getType(null, null, { type: "number", size: 4 }).value.should.equal("INTEGER");
Dialect.getType(null, null, { type: "number", size: 2 }).value.should.equal("SMALLINT");
Dialect.getType(null, null, { type: "number", size: 8 }).value.should.equal("BIGINT");
Dialect.getType(null, { mapsTo: 'abc', type: "integer" }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 4 }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 2 }, driver).value.should.equal("SMALLINT");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 8 }, driver).value.should.equal("BIGINT");
Dialect.getType(null, { mapsTo: 'abc', type: "number", rational: false }, driver).value.should.equal("INTEGER");

@@ -26,5 +27,5 @@ return done();

it("should detect rational numbers", function (done) {
Dialect.getType(null, null, { type: "number", rational: true }).value.should.equal("REAL");
Dialect.getType(null, null, { type: "number", rational: true, size: 4 }).value.should.equal("REAL");
Dialect.getType(null, null, { type: "number", rational: true, size: 8 }).value.should.equal("DOUBLE PRECISION");
Dialect.getType(null, { mapsTo: 'abc', type: "number"}, driver).value.should.equal("REAL");
Dialect.getType(null, { mapsTo: 'abc', type: "number", size: 4 }, driver).value.should.equal("REAL");
Dialect.getType(null, { mapsTo: 'abc', type: "number", size: 8 }, driver).value.should.equal("DOUBLE PRECISION");

@@ -35,3 +36,3 @@ return done();

it("should detect booleans", function (done) {
Dialect.getType(null, null, { type: "boolean" }).value.should.equal("BOOLEAN");
Dialect.getType(null, { mapsTo: 'abc', type: "boolean" }, driver).value.should.equal("BOOLEAN");

@@ -42,3 +43,3 @@ return done();

it("should detect dates", function (done) {
Dialect.getType(null, null, { type: "date" }).value.should.equal("DATE");
Dialect.getType(null, { mapsTo: 'abc', type: "date" }, driver).value.should.equal("DATE");

@@ -49,3 +50,3 @@ return done();

it("should detect dates with times", function (done) {
Dialect.getType(null, null, { type: "date", time: true }).value.should.equal("TIMESTAMP WITHOUT TIME ZONE");
Dialect.getType(null, { mapsTo: 'abc', type: "date", time: true }, driver).value.should.equal("TIMESTAMP WITHOUT TIME ZONE");

@@ -56,3 +57,3 @@ return done();

it("should detect binary", function (done) {
Dialect.getType(null, null, { type: "binary" }).value.should.equal("BYTEA");
Dialect.getType(null, { mapsTo: 'abc', type: "binary" }, driver).value.should.equal("BYTEA");

@@ -62,4 +63,4 @@ return done();

it("should detect required items", function (done) {
Dialect.getType(null, null, { type: "boolean", required: true }).value.should.match(/NOT NULL/);
it("should detect custom types", function (done) {
Dialect.getType(null, { mapsTo: 'abc', type: "json" }, driver).value.should.equal("JSON");

@@ -69,14 +70,11 @@ return done();

it("should detect default values", function (done) {
Dialect.getType(null, null, { type: "number", defaultValue: 3 }).value.should.match(/DEFAULT 3/);
it("should detect required items", function (done) {
Dialect.getType(null, { mapsTo: 'abc', type: "boolean", required: true }, driver).value.should.match(/NOT NULL/);
return done();
});
});
describe("PostgreSQL.escapeId", function () {
it("should correctly escape identifiers", function (done) {
Dialect.escapeId("my_id").should.equal('"my_id"');
Dialect.escapeId("my_\"id").should.equal('"my_""id"');
Dialect.escapeId("my_id", "sub").should.equal('"my_id"."sub"');
it("should detect default values", function (done) {
Dialect.getType(null, { mapsTo: 'abc', type: "number", defaultValue: 3 }, driver).value.should.match(/DEFAULT \^\^3\^\^/);
Dialect.getType(null, { mapsTo: 'abc', type: 'date', defaultValue: Date.now }, driver).value.should.equal('DATE DEFAULT now()');

@@ -83,0 +81,0 @@ return done();

@@ -0,8 +1,6 @@

var should = require("should");
var common = require("../common");
var SQL = require("../../lib/SQL");
var driver = common.fakeDriver;
var should = require("should");
var Dialect = common.fakeDialect;
describe("SQL.CREATE_TABLE", function () {

@@ -13,4 +11,4 @@ it("should return a CREATE TABLE", function (done) {

columns : [ "first_fake_column", "second_fake_column" ],
primary : [ "my_primary_key" ]
}, Dialect).should.equal("CREATE TABLE $$fake_table$$ (first_fake_column, second_fake_column, " +
keys : [ "my_primary_key" ]
}, driver).should.equal("CREATE TABLE $$fake_table$$ (first_fake_column, second_fake_column, " +
"PRIMARY KEY ($$my_primary_key$$))");

@@ -27,3 +25,3 @@

columns : [ "first_fake_column", "second_fake_column" ]
}, Dialect).should.equal("CREATE TABLE $$fake_table$$ (first_fake_column, second_fake_column)");
}, driver).should.equal("CREATE TABLE $$fake_table$$ (first_fake_column, second_fake_column)");

@@ -38,3 +36,3 @@ return done();

name : "fake_table"
}, Dialect).should.equal("DROP TABLE $$fake_table$$");
}, driver).should.equal("DROP TABLE $$fake_table$$");

@@ -47,14 +45,12 @@ return done();

describe("SQL.ALTER_TABLE_ADD_COLUMN", function () {
it("should return an ALTER TABLE", function (done) {
it("should be correct", function (done) {
SQL.ALTER_TABLE_ADD_COLUMN({
name : "fake_table",
column : "my_fake_column"
}, Dialect).should.equal("ALTER TABLE $$fake_table$$ ADD my_fake_column");
}, driver).should.equal("ALTER TABLE $$fake_table$$ ADD my_fake_column");
return done();
});
});
describe("SQL.ALTER_TABLE_ADD_COLUMN", function () {
it("should return an ALTER TABLE", function (done) {
it("should be correct when first is true", function (done) {
SQL.ALTER_TABLE_ADD_COLUMN({

@@ -64,10 +60,8 @@ name : "fake_table",

first : true
}, Dialect).should.equal("ALTER TABLE $$fake_table$$ ADD my_fake_column FIRST");
}, driver).should.equal("ALTER TABLE $$fake_table$$ ADD my_fake_column FIRST");
return done();
});
});
describe("SQL.ALTER_TABLE_ADD_COLUMN", function () {
it("should return an ALTER TABLE", function (done) {
it("should be correct when after is specified", function (done) {
SQL.ALTER_TABLE_ADD_COLUMN({

@@ -77,3 +71,3 @@ name : "fake_table",

after : "other_column"
}, Dialect).should.equal("ALTER TABLE $$fake_table$$ ADD my_fake_column AFTER $$other_column$$");
}, driver).should.equal("ALTER TABLE $$fake_table$$ ADD my_fake_column AFTER $$other_column$$");

@@ -84,2 +78,14 @@ return done();

describe("SQL.ALTER_TABLE_RENAME_COLUMN", function () {
it("should be correct", function (done) {
SQL.ALTER_TABLE_RENAME_COLUMN({
name : "fake_table",
oldColName : "usersfullname",
newColName : "name"
}, driver).should.equal("ALTER TABLE $$fake_table$$ RENAME COLUMN $$usersfullname$$ TO $$name$$");
return done();
});
});
describe("SQL.ALTER_TABLE_MODIFY_COLUMN", function () {

@@ -90,3 +96,3 @@ it("should return an ALTER TABLE", function (done) {

column : "my_fake_column"
}, Dialect).should.equal("ALTER TABLE $$fake_table$$ MODIFY my_fake_column");
}, driver).should.equal("ALTER TABLE $$fake_table$$ MODIFY my_fake_column");

@@ -102,3 +108,3 @@ return done();

column : "my_fake_column"
}, Dialect).should.equal("ALTER TABLE $$fake_table$$ DROP $$my_fake_column$$");
}, driver).should.equal("ALTER TABLE $$fake_table$$ DROP $$my_fake_column$$");

@@ -115,3 +121,3 @@ return done();

columns : [ "my_fake_column" ]
}, Dialect).should.equal("CREATE INDEX $$fake_index$$ ON $$fake_table$$ ($$my_fake_column$$)");
}, driver).should.equal("CREATE INDEX $$fake_index$$ ON $$fake_table$$ ($$my_fake_column$$)");

@@ -127,3 +133,3 @@ return done();

columns : [ "my_fake_column" ]
}, Dialect).should.equal("CREATE UNIQUE INDEX $$fake_index$$ ON $$fake_table$$ ($$my_fake_column$$)");
}, driver).should.equal("CREATE UNIQUE INDEX $$fake_index$$ ON $$fake_table$$ ($$my_fake_column$$)");

@@ -139,3 +145,3 @@ return done();

collection : "fake_table"
}, Dialect).should.equal("DROP INDEX $$fake_index$$ ON $$fake_table$$");
}, driver).should.equal("DROP INDEX $$fake_index$$ ON $$fake_table$$");

@@ -142,0 +148,0 @@ return done();

@@ -0,10 +1,10 @@

var should = require("should");
var common = require("../common");
var Dialect = require("../../lib/Dialects/sqlite");
var driver = common.fakeDriver;
var should = require("should");
describe("SQLite.getType", function () {
it("should detect text", function (done) {
Dialect.getType(null, null, { type: "text" }).value.should.equal("TEXT");
Dialect.getType(null, null, { type: "text", size: 150 }).value.should.equal("TEXT");
Dialect.getType(null, { mapsTo: 'abc', type: "text" }, driver).value.should.equal("TEXT");
Dialect.getType(null, { mapsTo: 'abc', type: "text", size: 150 }, driver).value.should.equal("TEXT");

@@ -15,6 +15,7 @@ return done();

it("should detect numbers", function (done) {
Dialect.getType(null, null, { type: "number" }).value.should.equal("INTEGER");
Dialect.getType(null, null, { type: "number", size: 4 }).value.should.equal("INTEGER");
Dialect.getType(null, null, { type: "number", size: 2 }).value.should.equal("INTEGER");
Dialect.getType(null, null, { type: "number", size: 8 }).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer" }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 4 }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 2 }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "integer", size: 8 }, driver).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "number", rational: false }, driver).value.should.equal("INTEGER");

@@ -25,5 +26,5 @@ return done();

it("should detect rational numbers", function (done) {
Dialect.getType(null, null, { type: "number", rational: true }).value.should.equal("REAL");
Dialect.getType(null, null, { type: "number", rational: true, size: 4 }).value.should.equal("REAL");
Dialect.getType(null, null, { type: "number", rational: true, size: 8 }).value.should.equal("REAL");
Dialect.getType(null, { mapsTo: 'abc', type: "number"}, driver).value.should.equal("REAL");
Dialect.getType(null, { mapsTo: 'abc', type: "number", size: 4 }, driver).value.should.equal("REAL");
Dialect.getType(null, { mapsTo: 'abc', type: "number", size: 8 }, driver).value.should.equal("REAL");

@@ -34,3 +35,3 @@ return done();

it("should detect booleans", function (done) {
Dialect.getType(null, null, { type: "boolean" }).value.should.equal("INTEGER");
Dialect.getType(null, { mapsTo: 'abc', type: "boolean" }, driver).value.should.equal("INTEGER UNSIGNED");

@@ -41,4 +42,4 @@ return done();

it("should detect dates", function (done) {
Dialect.getType(null, null, { type: "date" }).value.should.equal("DATETIME");
Dialect.getType(null, null, { type: "date", time: true }).value.should.equal("DATETIME");
Dialect.getType(null, { mapsTo: 'abc', type: "date" }, driver).value.should.equal("DATETIME");
Dialect.getType(null, { mapsTo: 'abc', type: "date", time: true }, driver).value.should.equal("DATETIME");

@@ -49,4 +50,4 @@ return done();

it("should detect binary", function (done) {
Dialect.getType(null, null, { type: "binary" }).value.should.equal("BLOB");
Dialect.getType(null, null, { type: "binary", big: true }).value.should.equal("BLOB");
Dialect.getType(null, { mapsTo: 'abc', type: "binary" }, driver).value.should.equal("BLOB");
Dialect.getType(null, { mapsTo: 'abc', type: "binary", big: true }, driver).value.should.equal("BLOB");

@@ -56,4 +57,10 @@ return done();

it("should detect custom types", function (done) {
Dialect.getType(null, { mapsTo: 'abc', type: "json" }, driver).value.should.equal("JSON");
return done();
});
it("should detect required items", function (done) {
Dialect.getType(null, null, { type: "boolean", required: true }).value.should.match(/NOT NULL/);
Dialect.getType(null, { mapsTo: 'abc', type: "boolean", required: true }, driver).value.should.match(/NOT NULL/);

@@ -64,3 +71,3 @@ return done();

it("should detect default values", function (done) {
Dialect.getType(null, null, { type: "number", defaultValue: 3 }).value.should.match(/DEFAULT 3/);
Dialect.getType(null, { mapsTo: 'abc', type: "number", defaultValue: 3 }, driver).value.should.match(/DEFAULT \^\^3\^\^/);

@@ -71,6 +78,3 @@ return done();

it("should detect serial", function (done) {
var column = Dialect.getType(null, null, {
type : "number",
serial : true
}).value;
var column = Dialect.getType(null, { mapsTo: 'abc', type: "serial" }).value;

@@ -83,11 +87,1 @@ column.should.match(/INT/);

});
describe("SQLite.escapeId", function () {
it("should correctly escape identifiers", function (done) {
Dialect.escapeId("my_id").should.equal("`my_id`");
Dialect.escapeId("my_`id").should.equal("`my_``id`");
Dialect.escapeId("my_id", "sub").should.equal("`my_id`.`sub`");
return done();
});
});
var program = require("commander");
var Mocha = require("mocha");
var orm = require("orm");
var common = require("./common");
var url = require("url");
var common = require("./common");
program.version("0.1.0")

@@ -23,38 +23,13 @@ .option("-u, --uri <uri>", "Database URI", String, null)

switch (uri.protocol) {
case "mysql:":
common.dialect = "mysql";
orm.connect(uri, function (err, db) {
if (err) throw err;
common.db = require("mysql").createConnection(program.uri);
common.db.connect(testDatabase);
break;
case "postgres:":
case "postgresql:":
case "pg:":
common.dialect = "postgresql";
common.driver = db.driver;
common.db = new (require("pg").Client)(uri);
common.db.connect(testDatabase);
break;
case "sqlite:":
case "sqlite3:":
common.dialect = "sqlite";
testDatabase()
});
common.db = new (require("sqlite3").Database)(uri.pathname);
testDatabase();
// common.db.connect(testDatabase);
break;
default:
process.stdout.write("Database protocol not supported.\n");
process.exit(2);
}
function testDatabase() {
var mocha = new Mocha({ reporter : "spec" });
function testDatabase(err) {
if (err) {
throw err;
}
var mocha = new Mocha({
reporter : "spec"
});
mocha.addFile(__dirname + "/integration/db.js");

@@ -61,0 +36,0 @@ mocha.run(function (failures) {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc