Comparing version 1.13.8 to 1.13.9
295
lib/model.js
@@ -48,2 +48,21 @@ var util = require(__dirname+'/util.js'); | ||
this._methods = {}; | ||
this._async = { | ||
init: false, | ||
retrieve: false, | ||
save: false, | ||
validate: false | ||
}; | ||
this._pre = { | ||
save: [], | ||
delete: [], | ||
validate: [] | ||
}; | ||
this._post = { | ||
init: [], | ||
retrieve: [], | ||
save: [], | ||
delete: [], | ||
validate: [] | ||
}; | ||
} | ||
@@ -136,6 +155,22 @@ util.inherits(Model, EventEmitter); | ||
var promises = []; | ||
var promise; | ||
if (proto._options.validate === 'oncreate') { | ||
doc.validate(); | ||
promise = doc.validate(); | ||
if (promise instanceof Promise) promises.push(promise); | ||
} | ||
if (proto._post.init.length > 0) { | ||
promise = util.hook({ | ||
postHooks: doc._getModel()._post.init, | ||
doc: doc, | ||
async: doc._getModel()._async.init, | ||
fn: function() {} | ||
}) | ||
if (promise instanceof Promise) promises.push(promise); | ||
} | ||
if (promises.length > 0) { | ||
return Promise.all(promises); | ||
} | ||
return doc; | ||
@@ -836,31 +871,40 @@ } | ||
var insert = function() { | ||
var promises = []; | ||
var promise; | ||
util.tryCatch(function() { | ||
for(var i=0; i<docs.length; i++) { | ||
docs[i] = new self(docs[i]); | ||
docs[i].validate(); | ||
promise = docs[i].validate(); | ||
if (promise instanceof Promise) promises.push(promise); | ||
} | ||
}, reject); | ||
r.table(self.getTableName()).insert(docs).run().then(function(results) { | ||
if ((results.errors === 0) && (results.inserted === docs.length)) { | ||
util.tryCatch(function() { | ||
var index = 0; | ||
// Set the primary keys | ||
for(var i=0; i<docs.length; i++) { | ||
if (docs[i].hasOwnProperty(self._getModel()._pk) === false) { | ||
docs[i][self._getModel()._pk] = results.generated_keys[index]; | ||
index++ | ||
var executeInsert = function () { | ||
r.table(self.getTableName()).insert(docs).run().then(function(results) { | ||
if ((results.errors === 0) && (results.inserted === docs.length)) { | ||
util.tryCatch(function() { | ||
var index = 0; | ||
// Set the primary keys | ||
for(var i=0; i<docs.length; i++) { | ||
if (docs[i].hasOwnProperty(self._getModel()._pk) === false) { | ||
docs[i][self._getModel()._pk] = results.generated_keys[index]; | ||
index++ | ||
} | ||
} | ||
} | ||
// Create instances of the model | ||
for(i=0; i<docs.length; i++) { | ||
docs[i].setSaved() | ||
} | ||
resolve(docs); | ||
}, reject) | ||
} | ||
else { | ||
reject(new Error("An error occurred during the batch insert.")) | ||
} | ||
}).error(reject); | ||
// Create instances of the model | ||
for(i=0; i<docs.length; i++) { | ||
docs[i].setSaved() | ||
} | ||
resolve(docs); | ||
}, reject) | ||
} | ||
else { | ||
reject(new Error("An error occurred during the batch insert.")) | ||
} | ||
}).error(reject); | ||
} | ||
// Works fine if promises.length === 0 | ||
Promise.all(promises).then(executeInsert).error(reject); | ||
} | ||
@@ -895,2 +939,5 @@ | ||
var self = this; | ||
var promises = []; | ||
var promise; | ||
var p = new Promise(function(resolve, reject) { | ||
@@ -901,14 +948,45 @@ if ((util.isPlainObject(data)) && (data.__proto__._next !== undefined)) { // Checking if a cursor | ||
for(var i=0; i<result.length; i++) { | ||
self.emit('retrieved', result[i]); | ||
result[i] = new self(result[i]) | ||
result[i].validate(); | ||
result[i].setSaved(true); | ||
self.emit('retrieved', result[i]); | ||
// Order matters here, we want the hooks to be executed *before* calling validate | ||
promise = util.hook({ | ||
postHooks: result[i]._getModel()._post.retrieve, | ||
doc: result[i], | ||
async: result[i]._getModel()._async.retrieve, | ||
fn: function() {} | ||
}) | ||
if (promise instanceof Promise) { | ||
promise.then(function() { | ||
var promise = result[i].validate(); | ||
if (promise instanceof Promise) { | ||
promise.then(resolve).error(reject); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
}).error(reject); | ||
promises.push(promise); | ||
} | ||
else { | ||
promise = result[i].validate(); | ||
if (promise instanceof Promise) promises.push(promise); | ||
} | ||
} | ||
resolve(result); | ||
}, function(error) { | ||
var newError = new Error(); | ||
newError.message = "The results could not be converted to instances of `"+self.getTableName()+"`\nDetailed error: "+error.message | ||
var newError = new Error("The results could not be converted to instances of `"+self.getTableName()+"`\nDetailed error: "+error.message); | ||
return reject(newError); | ||
}); | ||
if (promises.length > 0) { | ||
Promise.all(promises).then(function() { | ||
resolve(result); | ||
}).error(reject); | ||
} | ||
else { | ||
resolve(result); | ||
} | ||
}).error(reject) | ||
@@ -919,4 +997,4 @@ } | ||
if (util.isPlainObject(data) && (data.$reql_type$ === "GROUPED_DATA")) { | ||
var result = []; | ||
util.tryCatch(function() { | ||
var result = []; | ||
var reduction, newDoc; | ||
@@ -927,8 +1005,32 @@ for(var i=0; i<data.data.length; i++) { | ||
for(var j=0; j<data.data[i][1].length; j++) { | ||
self.emit('retrieved', data.data[i][1][j]); | ||
newDoc = new self(data.data[i][1][j]); | ||
newDoc.validate(); | ||
newDoc.setSaved(true); | ||
self.emit('retrieved', newDoc); | ||
promise = util.hook({ | ||
postHooks: newDoc._getModel()._post.retrieve, | ||
doc: newDoc, | ||
async: newDoc._getModel()._async.retrieve, | ||
fn: function() {} | ||
}) | ||
if (promise instanceof Promise) { | ||
promise.then(function() { | ||
var promise = newDoc.validate(); | ||
if (promise instanceof Promise) { | ||
promise.then(resolve).error(reject); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
}).error(reject); | ||
promises.push(promise); | ||
} | ||
else { | ||
promise = newDoc.validate(); | ||
if (promise instanceof Promise) promises.push(promise); | ||
} | ||
reduction.push(newDoc) | ||
} | ||
@@ -941,6 +1043,30 @@ result.push({ | ||
else { | ||
self.emit('retrieved', data.data[i][1]); | ||
newDoc = new self(data.data[i][1]); | ||
newDoc.validate(); | ||
newDoc.setSaved(true); | ||
self.emit('retrieved', newDoc); | ||
promise = util.hook({ | ||
postHooks: newDoc._getModel()._post.retrieve, | ||
doc: newDoc, | ||
async: newDoc._getModel()._async.retrieve, | ||
fn: function() {} | ||
}) | ||
if (promise instanceof Promise) { | ||
promise.then(function() { | ||
var promise = newDoc.validate(); | ||
if (promise instanceof Promise) { | ||
promise.then(resolve).error(reject); | ||
} | ||
else { | ||
resolve(); | ||
} | ||
}).error(reject); | ||
promises.push(promise); | ||
} | ||
else { | ||
promise = newDoc.validate(); | ||
if (promise instanceof Promise) promises.push(promise); | ||
} | ||
result.push({ | ||
@@ -950,7 +1076,13 @@ group: data.data[i][0], | ||
}) | ||
} | ||
} | ||
resolve(result) | ||
}, reject); | ||
if (promises.length > 0) { | ||
Promise.all(promises).then(function() { | ||
resolve(result) | ||
}).error(reject); | ||
} | ||
else { | ||
resolve(result); | ||
} | ||
} | ||
@@ -963,7 +1095,38 @@ else { | ||
util.tryCatch(function() { | ||
self.emit('retrieved', data); | ||
data = new self(data); | ||
data.validate(); | ||
data.setSaved(true); | ||
resolve(data) | ||
var newDoc = new self(data); | ||
newDoc.setSaved(true); | ||
self.emit('retrieved', newDoc); | ||
promise = util.hook({ | ||
postHooks: newDoc._getModel()._post.retrieve, | ||
doc: newDoc, | ||
async: newDoc._getModel()._async.retrieve, | ||
fn: function() {} | ||
}) | ||
if (promise instanceof Promise) { | ||
promise.then(function() { | ||
var promise = newDoc.validate(); | ||
if (promise instanceof Promise) { | ||
promise.then(resolve).error(reject); | ||
} | ||
else { | ||
resolve(newDoc); | ||
} | ||
}).error(reject); | ||
} | ||
else { | ||
promise = newDoc.validate(); | ||
} | ||
if (promise instanceof Promise) { | ||
promise.then(function() { | ||
resolve(newDoc) | ||
}).error(function(err) { | ||
reject(err) | ||
}); | ||
} | ||
else { | ||
resolve(newDoc); | ||
} | ||
}, reject); | ||
@@ -1043,4 +1206,54 @@ } | ||
module.exports = Model; | ||
Model.prototype.pre = function(ev, isAsync, fn) { | ||
if (arguments.length === 2) { | ||
if (typeof isAsync !== 'function') { | ||
throw new Error("Second argument to `pre` must be a function if only two arguments are provided.") | ||
} | ||
fn = isAsync; | ||
isAsync = false; | ||
} | ||
else if (arguments.length === 3) { | ||
if (typeof isAsync !== 'boolean') { | ||
throw new Error("Second argument to `pre` must be a boolean if three arguments are provided.") | ||
} | ||
if (typeof fn !== 'function') { | ||
throw new Error("Third argument to `pre` must be a function if three arguments are provided.") | ||
} | ||
} | ||
if (Array.isArray(this._pre[ev]) === false) { | ||
throw new Error("No pre-hook available for the event `"+ev+"`.") | ||
} | ||
if (isAsync === true) { | ||
this._getModel()._async[ev] = true; | ||
} | ||
this._getModel()._pre[ev].push(fn); | ||
} | ||
Model.prototype.post = function(ev, isAsync, fn) { | ||
if (arguments.length === 2) { | ||
if (typeof isAsync !== 'function') { | ||
throw new Error("Second argument to `post` must be a function if only two arguments are provided.") | ||
} | ||
fn = isAsync; | ||
isAsync = false; | ||
} | ||
else if (arguments.length === 3) { | ||
if (typeof isAsync !== 'boolean') { | ||
throw new Error("Second argument to `post` must be a boolean if three arguments are provided.") | ||
} | ||
if (typeof fn !== 'function') { | ||
throw new Error("Third argument to `post` must be a function if three arguments are provided.") | ||
} | ||
} | ||
if (Array.isArray(this._post[ev]) === false) { | ||
throw new Error("No post-hook available for the event `"+ev+"`.") | ||
} | ||
if (isAsync === true) { | ||
this._getModel()._async[ev] = true; | ||
} | ||
this._getModel()._post[ev].push(fn); | ||
} | ||
module.exports = Model; |
@@ -74,3 +74,3 @@ var Promise = require('bluebird'); | ||
}).error(reject) | ||
}) | ||
}); | ||
} | ||
@@ -99,3 +99,3 @@ else { | ||
}); | ||
}) | ||
}); | ||
} | ||
@@ -102,0 +102,0 @@ if (typeof callback === 'function') { |
112
lib/util.js
var util = require('util'); | ||
var Promise = require('bluebird'); | ||
function isPlainObject(obj) { | ||
@@ -134,4 +136,112 @@ return Object.prototype.toString.call(obj) === '[object Object]'; | ||
module.exports = util; | ||
function hook(options) { | ||
// Return a promise if a hook is asynchronous | ||
// If no hook is asynchronous, `fn` can still be asynchronous, | ||
// in which case we return a promise or undefined | ||
var preHooks = options.preHooks; | ||
var postHooks = options.postHooks; | ||
var doc = options.doc; // We need the doc to set the context of the hooks | ||
var async = options.async || false; | ||
var fn = options.fn; // The function that we are hook | ||
if (async === true) { | ||
return new Promise(function(resolve, reject) { | ||
_hook({ | ||
resolve: resolve, | ||
reject: reject, | ||
preHooks: preHooks, | ||
postHooks: postHooks, | ||
doc: doc, | ||
fn: fn | ||
}); | ||
}); | ||
} | ||
else { | ||
return _hook(options); | ||
} | ||
} | ||
function _hook(options) { | ||
var doc = options.doc; | ||
var preHooks = options.preHooks; | ||
var postHooks = options.postHooks; | ||
var fn = options.fn; | ||
var resolve = options.resolve; | ||
var reject = options.reject; | ||
var promise, result; | ||
var hookIndex = 0; | ||
var executePostHooks = function() { | ||
if ((Array.isArray(postHooks)) && (hookIndex < postHooks.length)) { | ||
postHooks[hookIndex].call(doc, function(err) { | ||
if (err) { | ||
if (typeof reject === 'function') { | ||
return reject(err) | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
hookIndex++; | ||
executePostHooks() | ||
}); | ||
} | ||
else { | ||
if (typeof resolve === 'function') { | ||
resolve(result); | ||
} | ||
} | ||
} | ||
var executePreHooks = function() { | ||
if ((Array.isArray(preHooks)) && (hookIndex < preHooks.length)) { | ||
preHooks[hookIndex].call(doc, function(err) { | ||
if (err) { | ||
if (typeof reject === 'function') { | ||
return reject(err) | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
hookIndex++; | ||
executePreHooks() | ||
}); | ||
} | ||
else { | ||
tryCatch(function() { | ||
promise = fn.bind(doc)(); | ||
}, function(err) { | ||
if (typeof reject === 'function') { | ||
reject(err); | ||
} | ||
else { | ||
throw err; | ||
} | ||
}); | ||
if (promise instanceof Promise) { | ||
promise.then(function(res) { | ||
result = res; | ||
hookIndex = 0; | ||
executePostHooks(); | ||
}).error(reject); | ||
} | ||
else { | ||
result = promise; | ||
hookIndex = 0; | ||
executePostHooks(); | ||
} | ||
} | ||
} | ||
executePreHooks(); | ||
if ((typeof resolve !== 'function') && (promise instanceof Promise)) { | ||
// No hook is asynchronous, but `fn` returned a promise | ||
return promise; | ||
} | ||
} | ||
util.hook = hook; | ||
module.exports = util; |
{ | ||
"name": "thinky", | ||
"version": "1.13.8", | ||
"version": "1.13.9", | ||
"description": "RethinkDB ORM for Node.js", | ||
@@ -5,0 +5,0 @@ "main": "lib/thinky.js", |
Sorry, the diff of this file is too big to display
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
141699
11
3076