Skip to content

Operation hooks improvements #486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 88 additions & 55 deletions lib/dao.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ 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) {
Expand All @@ -230,7 +231,8 @@ DataAccessObject.create = function (data, options, cb) {
Model = this.lookupModel(data); // data-specific
if (Model !== obj.constructor) obj = new Model(data);

Model.notifyObserversOf('before save', { Model: Model, instance: obj }, function(err) {
var context = { Model: Model, instance: obj, hookState: hookState };
Model.notifyObserversOf('before save', context, function(err) {
if (err) return cb(err);

data = obj.toObject(true);
Expand Down Expand Up @@ -268,7 +270,8 @@ DataAccessObject.create = function (data, options, cb) {
if (err) {
return cb(err, obj);
}
Model.notifyObserversOf('after save', { Model: Model, instance: obj }, function(err) {
var context = { Model: Model, instance: obj, hookState: hookState };
Model.notifyObserversOf('after save', context, function(err) {
cb(err, obj);
if(!err) Model.emit('changed', obj);
});
Expand Down Expand Up @@ -345,20 +348,27 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data

var self = this;
var Model = this;
var hookState = {};

var id = getIdValue(this, data);
if (!id) {
return this.create(data, options, cb);
}

Model.notifyObserversOf('access', { Model: Model, query: byIdQuery(Model, id) }, doUpdateOrCreate);
var context = { Model: Model, query: byIdQuery(Model, id), hookState: hookState };
Model.notifyObserversOf('access', context, doUpdateOrCreate);

function doUpdateOrCreate(err, ctx) {
if (err) return cb(err);

var isOriginalQuery = isWhereByGivenId(Model, ctx.query.where, id)
if (Model.getDataSource().connector.updateOrCreate && isOriginalQuery) {
var context = { Model: Model, where: ctx.query.where, data: data };
var context = {
Model: Model,
where: ctx.query.where,
data: data,
hookState: hookState
};
Model.notifyObserversOf('before save', context, function(err, ctx) {
if (err) return cb(err);

Expand Down Expand Up @@ -394,7 +404,8 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
Model.emit('changed', inst);
}
} else {
Model.notifyObserversOf('after save', { Model: Model, instance: obj }, function(err) {
var context = { Model: Model, instance: obj, hookState: hookState };
Model.notifyObserversOf('after save', context, function(err) {
cb(err, obj);
if(!err) {
Model.emit('changed', inst);
Expand Down Expand Up @@ -478,6 +489,7 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)

var Model = this;
var self = this;
var hookState = {};

function _findOrCreate(query, data) {
var modelName = self.modelName;
Expand All @@ -493,8 +505,8 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
}

if (created) {
Model.notifyObserversOf('after save', { Model: Model, instance: obj },
function(err) {
var context = { Model: Model, instance: obj, hookState: hookState };
Model.notifyObserversOf('after save', context, function(err) {
if (cb.promise) {
cb(err, [obj, created]);
} else {
Expand Down Expand Up @@ -526,8 +538,8 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)

this.applyScope(query);

Model.notifyObserversOf('access', { Model: Model, query: query },
function (err, ctx) {
var context = { Model: Model, query: query, hookState: hookState };
Model.notifyObserversOf('access', context, function (err, ctx) {
if (err) return cb(err);

var query = ctx.query;
Expand All @@ -539,8 +551,8 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
Model.applyProperties(enforced, obj);
obj.setAttributes(enforced);

Model.notifyObserversOf('before save', { Model: Model, instance: obj },
function(err, ctx) {
var context = { Model: Model, instance: obj, hookState: hookState };
Model.notifyObserversOf('before save', context, function(err, ctx) {
if (err) return cb(err);

var obj = ctx.instance;
Expand Down Expand Up @@ -1081,6 +1093,7 @@ DataAccessObject.find = function find(query, options, cb) {
assert(typeof cb === 'function', 'The cb argument must be a function');

var self = this;
var hookState = {};

try {
this._normalize(query);
Expand All @@ -1105,7 +1118,8 @@ DataAccessObject.find = function find(query, options, cb) {
// using all documents
// TODO [fabien] use default scope here?

self.notifyObserversOf('access', { Model: self, query: query }, function(err, ctx) {
var context = { Model: self, query: query, hookState: hookState };
self.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err);

self.getDataSource().connector.all(self.modelName, {}, function (err, data) {
Expand Down Expand Up @@ -1199,7 +1213,8 @@ DataAccessObject.find = function find(query, options, cb) {
if (options.notify === false) {
self.getDataSource().connector.all(self.modelName, query, allCb);
} else {
this.notifyObserversOf('access', { Model: this, query: query }, function(err, ctx) {
var context = { Model: this, query: query, hookState: hookState };
this.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err);
var query = ctx.query;
self.getDataSource().connector.all(self.modelName, query, allCb);
Expand Down Expand Up @@ -1296,16 +1311,20 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
this.applyScope(query);
where = query.where;

var context = { Model: Model, where: whereIsEmpty(where) ? {} : where };
var hookState = {};

var context = {
Model: Model, where: whereIsEmpty(where) ? {} : where, hookState: hookState
};

if (options.notify === false) {
doDelete(where);
} else {
query = { where: whereIsEmpty(where) ? {} : where };
Model.notifyObserversOf('access',
{ Model: Model, query: query },
function(err, ctx) {
var context = { Model: Model, query: query, hookState: hookState };
Model.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err);
var context = { Model: Model, where: ctx.query.where };
var context = { Model: Model, where: ctx.query.where, hookState: hookState };
Model.notifyObserversOf('before delete', context, function(err, ctx) {
if (err) return cb(err);
doDelete(ctx.where);
Expand Down Expand Up @@ -1338,7 +1357,8 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
return cb(err, data);
}

Model.notifyObserversOf('after delete', { Model: Model, where: where }, function(err) {
var context = { Model: Model, where: where, hookState: hookState };
Model.notifyObserversOf('after delete', context, function(err) {
cb(err, data);
if (!err)
Model.emit('deletedAll', whereIsEmpty(where) ? undefined : where);
Expand Down Expand Up @@ -1459,7 +1479,10 @@ DataAccessObject.count = function (where, options, cb) {
}

var Model = this;
this.notifyObserversOf('access', { Model: Model, query: { where: where } }, function(err, ctx) {
var hookState = {};

var context = { Model: Model, query: { where: where }, hookState: hookState };
this.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err);
where = ctx.query.where;
Model.getDataSource().connector.count(Model.modelName, cb, where);
Expand Down Expand Up @@ -1506,8 +1529,10 @@ DataAccessObject.prototype.save = function (options, cb) {

var inst = this;
var modelName = Model.modelName;

Model.notifyObserversOf('before save', { Model: Model, instance: inst }, function(err) {
var hookState = {};

var context = { Model: Model, instance: inst, hookState: hookState };
Model.notifyObserversOf('before save', context, function(err) {
if (err) return cb(err);

var data = inst.toObject(true);
Expand Down Expand Up @@ -1542,7 +1567,8 @@ DataAccessObject.prototype.save = function (options, cb) {
return cb(err, inst);
}
inst._initProperties(data, { persisted: true });
Model.notifyObserversOf('after save', { Model: Model, instance: inst }, function(err) {
var context = { Model: Model, instance: inst, hookState: hookState };
Model.notifyObserversOf('after save', context, function(err) {
if (err) return cb(err, inst);
updateDone.call(inst, function () {
saveDone.call(inst, function () {
Expand Down Expand Up @@ -1625,16 +1651,15 @@ DataAccessObject.updateAll = function (where, data, options, cb) {
where = query.where;

var Model = this;
var hookState = {};

Model.notifyObserversOf('access', { Model: Model, query: { where: where } }, function(err, ctx) {
var context = { Model: Model, query: { where: where }, hookState: hookState };
Model.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err);
Model.notifyObserversOf(
'before save',
{
Model: Model,
where: ctx.query.where,
data: data
},
var context = {
Model: Model, where: ctx.query.where, data: data, hookState: hookState
};
Model.notifyObserversOf('before save', context,
function(err, ctx) {
if (err) return cb(err);
doUpdate(ctx.where, ctx.data);
Expand All @@ -1657,14 +1682,10 @@ DataAccessObject.updateAll = function (where, data, options, cb) {
var connector = Model.getDataSource().connector;
connector.update(Model.modelName, where, data, function(err, count) {
if (err) return cb (err);
Model.notifyObserversOf(
'after save',
{
Model: Model,
where: where,
data: data
},
function(err, ctx) {
var context = {
Model: Model, where: where, data: data, hookState: hookState
};
Model.notifyObserversOf('after save', context, function(err, ctx) {
return cb(err, count);
});
});
Expand Down Expand Up @@ -1711,19 +1732,21 @@ 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 self = this;
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.notifyObserversOf(
'access',
{ Model: Model, query: byIdQuery(Model, id) },
function(err, ctx) {
Model.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err);
Model.notifyObserversOf(
'before delete',
{ Model: Model, where: ctx.query.where },
function(err, ctx) {
var context = {
Model: Model, where: ctx.query.where, instance: inst, hookState: hookState
};
Model.notifyObserversOf('before delete', context, function(err, ctx) {
if (err) return cb(err);
doDeleteInstance(ctx.where);
});
Expand All @@ -1736,22 +1759,28 @@ DataAccessObject.prototype.remove =
// We must switch to full query-based delete.
Model.deleteAll(where, { notify: false }, function(err) {
if (err) return cb(err);
Model.notifyObserversOf('after delete', { Model: Model, where: where }, function(err) {
var context = {
Model: Model, where: where, instance: inst, hookState: hookState
};
Model.notifyObserversOf('after delete', context, function(err) {
cb(err);
if (!err) Model.emit('deleted', id);
});
});
return;
}

self.trigger('destroy', function (destroyed) {
self._adapter().destroy(self.constructor.modelName, id, function (err) {
inst.trigger('destroy', function (destroyed) {
inst._adapter().destroy(inst.constructor.modelName, id, function (err) {
if (err) {
return cb(err);
}

destroyed(function () {
Model.notifyObserversOf('after delete', { Model: Model, where: where }, function(err) {
var context = {
Model: Model, where: where, instance: inst, hookState: hookState
};
Model.notifyObserversOf('after delete', context, function(err) {
cb(err);
if (!err) Model.emit('deleted', id);
});
Expand Down Expand Up @@ -1858,7 +1887,8 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
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) {
data = data.toObject(false);
Expand All @@ -1868,7 +1898,9 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
var context = {
Model: Model,
where: byIdQuery(Model, getIdValue(Model, inst)).where,
data: data
data: data,
currentInstance: inst,
hookState: hookState
};

Model.notifyObserversOf('before save', context, function(err, ctx) {
Expand Down Expand Up @@ -1905,7 +1937,8 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
done.call(inst, function () {
saveDone.call(inst, function () {
if (err) return cb(err, inst);
Model.notifyObserversOf('after save', { Model: Model, instance: inst }, function(err) {
var context = { Model: Model, instance: inst, hookState: hookState };
Model.notifyObserversOf('after save', context, function(err) {
if(!err) Model.emit('changed', inst);
cb(err, inst);
});
Expand Down
Loading