Merge pull request #549 from fabien/feature/hookstate-from-options
Allow passing in hookState from options
This commit is contained in:
commit
44e5ad1fef
160
lib/dao.js
160
lib/dao.js
|
@ -178,6 +178,8 @@ DataAccessObject.create = function (data, options, cb) {
|
|||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
// Undefined item will be skipped by async.map() which internally uses
|
||||
// Array.prototype.map(). The following loop makes sure all items are
|
||||
|
@ -216,7 +218,6 @@ DataAccessObject.create = function (data, options, cb) {
|
|||
var enforced = {};
|
||||
var obj;
|
||||
var idValue = getIdValue(this, data);
|
||||
var hookState = {};
|
||||
|
||||
// if we come from save
|
||||
if (data instanceof Model && !idValue) {
|
||||
|
@ -235,7 +236,8 @@ DataAccessObject.create = function (data, options, cb) {
|
|||
Model: Model,
|
||||
instance: obj,
|
||||
isNewInstance: true,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('before save', context, function(err) {
|
||||
if (err) return cb(err);
|
||||
|
@ -279,7 +281,8 @@ DataAccessObject.create = function (data, options, cb) {
|
|||
Model: Model,
|
||||
instance: obj,
|
||||
isNewInstance: true,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after save', context, function(err) {
|
||||
cb(err, obj);
|
||||
|
@ -356,16 +359,22 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
|
|||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var self = this;
|
||||
var Model = this;
|
||||
var hookState = {};
|
||||
|
||||
var id = getIdValue(this, data);
|
||||
if (id === undefined || id === null) {
|
||||
return this.create(data, options, cb);
|
||||
}
|
||||
|
||||
var context = { Model: Model, query: byIdQuery(Model, id), hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
query: byIdQuery(Model, id),
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('access', context, doUpdateOrCreate);
|
||||
|
||||
function doUpdateOrCreate(err, ctx) {
|
||||
|
@ -377,7 +386,8 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
|
|||
Model: Model,
|
||||
where: ctx.query.where,
|
||||
data: data,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('before save', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
|
@ -418,7 +428,8 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
|
|||
Model: Model,
|
||||
instance: obj,
|
||||
isNewInstance: result ? result.isNewInstance : undefined,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after save', context, function(err) {
|
||||
cb(err, obj);
|
||||
|
@ -502,9 +513,10 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var Model = this;
|
||||
var self = this;
|
||||
var hookState = {};
|
||||
|
||||
function _findOrCreate(query, data) {
|
||||
var modelName = self.modelName;
|
||||
|
@ -524,7 +536,8 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
Model: Model,
|
||||
instance: obj,
|
||||
isNewInstance: true,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after save', context, function(err) {
|
||||
if (cb.promise) {
|
||||
|
@ -558,7 +571,12 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
|
||||
this.applyScope(query);
|
||||
|
||||
var context = { Model: Model, query: query, hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
query: query,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('access', context, function (err, ctx) {
|
||||
if (err) return cb(err);
|
||||
|
||||
|
@ -575,7 +593,8 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
Model: Model,
|
||||
instance: obj,
|
||||
isNewInstance: true,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('before save', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
|
@ -1117,8 +1136,8 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var self = this;
|
||||
var hookState = {};
|
||||
var self = this;
|
||||
|
||||
try {
|
||||
this._normalize(query);
|
||||
|
@ -1143,7 +1162,12 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
// using all documents
|
||||
// TODO [fabien] use default scope here?
|
||||
|
||||
var context = { Model: self, query: query, hookState: hookState };
|
||||
var context = {
|
||||
Model: self,
|
||||
query: query,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
self.notifyObserversOf('access', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
|
||||
|
@ -1238,7 +1262,12 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
if (options.notify === false) {
|
||||
self.getDataSource().connector.all(self.modelName, query, allCb);
|
||||
} else {
|
||||
var context = { Model: this, query: query, hookState: hookState };
|
||||
var context = {
|
||||
Model: this,
|
||||
query: query,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
this.notifyObserversOf('access', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
var query = ctx.query;
|
||||
|
@ -1327,29 +1356,42 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
|
|||
cb = cb || utils.createPromiseCallback();
|
||||
where = where || {};
|
||||
options = options || {};
|
||||
|
||||
|
||||
assert(typeof where === 'object', 'The where argument must be an object');
|
||||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var query = { where: where };
|
||||
this.applyScope(query);
|
||||
where = query.where;
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var context = {
|
||||
Model: Model, where: whereIsEmpty(where) ? {} : where, hookState: hookState
|
||||
Model: Model,
|
||||
where: whereIsEmpty(where) ? {} : where,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
|
||||
if (options.notify === false) {
|
||||
doDelete(where);
|
||||
} else {
|
||||
query = { where: whereIsEmpty(where) ? {} : where };
|
||||
var context = { Model: Model, query: query, hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
query: query,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('access', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
var context = { Model: Model, where: ctx.query.where, hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
where: ctx.query.where,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('before delete', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
doDelete(ctx.where);
|
||||
|
@ -1382,7 +1424,12 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
|
|||
return cb(err, info);
|
||||
}
|
||||
|
||||
var context = { Model: Model, where: where, hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
where: where,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after delete', context, function(err) {
|
||||
cb(err, info);
|
||||
if (!err)
|
||||
|
@ -1489,6 +1536,8 @@ DataAccessObject.count = function (where, options, cb) {
|
|||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var query = { where: where };
|
||||
this.applyScope(query);
|
||||
where = query.where;
|
||||
|
@ -1504,9 +1553,13 @@ DataAccessObject.count = function (where, options, cb) {
|
|||
}
|
||||
|
||||
var Model = this;
|
||||
var hookState = {};
|
||||
|
||||
var context = { Model: Model, query: { where: where }, hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
query: { where: where },
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
this.notifyObserversOf('access', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
where = ctx.query.where;
|
||||
|
@ -1540,6 +1593,8 @@ DataAccessObject.prototype.save = function (options, cb) {
|
|||
|
||||
assert(typeof options === 'object', 'The options argument should be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument should be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
if (options.validate === undefined) {
|
||||
options.validate = true;
|
||||
|
@ -1554,9 +1609,13 @@ DataAccessObject.prototype.save = function (options, cb) {
|
|||
|
||||
var inst = this;
|
||||
var modelName = Model.modelName;
|
||||
var hookState = {};
|
||||
|
||||
var context = { Model: Model, instance: inst, hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
instance: inst,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('before save', context, function(err) {
|
||||
if (err) return cb(err);
|
||||
|
||||
|
@ -1596,7 +1655,8 @@ DataAccessObject.prototype.save = function (options, cb) {
|
|||
Model: Model,
|
||||
instance: inst,
|
||||
isNewInstance: result && result.isNewInstance,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after save', context, function(err) {
|
||||
if (err) return cb(err, inst);
|
||||
|
@ -1674,6 +1734,8 @@ DataAccessObject.updateAll = function (where, data, options, cb) {
|
|||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var query = { where: where };
|
||||
this.applyScope(query);
|
||||
this.applyProperties(data);
|
||||
|
@ -1681,13 +1743,21 @@ DataAccessObject.updateAll = function (where, data, options, cb) {
|
|||
where = query.where;
|
||||
|
||||
var Model = this;
|
||||
var hookState = {};
|
||||
|
||||
var context = { Model: Model, query: { where: where }, hookState: hookState };
|
||||
var context = {
|
||||
Model: Model,
|
||||
query: { where: where },
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('access', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
var context = {
|
||||
Model: Model, where: ctx.query.where, data: data, hookState: hookState
|
||||
Model: Model,
|
||||
where: ctx.query.where,
|
||||
data: data,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('before save', context,
|
||||
function(err, ctx) {
|
||||
|
@ -1713,7 +1783,11 @@ DataAccessObject.updateAll = function (where, data, options, cb) {
|
|||
connector.update(Model.modelName, where, data, function(err, info) {
|
||||
if (err) return cb (err);
|
||||
var context = {
|
||||
Model: Model, where: where, data: data, hookState: hookState
|
||||
Model: Model,
|
||||
where: where,
|
||||
data: data,
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after save', context, function(err, ctx) {
|
||||
return cb(err, info);
|
||||
|
@ -1762,13 +1836,17 @@ DataAccessObject.prototype.remove =
|
|||
assert(typeof options === 'object', 'The options argument should be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument should be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var inst = this;
|
||||
var Model = this.constructor;
|
||||
var id = getIdValue(this.constructor, this);
|
||||
var hookState = {};
|
||||
|
||||
var context = {
|
||||
Model: Model, query: byIdQuery(Model, id), hookState: hookState
|
||||
Model: Model,
|
||||
query: byIdQuery(Model, id),
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
|
||||
Model.notifyObserversOf('access', context, function(err, ctx) {
|
||||
|
@ -1777,7 +1855,8 @@ DataAccessObject.prototype.remove =
|
|||
Model: Model,
|
||||
where: ctx.query.where,
|
||||
instance: inst,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('before delete', context, function(err, ctx) {
|
||||
if (err) return cb(err);
|
||||
|
@ -1796,7 +1875,8 @@ DataAccessObject.prototype.remove =
|
|||
Model: Model,
|
||||
where: where,
|
||||
instance: inst,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after delete', context, function(err) {
|
||||
cb(err);
|
||||
|
@ -1817,7 +1897,8 @@ DataAccessObject.prototype.remove =
|
|||
Model: Model,
|
||||
where: where,
|
||||
instance: inst,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after delete', context, function(err) {
|
||||
cb(err);
|
||||
|
@ -1944,10 +2025,11 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
|
|||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
var hookState = {};
|
||||
|
||||
var inst = this;
|
||||
var Model = this.constructor;
|
||||
var model = Model.modelName;
|
||||
var hookState = {};
|
||||
|
||||
// Convert the data to be plain object so that update won't be confused
|
||||
if (data instanceof Model) {
|
||||
|
@ -1974,7 +2056,8 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
|
|||
where: byIdQuery(Model, getIdValue(Model, inst)).where,
|
||||
data: data,
|
||||
currentInstance: inst,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
|
||||
Model.notifyObserversOf('before save', context, function(err, ctx) {
|
||||
|
@ -2015,7 +2098,8 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
|
|||
Model: Model,
|
||||
instance: inst,
|
||||
isNewInstance: false,
|
||||
hookState: hookState
|
||||
hookState: hookState,
|
||||
options: options
|
||||
};
|
||||
Model.notifyObserversOf('after save', context, function(err) {
|
||||
if(!err) Model.emit('changed', inst);
|
||||
|
|
|
@ -473,8 +473,8 @@ module.exports = function(dataSource, should) {
|
|||
observedContexts.should.eql(aTestModelCtx({ instance: {
|
||||
id: existingInstance.id,
|
||||
name: 'changed',
|
||||
extra: undefined
|
||||
}}));
|
||||
extra: undefined,
|
||||
}, options: { throws: false, validate: true } }));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -524,8 +524,8 @@ module.exports = function(dataSource, should) {
|
|||
name: 'changed',
|
||||
extra: undefined
|
||||
},
|
||||
isNewInstance: false
|
||||
}));
|
||||
isNewInstance: false,
|
||||
options: { throws: false, validate: true } }));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -1297,6 +1297,23 @@ module.exports = function(dataSource, should) {
|
|||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts hookState from options', function(done) {
|
||||
TestModel.observe('after save', pushContextAndNext());
|
||||
|
||||
TestModel.updateAll(
|
||||
{ id: existingInstance.id },
|
||||
{ name: 'updated name' },
|
||||
{ foo: 'bar' },
|
||||
function(err) {
|
||||
if (err) return done(err);
|
||||
observedContexts.options.should.eql({
|
||||
foo: 'bar'
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function pushContextAndNext(fn) {
|
||||
|
@ -1351,6 +1368,9 @@ module.exports = function(dataSource, should) {
|
|||
if (!ctx.hookState) {
|
||||
ctx.hookState = { test: true };
|
||||
}
|
||||
if (!ctx.options) {
|
||||
ctx.options = {};
|
||||
}
|
||||
return deepCloneToObject(ctx);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue