Comparing version 1.15.0 to 1.15.1
212
lib/model.js
var util = require(__dirname+'/util.js'); | ||
var schemaUtil = require(__dirname+'/schema.js'); | ||
var Document = require(__dirname+'/document.js'); | ||
@@ -14,5 +15,11 @@ var EventEmitter = require('events').EventEmitter; | ||
util.validateSchema(schema) | ||
schemaUtil.validateSchema(schema) | ||
this._schema = schema; | ||
this.virtualFields = []; | ||
schemaUtil.getVirtualFields(schema, [], this.virtualFields); | ||
this.defaultFields = []; | ||
schemaUtil.getDefaultFields(schema, [], this.defaultFields); | ||
this.needToGenerateFields = (this.defaultFields.length+this.virtualFields.length) !== 0; | ||
// We want a deep copy | ||
@@ -45,2 +52,3 @@ options = options || {}; | ||
this._joins = {}; | ||
this._localKeys = {}; // key used as a foreign key by another model | ||
@@ -83,10 +91,14 @@ // This is to track joins that were not directly called by this model but that we still need | ||
} | ||
doc = util.deepCopy(doc); | ||
doc.__proto__ = new Document(model, options); | ||
// We create a deepcopy only if doc was already used to create a document | ||
if (doc instanceof Document) { | ||
doc = util.deepCopy(doc); | ||
} | ||
util.changeProto(doc, new Document(model, options)); | ||
// Make joins | ||
for(var key in proto._joins) { | ||
util.loopKeys(proto._joins, function(joins, key) { | ||
if (doc[key] != null) { | ||
if (proto._joins[key].type === 'hasOne') { | ||
doc[key] = new proto._joins[key].model(doc[key], options); | ||
if (joins[key].type === 'hasOne') { | ||
doc[key] = new joins[key].model(doc[key], options); | ||
@@ -106,4 +118,4 @@ doc.__proto__._hasOne[key] = { | ||
} | ||
else if (proto._joins[key].type === 'belongsTo') { | ||
doc[key] = new proto._joins[key].model(doc[key], options); | ||
else if (joins[key].type === 'belongsTo') { | ||
doc[key] = new joins[key].model(doc[key], options); | ||
@@ -120,7 +132,7 @@ if (doc[key].__proto__._parents._belongsTo[doc._getModel()._name] == null) { | ||
} | ||
else if (proto._joins[key].type === 'hasMany') { | ||
else if (joins[key].type === 'hasMany') { | ||
doc.__proto__._hasMany[key] = [] | ||
for(var i=0; i<doc[key].length; i++) { | ||
doc[key][i] = new proto._joins[key].model(doc[key][i], options); | ||
doc[key][i] = new joins[key].model(doc[key][i], options); | ||
doc.__proto__._hasMany[key].push({ | ||
@@ -141,7 +153,7 @@ doc: doc[key][i], | ||
} | ||
else if (proto._joins[key].type === 'hasAndBelongsToMany') { | ||
else if (joins[key].type === 'hasAndBelongsToMany') { | ||
doc.__proto__._links[model._joins[key].link] = {} | ||
for(var i=0; i<doc[key].length; i++) { | ||
doc[key][i] = new proto._joins[key].model(doc[key][i], options); | ||
doc[key][i] = new joins[key].model(doc[key][i], options); | ||
@@ -161,4 +173,6 @@ doc.__proto__._links[model._joins[key].link][doc[key][i][model._joins[key].rightKey]] = true; | ||
} | ||
}); | ||
if (proto.needToGenerateFields === true) { | ||
doc._generateDefault(); | ||
} | ||
doc.__proto__._generateDefault.apply(doc) | ||
@@ -193,3 +207,3 @@ var promises = []; | ||
// the constructor and the instance of Model | ||
for(var key in EventEmitter.prototype) { | ||
util.loopKeys(EventEmitter.prototype, function(emitter, key) { | ||
(function(_key) { | ||
@@ -200,3 +214,3 @@ model[_key] = function() { | ||
})(key) | ||
} | ||
}); | ||
@@ -257,13 +271,2 @@ | ||
/* | ||
* Make a shallow copy of docValues in doc | ||
*/ | ||
Model.prototype.create = function(docValues) { | ||
var doc = {}; | ||
for(var key in docValues) { | ||
doc[key] = docValues[key]; | ||
} | ||
return doc; | ||
} | ||
/* | ||
* Return the options of the model -- call from an instance of Model | ||
@@ -420,2 +423,3 @@ */ | ||
} | ||
joinedModel._getModel()._localKeys[rightKey] = true; | ||
@@ -519,3 +523,4 @@ options = options || {}; | ||
type: 'belongsTo' | ||
} | ||
}; | ||
self._getModel()._localKeys[leftKey] = true; | ||
@@ -618,4 +623,5 @@ joinedModel._getModel()._reverseJoins[fieldDoc] = { | ||
type: 'hasMany' | ||
} | ||
}; | ||
joinedModel._getModel()._localKeys[rightKey] = true; | ||
options = options || {}; | ||
@@ -910,63 +916,65 @@ if (options.init !== false) { | ||
} | ||
} | ||
}; | ||
// Import rethinkdbdash methods | ||
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__; | ||
for(var key in Term) { | ||
if ((Term.hasOwnProperty(key)) && (key !== 'run') && (key[0] !== '_')) { | ||
(function(key) { | ||
switch (key) { | ||
case 'orderBy': | ||
Model.prototype[key] = function() { | ||
var query = new Query(this); | ||
if ((arguments.length === 1) | ||
&& (typeof arguments[0] === 'string') | ||
&& (this._getModel()._indexes[arguments[0]] === true)) { | ||
(function() { | ||
// Import rethinkdbdash methods | ||
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__; | ||
util.loopKeys(Term, function(Term, key) { | ||
if ((Term.hasOwnProperty(key)) && (key !== 'run') && (key[0] !== '_')) { | ||
(function(key) { | ||
switch (key) { | ||
case 'orderBy': | ||
Model.prototype[key] = function() { | ||
var query = new Query(this); | ||
if ((arguments.length === 1) | ||
&& (typeof arguments[0] === 'string') | ||
&& (this._getModel()._indexes[arguments[0]] === true)) { | ||
query = query[key]({index: arguments[0]}); | ||
query = query[key]({index: arguments[0]}); | ||
return query; | ||
} | ||
else { | ||
query = query[key].apply(query, arguments); | ||
return query; | ||
} | ||
} | ||
else { | ||
query = query[key].apply(query, arguments); | ||
return query; | ||
} | ||
} | ||
break; | ||
case 'filter': | ||
Model.prototype[key] = function() { | ||
var query = new Query(this); | ||
if ((arguments.length === 1) | ||
&& (util.isPlainObject(arguments[0]))) { | ||
break; | ||
case 'filter': | ||
Model.prototype[key] = function() { | ||
var query = new Query(this); | ||
if ((arguments.length === 1) | ||
&& (util.isPlainObject(arguments[0]))) { | ||
// Optimize a filter with an object | ||
// We replace the first key that match an index name | ||
var filter = arguments[0]; | ||
// Optimize a filter with an object | ||
// We replace the first key that match an index name | ||
var filter = arguments[0]; | ||
var keys = Object.keys(filter).sort(); // Lexicographical order | ||
for(var i=0 ; i<keys.length; i++) { | ||
var index = keys[i]; | ||
var keys = Object.keys(filter).sort(); // Lexicographical order | ||
for(var i=0 ; i<keys.length; i++) { | ||
var index = keys[i]; | ||
if (this._getModel()._indexes[index] === true) { // Index found | ||
query = query.getAll(filter[index], {index: index}); | ||
delete filter[index]; | ||
break; | ||
if (this._getModel()._indexes[index] === true) { // Index found | ||
query = query.getAll(filter[index], {index: index}); | ||
delete filter[index]; | ||
break; | ||
} | ||
} | ||
} | ||
query = query[key].apply(query, arguments); | ||
return query; | ||
} | ||
query = query[key].apply(query, arguments); | ||
return query; | ||
break; | ||
default: | ||
Model.prototype[key] = function() { | ||
var query = new Query(this); | ||
query = query[key].apply(query, arguments); | ||
return query; | ||
} | ||
} | ||
break; | ||
default: | ||
Model.prototype[key] = function() { | ||
var query = new Query(this); | ||
query = query[key].apply(query, arguments); | ||
return query; | ||
} | ||
} | ||
})(key); | ||
} | ||
} | ||
})(key); | ||
} | ||
}); | ||
})(); | ||
@@ -1328,18 +1336,8 @@ Model.prototype.getJoin = function() { | ||
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; | ||
Model.prototype.pre = function(ev, fn) { | ||
if (typeof fn !== "function") { | ||
throw new Error("Second argument to `pre` must be a function"); | ||
} | ||
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 (fn.length > 1) { | ||
throw new Error("Second argument to `pre` must be a function with at most one argument."); | ||
} | ||
@@ -1349,23 +1347,12 @@ if (Array.isArray(this._pre[ev]) === false) { | ||
} | ||
if (isAsync === true) { | ||
this._getModel()._async[ev] = true; | ||
} | ||
this._getModel()._async[ev] = this._getModel()._async[ev] || (fn.length === 1) | ||
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; | ||
Model.prototype.post = function(ev, fn) { | ||
if (typeof fn !== "function") { | ||
throw new Error("Second argument to `pre` must be a function"); | ||
} | ||
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 (fn.length > 1) { | ||
throw new Error("Second argument to `pre` must be a function with at most one argument."); | ||
} | ||
@@ -1375,9 +1362,6 @@ if (Array.isArray(this._post[ev]) === false) { | ||
} | ||
if (isAsync === true) { | ||
this._getModel()._async[ev] = true; | ||
} | ||
this._getModel()._async[ev] = this._getModel()._async[ev] || (fn.length === 1) | ||
this._getModel()._post[ev].push(fn); | ||
} | ||
module.exports = Model; |
@@ -11,10 +11,9 @@ var Promise = require('bluebird'); | ||
this._r = model._getModel()._thinky.r; | ||
for (var key in model._staticMethods) { | ||
(function(key) { | ||
self[key] = function() { | ||
return model._staticMethods[key].apply(self, arguments); | ||
util.loopKeys(model._getModel()._staticMethods, function(staticMethods, key) { | ||
(function(_key) { | ||
self[_key] = function() { | ||
return staticMethods[_key].apply(self, arguments); | ||
}; | ||
})(key); | ||
} | ||
}); | ||
} | ||
@@ -51,7 +50,5 @@ | ||
var fullOptions = {groupFormat: 'raw'} | ||
for(var key in options) { | ||
if (options.hasOwnProperty(key)) { | ||
fullOptions[key] = options[key] | ||
} | ||
} | ||
util.loopKeys(options, function(options, key) { | ||
fullOptions[key] = options[key] | ||
}); | ||
if (parse !== true) { | ||
@@ -130,10 +127,3 @@ fullOptions.cursor = true; | ||
} | ||
if (typeof callback === 'function') { | ||
p.then(function(result) { | ||
callback(null, result); | ||
}).error(function(error) { | ||
callback(error); | ||
}); | ||
} | ||
return p; | ||
return p.nodeify(callback); | ||
} | ||
@@ -176,4 +166,4 @@ | ||
for(var key in joins) { | ||
if (((getAll === true) || (key in modelToGet)) && ((getAll === false) || (gotModel[joins[key].model.getTableName()] !== true))) { | ||
util.loopKeys(joins, function(joins, key) { | ||
if (util.recurse(key, joins, modelToGet, getAll, gotModel)) { | ||
if (joins[key].type === 'hasOne') { | ||
@@ -289,3 +279,3 @@ self._query = self._query.merge(function(doc) { | ||
} | ||
} | ||
}); | ||
@@ -297,24 +287,29 @@ return self; | ||
throw new Error("The method `then` is not defined on Query. Did you forgot `.run()` or `.execute()`?") | ||
} | ||
}; | ||
// Import rethinkdbdash methods | ||
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__; | ||
for(var key in Term) { | ||
if ((Term.hasOwnProperty(key)) && (key !== 'run') && (key[0] !== '_')) { | ||
if (key === 'get') { | ||
(function(key) { | ||
Query.prototype[key] = function() { | ||
return new Query(this._model, this._query[key].apply(this._query, arguments)).default(this._r.error("The query did not find a document and returned null.")); | ||
} | ||
})(key); | ||
(function() { | ||
// Import rethinkdbdash methods | ||
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__; | ||
util.loopKeys(Term, function(Term, key) { | ||
// Note: We suppose that no method has an empty name | ||
if ((key !== 'run') && (key[0] !== '_')) { | ||
if (key === 'get') { | ||
(function(key) { | ||
Query.prototype[key] = function() { | ||
return new Query(this._model, this._query[key].apply(this._query, arguments)).default(this._r.error("The query did not find a document and returned null.")); | ||
} | ||
})(key); | ||
} | ||
else { | ||
(function(key) { | ||
Query.prototype[key] = function() { | ||
// Create a new query to let people fork it | ||
return new Query(this._model, this._query[key].apply(this._query, arguments)); | ||
} | ||
})(key); | ||
} | ||
} | ||
else { | ||
(function(key) { | ||
Query.prototype[key] = function() { | ||
return new Query(this._model, this._query[key].apply(this._query, arguments)); | ||
} | ||
})(key); | ||
} | ||
} | ||
} | ||
}); | ||
})(); | ||
@@ -321,0 +316,0 @@ Query.prototype.toString = function() { |
@@ -87,5 +87,5 @@ var rethinkdbdash = require('rethinkdbdash'); | ||
options = options || {}; | ||
for(var key in options) { | ||
util.loopKeys(options, function(options, key) { | ||
fullOptions[key] = options[key]; | ||
} | ||
}); | ||
@@ -144,1 +144,7 @@ if (self.models[name] !== undefined) { | ||
} | ||
// Internal use only, to speed up testing | ||
Thinky.prototype._clean = function() { | ||
this.models = {}; | ||
} | ||
305
lib/util.js
var util = require('util'); | ||
var Promise = require('bluebird'); | ||
var EventEmitter = require('events').EventEmitter; | ||
@@ -9,82 +10,2 @@ function isPlainObject(obj) { | ||
function validateSchema(schema, prefix) { | ||
// Validate a schema and add the field _enum if needed | ||
prefix = prefix || ''; | ||
if (isPlainObject(schema)) { | ||
for(var key in schema) { | ||
if (Array.isArray(schema[key])) { | ||
validateSchema(schema[key], prefix+'['+key+']'); | ||
} | ||
else if (isPlainObject(schema[key])) { | ||
if (schema[key].hasOwnProperty('_type')) { | ||
if ((schema[key]._type !== String) | ||
&& (schema[key]._type !== Number) | ||
&& (schema[key]._type !== Boolean) | ||
&& (schema[key]._type !== Date) | ||
&& (schema[key]._type !== Buffer) | ||
&& (schema[key]._type !== Object) | ||
&& (schema[key]._type !== Array) | ||
&& (schema[key]._type !== 'Point') | ||
&& (schema[key]._type !== 'virtual')) { | ||
throw new Error("The field `_type` must be `String`/`Number`/`Boolean`/`Date`/`Buffer`/`Object`/`Array`/`'virtual'`/`'Point'` for "+prefix+"["+key+"]"); | ||
} | ||
// Add the set with the valid values for an enum | ||
if (Array.isArray(schema[key].enum)) { | ||
schema[key]._enum = {} | ||
for(var i=0; i<schema[key].enum.length; i++) { | ||
schema[key]._enum[schema[key].enum[i]] = true; | ||
} | ||
} | ||
} | ||
else { | ||
validateSchema(schema[key], prefix+'['+key+']'); | ||
} | ||
} | ||
else if ((schema[key] !== String) | ||
&& (schema[key] !== Number) | ||
&& (schema[key] !== Boolean) | ||
&& (schema[key] !== Date) | ||
&& (schema[key] !== Buffer) | ||
&& (schema[key] !== Object) | ||
&& (schema[key] !== Array) | ||
&& (schema[key] !== 'Point') | ||
&& (schema[key] !== 'virtual')) { | ||
throw new Error("The value must be `String`/`Number`/`Boolean`/`Date`/`Buffer`/`Object`/`Array`/`'virtual'`/`'Point'` for "+prefix+"["+key+"]"); | ||
} | ||
} | ||
} | ||
else if (Array.isArray(schema)) { | ||
if (schema.length > 1) { | ||
throw new Error("An array in a schema can have at most one element. Found "+schema.length+" elements in "+prefix) | ||
} | ||
else if (schema.length === 1) { | ||
if (isPlainObject(schema[0])) { | ||
validateSchema(schema[0], prefix+'[0]'); | ||
} | ||
else if (Array.isArray(schema[0])) { | ||
validateSchema(schema[0], prefix+'[0]'); | ||
} | ||
else{ | ||
if ((schema[0] !== String) | ||
&& (schema[0] !== Number) | ||
&& (schema[0] !== Boolean) | ||
&& (schema[0] !== Date) | ||
&& (schema[0] !== Buffer) | ||
&& (schema[0] !== Object) | ||
&& (schema[0] !== Array) | ||
&& (schema[0] !== 'Point')) { | ||
throw new Error("The field `_type` must be `String`/`Number`/`Boolean`/`Date`/`Buffer`/`Object`/`Array`/`'Point'` in "+prefix); | ||
} | ||
} | ||
} | ||
} | ||
else { | ||
throw new Error("The schema must be a plain object.") | ||
} | ||
} | ||
util.validateSchema = validateSchema; | ||
// Obviously not a real deep copy... | ||
@@ -100,7 +21,7 @@ function deepCopy(value) { | ||
result = {}; | ||
for(var key in value) { | ||
if (value.hasOwnProperty(key)) { | ||
result[key] = deepCopy(value[key]); | ||
loopKeys(value, function(_value, key) { | ||
if (_value.hasOwnProperty(key)) { | ||
result[key] = deepCopy(_value[key]); | ||
} | ||
} | ||
}); | ||
return result; | ||
@@ -121,31 +42,3 @@ } | ||
function undefinedField(prefix) { | ||
throw new Error("Value for "+prefix+" must be defined.") | ||
} | ||
util.undefinedField = undefinedField; | ||
function strictType(prefix, expected) { | ||
throw new Error("Value for "+prefix+" must be a "+expected+".") | ||
} | ||
util.strictType = strictType; | ||
function extraField(prefix, key) { | ||
if (prefix === '') { | ||
throw new Error("Extra field `"+key+"` not allowed.") | ||
} | ||
else { | ||
throw new Error("Extra field `"+key+"` in "+prefix+" not allowed.") | ||
} | ||
} | ||
util.extraField = extraField; | ||
function looseType(prefix, expected) { | ||
throw new Error("Value for "+prefix+" must be a "+expected+" or null.") | ||
} | ||
util.looseType = looseType; | ||
function pseudoTypeError(type, missingField, prefix) { | ||
throw new Error("The raw "+type+" object for "+prefix+" is missing the required field "+missingField+".") | ||
} | ||
util.pseudoTypeError = pseudoTypeError; | ||
function tryCatch(toTry, handleError) { | ||
@@ -167,10 +60,17 @@ try{ | ||
var preHooks = options.preHooks; | ||
if (Array.isArray(preHooks) === false) { | ||
preHooks = []; | ||
} | ||
var postHooks = options.postHooks; | ||
if (Array.isArray(postHooks) === false) { | ||
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 | ||
var fnArgs = options.fnArgs; | ||
if (async === true) { | ||
return new Promise(function(resolve, reject) { | ||
_hook({ | ||
_asyncHook({ | ||
resolve: resolve, | ||
@@ -181,3 +81,4 @@ reject: reject, | ||
doc: doc, | ||
fn: fn | ||
fn: fn, | ||
fnArgs: fnArgs | ||
}); | ||
@@ -187,88 +88,130 @@ }); | ||
else { | ||
return _hook(options); | ||
return _syncHook({ | ||
preHooks: preHooks, | ||
postHooks: postHooks, | ||
doc: doc, | ||
fn: fn, | ||
fnArgs: fnArgs | ||
}); | ||
} | ||
} | ||
function _hook(options) { | ||
var doc = options.doc; | ||
function _syncHook(args) { | ||
var preHooks = args.preHooks; | ||
var postHooks = args.postHooks; | ||
var fn = args.fn; | ||
var doc = args.doc; | ||
var fnArgs = args.fnArgs; | ||
var preHooks = options.preHooks; | ||
var postHooks = options.postHooks; | ||
for(var i=0; i<preHooks.length; i++) { | ||
preHooks[i].call(doc); | ||
} | ||
var result = fn.apply(doc, fnArgs); | ||
for(var j=0; j<postHooks.length; j++) { | ||
postHooks[j].call(doc); | ||
} | ||
return result; | ||
} | ||
function _asyncHook(args) { | ||
// One of the hook, or the function is asynchronous, so we will | ||
// always return a promise | ||
// We only need to keep track of the result return/resolved for fn | ||
var fn = options.fn; | ||
var resolve = options.resolve; | ||
var reject = options.reject; | ||
var preHooks = args.preHooks; | ||
var postHooks = args.postHooks; | ||
var fn = args.fn; | ||
var fnArgs = args.fnArgs; | ||
var doc = args.doc; | ||
var resolve = args.resolve; | ||
var reject = args.reject; | ||
var args = args.args; | ||
var promise, result; | ||
var 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() | ||
}); | ||
var nextPost = function() { | ||
if (typeof resolve === "function") { | ||
resolve(result); | ||
} | ||
return result; | ||
} | ||
var executeMain = function() { | ||
result = fn.apply(doc, fnArgs); | ||
if (result instanceof Promise) { | ||
return result.then(function(res) { | ||
result = res; | ||
executeHooks(0, postHooks, doc, reject, nextPost); | ||
}).error(reject); | ||
} | ||
else { | ||
if (typeof resolve === 'function') { | ||
resolve(result); | ||
} | ||
return executeHooks(0, postHooks, doc, reject, nextPost); | ||
} | ||
} | ||
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() | ||
var nextPre = function() { | ||
tryCatch(executeMain, function (err) { | ||
return reject(err); | ||
}); | ||
} | ||
return executeHooks(0, preHooks, doc, reject, nextPre); | ||
} | ||
util.hook = hook; | ||
function executeHooks(hookIndex, hooks, doc, reject, next) { | ||
if (hookIndex < hooks.length) { | ||
if (hooks[hookIndex].length === 1) { | ||
hooks[hookIndex].call(doc, function(err) { | ||
if (err) return reject(err); | ||
executeHooks(hookIndex+1, hooks, doc, reject, next) | ||
}); | ||
} | ||
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(); | ||
} | ||
hooks[hookIndex](doc); | ||
executeHooks(hookIndex+1, hooks, doc, reject, next) | ||
} | ||
} | ||
executePreHooks(); | ||
if ((typeof resolve !== 'function') && (promise instanceof Promise)) { | ||
// No hook is asynchronous, but `fn` returned a promise | ||
return promise; | ||
else { | ||
next(); | ||
} | ||
} | ||
util.hook = hook; | ||
function loopKeys(obj, fn) { | ||
if (isPlainObject(obj)) { | ||
var keys = Object.keys(obj); | ||
var result; | ||
for(var i=0; i<keys.length; i++) { | ||
result = fn(obj, keys[i]); | ||
if (result === false) return; | ||
} | ||
} | ||
} | ||
util.loopKeys = loopKeys; | ||
function changeProto(object, newProto) { | ||
object.__proto__ = newProto; | ||
} | ||
util.changeProto = changeProto; | ||
function recurse(key, joins, modelTo, all, done) { | ||
return (util.isPlainObject(modelTo) && modelTo.hasOwnProperty(key)) | ||
|| ((all === true) && (done[joins[key].model.getTableName()] !== true)) | ||
} | ||
util.recurse = recurse; | ||
function bindEmitter(self) { | ||
util.loopKeys(EventEmitter.prototype, function(emitter, key) { | ||
var fn = emitter[key]; | ||
if (typeof fn === 'function') { | ||
self[key] = function() { | ||
var args = new Array(arguments.length); | ||
for(var i = 0; i < arguments.length; i++) { | ||
args[i] = arguments[i]; | ||
} | ||
fn.apply(self, args); | ||
} | ||
} | ||
}); | ||
} | ||
util.bindEmitter = bindEmitter; | ||
module.exports = util; |
{ | ||
"name": "thinky", | ||
"version": "1.15.0", | ||
"version": "1.15.1", | ||
"description": "RethinkDB ORM for Node.js", | ||
@@ -10,3 +10,3 @@ "main": "lib/thinky.js", | ||
"scripts": { | ||
"test": "mocha --check-leaks -t 30000" | ||
"test": "mocha --check-leaks -t 5000" | ||
}, | ||
@@ -13,0 +13,0 @@ "repository": { |
@@ -73,3 +73,3 @@ # Thinky | ||
```js | ||
Post.get("0e4a6f6f-cc0c-4aa5-951a-fcfc480dd05a").getJoin().then(function(result) { | ||
Post.get("0e4a6f6f-cc0c-4aa5-951a-fcfc480dd05a").getJoin().run().then(function(result) { | ||
/* | ||
@@ -109,6 +109,7 @@ result = { | ||
### Roadmap | ||
- Make the tests faster (by using less tables) | ||
- Merge write queries into a unique one? | ||
The roadmap is defined with the issues/feedback on GitHub. Checkout: | ||
[https://github.com/neumino/thinky/issues](https://github.com/neumino/thinky/issues) | ||
### Author | ||
@@ -120,2 +121,3 @@ - Michel Tu -- orphee@gmail.com -- [blog](http://blog.justonepixel.com) -- [twitter](https://twitter.com/neumino) | ||
- [colprog](https://github.com/colprog) | ||
- [dulichan](https://github.com/dulichan) | ||
- [flienteen](https://github.com/flienteen) | ||
@@ -122,0 +124,0 @@ - [marshall007](https://github.com/marshall007) |
Sorry, the diff of this file is too big to display
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
145
154164
3539