Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

support validate on instances as well as model

  • Loading branch information...
commit fcad293b64035d7779798a52865b52aa1a4bbdc4 1 parent 290d01c
@joeferner authored
Showing with 77 additions and 64 deletions.
  1. +77 −64 lib/connection.js
View
141 lib/connection.js
@@ -9,18 +9,18 @@ var Class = require('./class');
var over = require('over');
var Connection = Class.extend({
- init: function (driver, opts) {
+ init: function(driver, opts) {
this.driver = driver;
this.opts = opts || {};
},
- save: function (obj, callback) {
+ save: function(obj, callback) {
var self = this;
if (obj instanceof Array) {
if (obj.length === 0) {
callback(null);
} else {
- this.save(obj[0], function (err) {
+ this.save(obj[0], function(err) {
if (err) {
callback(err);
return;
@@ -34,13 +34,13 @@ var Connection = Class.extend({
this._save(true, obj, callback);
},
- update: function (obj, callback) {
+ update: function(obj, callback) {
var self = this;
if (obj instanceof Array) {
if (obj.length === 0) {
callback(null);
} else {
- this.update(obj[0], function (err) {
+ this.update(obj[0], function(err) {
if (err) {
callback(err);
return;
@@ -54,18 +54,31 @@ var Connection = Class.extend({
this._save(false, obj, callback);
},
- _save: function (isNew, obj, callback) {
+ _save: function(isNew, obj, callback) {
var self = this;
- if (obj._getModel().validate) {
- obj._getModel().validate(obj, function (success, message) {
+ if (obj.validate && typeof(obj.validate) === 'function') {
+ return obj.validate(function(success, message) {
if (success) {
- return doSave();
+ return doModelValidation();
}
return callback(new Error("Validation failed: " + message));
});
} else {
- return doSave();
+ return doModelValidation();
+ }
+
+ function doModelValidation() {
+ if (obj._getModel().validate) {
+ return obj._getModel().validate(obj, function(success, message) {
+ if (success) {
+ return doSave();
+ }
+ return callback(new Error("Validation failed: " + message));
+ });
+ } else {
+ return doSave();
+ }
}
function doSave() {
@@ -86,7 +99,7 @@ var Connection = Class.extend({
} else {
sqlAndValues = self.driver.getUpdateSql(obj);
}
- self._runSql(sqlAndValues.sql, sqlAndValues.values, function (err, data) {
+ self._runSql(sqlAndValues.sql, sqlAndValues.values, function(err, data) {
if (err) {
callback(err);
return;
@@ -95,9 +108,9 @@ var Connection = Class.extend({
var idPropName = obj._getModel().getIdPropertyName();
obj[idPropName] = data.lastId;
}
- obj._getConnection = function () { return self; }; // hide from JSON.stringify
- obj._isPersisted = function () { return true; };
- self.saveAssociations(obj, function (err, obj) {
+ obj._getConnection = function() { return self; }; // hide from JSON.stringify
+ obj._isPersisted = function() { return true; };
+ self.saveAssociations(obj, function(err, obj) {
if (isNew) {
obj._getModel().emit("afterCreate", obj);
obj._getModel().emit("afterSave", obj);
@@ -112,7 +125,7 @@ var Connection = Class.extend({
}
},
- updatePartial: function (model, id, data, callback) {
+ updatePartial: function(model, id, data, callback) {
var self = this;
if (model.onSave) {
@@ -123,10 +136,10 @@ var Connection = Class.extend({
this._runSql(sqlAndValues.sql, sqlAndValues.values, callback);
},
- chain: function (tasks, chainCallback) {
+ chain: function(tasks, chainCallback) {
var self = this;
if (tasks instanceof Array) {
- async.mapSeries(tasks, function (item, callback) {
+ async.mapSeries(tasks, function(item, callback) {
if (typeof (item) === 'function') {
item.call(item, self, callback);
} else {
@@ -139,8 +152,8 @@ var Connection = Class.extend({
for (key in tasks) {
items.push({ key: key, task: tasks[key] });
}
- async.mapSeries(items, function (item, callback) {
- item.task.call(item.task, self, function (err, value) {
+ async.mapSeries(items, function(item, callback) {
+ item.task.call(item.task, self, function(err, value) {
if (err) {
callback(err);
return;
@@ -148,7 +161,7 @@ var Connection = Class.extend({
var v = { key: item.key, value: value };
callback(null, v);
});
- }, function (err, items) {
+ }, function(err, items) {
if (err) {
chainCallback(err);
return;
@@ -163,15 +176,15 @@ var Connection = Class.extend({
}
},
- saveAssociation: function (obj, name, association, callback) {
+ saveAssociation: function(obj, name, association, callback) {
var self = this;
if (association.type === 'hasMany' && obj['_' + name] && association.through) {
var relatedObjs = obj['_' + name];
var Query = require('./query'); // late bind query because it causes a circular reference
new Query(this, association.through)
.where(association.foreignKey + " = ?", obj.getId())
- .deleteAll(function (err, deleteCallback) {
- async.forEachSeries(relatedObjs, function (relatedObj, saveRelatedObjCallback) {
+ .deleteAll(function(err, deleteCallback) {
+ async.forEachSeries(relatedObjs, function(relatedObj, saveRelatedObjCallback) {
var sqlAndValues = self.driver.getManyToManyInsertSql(association, obj, relatedObj);
self._runSql(sqlAndValues.sql, sqlAndValues.values, saveRelatedObjCallback);
}, callback);
@@ -181,7 +194,7 @@ var Connection = Class.extend({
}
},
- saveAssociations: function (obj, callback) {
+ saveAssociations: function(obj, callback) {
var self = this;
var associations = [];
var name;
@@ -192,33 +205,33 @@ var Connection = Class.extend({
});
}
- async.forEachSeries(associations, function (association, saveAssociationCallback) {
+ async.forEachSeries(associations, function(association, saveAssociationCallback) {
self.saveAssociation(obj, association.name, association.association, saveAssociationCallback);
- }, function (err) {
+ }, function(err) {
callback(err, obj);
});
},
- each: function (sqlTree, callback, doneCallback) {
+ each: function(sqlTree, callback, doneCallback) {
var self = this;
var sqlAndValues = this.driver.getSqlFromSqlTree(sqlTree);
- this._runSqlEach(sqlAndValues.sql, sqlAndValues.values, function (err, data) {
+ this._runSqlEach(sqlAndValues.sql, sqlAndValues.values, function(err, data) {
if (err) {
callback(err);
return;
}
var obj = sqlTree.toObject(data);
- obj._getConnection = function () { return self; }; // hide from JSON.stringify
+ obj._getConnection = function() { return self; }; // hide from JSON.stringify
callback(null, obj);
- }, function () {
+ }, function() {
if (doneCallback) {
doneCallback();
}
});
},
- _resultsArrayGetById: function (model, array, id) {
+ _resultsArrayGetById: function(model, array, id) {
var i;
for (i = 0; i < array.length; i++) {
var itemId = array[i].getId();
@@ -229,17 +242,17 @@ var Connection = Class.extend({
return null;
},
- _augmentResultsArrayWithHelpers: function (model, array) {
+ _augmentResultsArrayWithHelpers: function(model, array) {
array.getById = this._resultsArrayGetById.bind(this, model, array);
},
- all: function (sqlTree, callback) {
+ all: function(sqlTree, callback) {
var self = this;
var sqlAndValues = this.driver.getSqlFromSqlTree(sqlTree);
if (self.opts.trace) {
console.log(sqlAndValues.sql, sqlAndValues.values);
}
- this._runSqlAll(sqlAndValues.sql, sqlAndValues.values, function (err, data) {
+ this._runSqlAll(sqlAndValues.sql, sqlAndValues.values, function(err, data) {
if (err) {
callback(err);
return;
@@ -248,7 +261,7 @@ var Connection = Class.extend({
// add connections to all the objects
var i;
- var selfFunc = function () { return self; };
+ var selfFunc = function() { return self; };
for (i = 0; i < objs.length; i++) {
objs[i]._getConnection = selfFunc; // hide from JSON.stringify
}
@@ -261,10 +274,10 @@ var Connection = Class.extend({
});
},
- single: function (sqlTree, fieldName, callback) {
+ single: function(sqlTree, fieldName, callback) {
var self = this;
var sqlAndValues = this.driver.getSqlFromSqlTree(sqlTree);
- this._runSqlAll(sqlAndValues.sql, sqlAndValues.values, function (err, data) {
+ this._runSqlAll(sqlAndValues.sql, sqlAndValues.values, function(err, data) {
if (err) {
callback(err);
return;
@@ -276,8 +289,8 @@ var Connection = Class.extend({
// filename, values, callback
// filename, callback
runSqlFromFile: over([
- [over.string, over.arrayOptionalWithDefault(null), over.callbackOptional, function (filename, params, callback) {
- this._readSqlFile(filename, function (err, sql) {
+ [over.string, over.arrayOptionalWithDefault(null), over.callbackOptional, function(filename, params, callback) {
+ this._readSqlFile(filename, function(err, sql) {
if (err) {
return callback(err);
}
@@ -286,12 +299,12 @@ var Connection = Class.extend({
}]
]),
- runSqlAllFromFile: function (filename, params, callback) {
+ runSqlAllFromFile: function(filename, params, callback) {
var self = this;
if (arguments.length === 2) {
return this.runSqlAllFromFile(filename, null, arguments[1]);
}
- this._readSqlFile(filename, function (err, sql) {
+ this._readSqlFile(filename, function(err, sql) {
if (err) {
return callback(err);
}
@@ -299,12 +312,12 @@ var Connection = Class.extend({
});
},
- runSqlEachFromFile: function (filename, params, rowCallback, doneCallback) {
+ runSqlEachFromFile: function(filename, params, rowCallback, doneCallback) {
var self = this;
if (arguments.length === 3) {
return this.runSqlEachFromFile(filename, null, arguments[1], arguments[2]);
}
- this._readSqlFile(filename, function (err, sql) {
+ this._readSqlFile(filename, function(err, sql) {
if (err) {
return callback(err);
}
@@ -312,17 +325,17 @@ var Connection = Class.extend({
});
},
- _readSqlFile: function (filename, callback) {
+ _readSqlFile: function(filename, callback) {
async.detect([
filename,
filename + '.sql',
path.join(this.opts.sqlDir, filename),
path.join(this.opts.sqlDir, filename) + '.sql'
- ], fs.exists, function (fname) {
+ ], fs.exists, function(fname) {
if (!fname) {
return callback(new Error("Could not find SQL file. " + filename));
}
- fs.readFile(fname, 'utf8', function (err, sql) {
+ fs.readFile(fname, 'utf8', function(err, sql) {
if (err) {
return callback(new Error('Could not read SQL file. ' + filename + '. ' + err));
}
@@ -335,16 +348,16 @@ var Connection = Class.extend({
// [sql, ...], callback
// sql, values, callback
// sql, callback
- runSql: function () {
+ runSql: function() {
var self = this;
var args = arguments;
// todo: there has to be a better way to handle this mess.
// todo: when it's an array the results to callback should be an array of results.
if (arguments[0] instanceof Array) {
var runSqlCallback = args[arguments.length - 1];
- if (typeof (runSqlCallback) !== "function") { runSqlCallback = function () {}; }
+ if (typeof (runSqlCallback) !== "function") { runSqlCallback = function() {}; }
- async.mapSeries(arguments[0], function (item, callback) {
+ async.mapSeries(arguments[0], function(item, callback) {
if (args.length === 2) {
self._runSql(item, callback);
} else if (args.length === 3) {
@@ -373,16 +386,16 @@ var Connection = Class.extend({
// [sql, ...], callback
// sql, values, callback
// sql, callback
- _runSql: function () {
+ _runSql: function() {
var self = this;
var args = arguments;
// todo: there has to be a better way to handle this mess.
// todo: when it's an array the results to callback should be an array of results.
if (arguments[0] instanceof Array) {
var runSqlCallback = args[arguments.length - 1];
- if (typeof (runSqlCallback) !== "function") { runSqlCallback = function () {}; }
+ if (typeof (runSqlCallback) !== "function") { runSqlCallback = function() {}; }
- async.mapSeries(arguments[0], function (item, callback) {
+ async.mapSeries(arguments[0], function(item, callback) {
if (args.length === 2) {
self._runSql(item, callback);
} else if (args.length === 3) {
@@ -430,43 +443,43 @@ var Connection = Class.extend({
}
},
- _runSql2: function (sql, callback) {
+ _runSql2: function(sql, callback) {
throw new Error("Not Implemented");
},
- _runSql3: function (sql, values, callback) {
+ _runSql3: function(sql, values, callback) {
throw new Error("Not Implemented");
},
- _runSqlAll: function (sql, params, callback) {
+ _runSqlAll: function(sql, params, callback) {
throw new Error("Not Implemented");
},
// sql, [callback]
// sql, params, [callback]
runSqlAll: over([
- [over.string, over.arrayOptional, over.callbackOptional, function (sql, params, callback) {
+ [over.string, over.arrayOptional, over.callbackOptional, function(sql, params, callback) {
sql = this.driver._updateSubstitutes(sql, params);
return this._runSqlAll(sql, params, callback);
}]
]),
- _runSqlEach: function (sql, params, callback, doneCallback) {
+ _runSqlEach: function(sql, params, callback, doneCallback) {
throw new Error("Not Implemented");
},
- runSqlEach: function (sql, params, callback, doneCallback) {
+ runSqlEach: function(sql, params, callback, doneCallback) {
sql = this.driver._updateSubstitutes(sql, params);
return this._runSqlEach(sql, params, callback, doneCallback);
},
- close: function () {
+ close: function() {
throw new Error("Not Implemented");
},
- tx: function (callback) {
+ tx: function(callback) {
var self = this;
- this.beginTransaction(function (err) {
+ this.beginTransaction(function(err) {
if (err) {
callback(err);
return;
@@ -475,15 +488,15 @@ var Connection = Class.extend({
});
},
- beginTransaction: function (callback) {
+ beginTransaction: function(callback) {
throw new Error("Not Implemented");
},
- commitTransaction: function (callback) {
+ commitTransaction: function(callback) {
throw new Error("Not Implemented");
},
- rollbackTransaction: function (callback) {
+ rollbackTransaction: function(callback) {
throw new Error("Not Implemented");
}
});
Please sign in to comment.
Something went wrong with that request. Please try again.