Skip to content

Commit e3d694e

Browse files
committed
Added additional hooks, and a better hooking system
1 parent 3891b2b commit e3d694e

File tree

4 files changed

+322
-60
lines changed

4 files changed

+322
-60
lines changed

lib/Instance.js

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -125,23 +125,25 @@ function Instance(model, doc, isNew) {
125125
if (!cb) cb = function () { };
126126

127127
var createObject = function (callback) {
128-
129128
var createDoc = _.cloneDeep(newDoc);
130-
model.toSource(createDoc);
131129

132-
model.collection.insert(createDoc, { w: 1 }, function (err, inserted) {
130+
model.onCreating(createDoc, function(err) {
133131
if (err) return callback(err);
134132

135-
inserted = inserted[0];
136-
model.fromSource(inserted);
137-
138-
oldDoc = newDoc = inserted;
139-
140-
addSchemaProperties();
141-
142-
isNew = false;
143-
144-
return callback(null, $);
133+
model.toSource(createDoc);
134+
135+
model.collection.insert(createDoc, { w: 1 }, function (err, inserted) {
136+
if (err) return callback(err);
137+
138+
isNew = false;
139+
return model.onRetrieved(inserted[0], callback, function(value) {
140+
model.fromSource(value);
141+
oldDoc = _.cloneDeep(value);
142+
newDoc = _.cloneDeep(value);
143+
addSchemaProperties();
144+
return $;
145+
});
146+
});
145147
});
146148
};
147149

@@ -160,32 +162,31 @@ function Instance(model, doc, isNew) {
160162

161163
var conditions = model.uniqueConditions(newDoc);
162164

163-
model.collection.update(conditions, changes, { w: 1 }, function (err, updateCount) {
164-
if (err) return cb(err);
165-
166-
if (updateCount > 0) {
167-
model.collection.findOne(conditions, function (err, updated) {
168-
if (err) return cb(err);
169-
170-
model.fromSource(updated);
171-
172-
newDoc = _.cloneDeep(updated);
173-
oldDoc = _.cloneDeep(updated);
174-
175-
addSchemaProperties();
176-
177-
return cb(null, $);
178-
});
179-
} else return cb(null, $);
180-
});
165+
model.onSaving($, changes, function(err) {
166+
if(err) return cb(err);
167+
168+
model.collection.update(conditions, changes, { w: 1 }, function (err, updateCount) {
169+
if (err) return cb(err);
170+
171+
if (updateCount > 0) {
172+
model.collection.findOne(conditions, function (err, updated) {
173+
if (err) return cb(err);
174+
175+
return model.onRetrieved(updated, cb, function(value) {
176+
model.fromSource(value);
177+
oldDoc = _.cloneDeep(value);
178+
newDoc = _.cloneDeep(value);
179+
addSchemaProperties();
180+
return $;
181+
});
182+
});
183+
} else return cb(null, $);
184+
});
185+
});
181186
};
182187

183188
if (!isNew) return runOptions();
184-
else createObject(function (err) {
185-
if (err) return cb(err);
186-
if (Object.keys(changes).length > 0) runOptions(cb);
187-
else return cb(null, $);
188-
});
189+
else createObject(cb);
189190
}
190191
else return cb(null, $);
191192
},
@@ -206,14 +207,13 @@ function Instance(model, doc, isNew) {
206207

207208
model.collection.findOne(conditions, function (err, updated) {
208209
if (err) return cb(err);
209-
210-
model.fromSource(updated);
211-
212-
oldDoc = newDoc = updated;
213-
214-
addSchemaProperties();
215-
216-
if(callback) return callback(null, $);
210+
return model.onRetrieved(updated,callback, function(value) {
211+
model.fromSource(value);
212+
oldDoc = _.cloneDeep(value);
213+
newDoc = _.cloneDeep(value);
214+
addSchemaProperties();
215+
return $;
216+
});
217217
});
218218
}
219219
});

lib/Model.js

Lines changed: 139 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ Model.prototype.downstreamID = function(id) {
121121
/// </signature>
122122
/// <signature>
123123
/// <summary>Gets the set of conditions representing the downstream _id field for the given downstream identifier</summary>
124-
/// <param name="id" type="Mixed">The identifier to created the conditions from</param>
124+
/// <param name="id" type="Mixed">The identifier to create the conditions from</param>
125125
/// <returns type="Object"/>
126126
/// </signature>
127127

@@ -161,6 +161,140 @@ Model.prototype.wrap = function (document, isNew) {
161161
return new Instance(this, document, isNew);
162162
};
163163

164+
Model.prototype.onRetrieved = function(results, callback, wrapper) {
165+
///<signature>
166+
///<summary>Handles any post-receive hooks and the wrapping of objects from the database</summary>
167+
///<param name="results" type="Object">The object retrieved from the database</param>
168+
///<param name="callback" type="Function">The function to be called once the objects have been wrapped</param>
169+
///</signature>
170+
///<signature>
171+
///<summary>Handles any post-receive hooks and the wrapping of objects from the database</summary>
172+
///<param name="results" type="Array" elementType="Object">The objects retrieved from the database</param>
173+
///<param name="callback" type="Function">The function to be called once the objects have been wrapped</param>
174+
///</signature>
175+
///<signature>
176+
///<summary>Handles any post-receive hooks and the wrapping of objects from the database</summary>
177+
///<param name="results" type="Object">The object retrieved from the database</param>
178+
///<param name="callback" type="Function">The function to be called once the objects have been wrapped</param>
179+
///<param name="wrapper" type="Function">A function which converts the retrieved objects prior to submission</param>
180+
///</signature>
181+
///<signature>
182+
///<summary>Handles any post-receive hooks and the wrapping of objects from the database</summary>
183+
///<param name="results" type="Array" elementType="Object">The objects retrieved from the database</param>
184+
///<param name="callback" type="Function">The function to be called once the objects have been wrapped</param>
185+
///<param name="wrapper" type="Function">A function which converts the retrieved objects prior to submission</param>
186+
///</signature>
187+
188+
var $ = this;
189+
wrapper = wrapper || this.wrap.bind(this);
190+
191+
var toProcess = results;
192+
193+
var output = [];
194+
var errors = [];
195+
var remaining = 1;
196+
197+
if(!Array.isArray(toProcess)) toProcess = [toProcess];
198+
199+
function doHook(hook, target, next) {
200+
if(!hook) return next();
201+
if(hook.length === 0) {
202+
try {
203+
hook.call(target);
204+
return next();
205+
} catch(err) {
206+
return next(err);
207+
}
208+
} else {
209+
hook.call(target, next);
210+
}
211+
}
212+
213+
function onComplete() {
214+
remaining--;
215+
if(remaining === 0) {
216+
if(Array.isArray(results)) {
217+
for(var i = 0; i < errors.length; i++)
218+
if(errors[i]) return callback(errors[i]);
219+
return callback(null, output);
220+
} else {
221+
return callback(errors[0], output[0]);
222+
}
223+
}
224+
}
225+
226+
function process(target) {
227+
doHook($.options.hooks.retrieved, target, function(err) {
228+
if(err) {
229+
errors.push(err);
230+
output.push(null);
231+
return onComplete();
232+
}
233+
234+
var wrapped = wrapper(target);
235+
236+
doHook($.options.hooks.ready, wrapped, function(err) {
237+
if(err) {
238+
errors.push(err);
239+
output.push(null);
240+
return onComplete();
241+
}
242+
243+
errors.push(null);
244+
output.push(wrapped);
245+
return onComplete();
246+
});
247+
});
248+
}
249+
for(var i = 0; i < toProcess.length; i++) {
250+
remaining++;
251+
process(toProcess[i]);
252+
}
253+
254+
return onComplete();
255+
};
256+
257+
Model.prototype.onCreating = function(document, callback) {
258+
function doHook(hook, target, args, next) {
259+
if(!hook) return next();
260+
if(hook.length === 0) {
261+
try {
262+
hook.apply(target, args);
263+
return next();
264+
} catch(err) {
265+
return next(err);
266+
}
267+
} else {
268+
args.push(next);
269+
hook.apply(target, args);
270+
}
271+
}
272+
273+
doHook(this.options.hooks.creating || this.options.hooks.beforeCreate, document, [], callback);
274+
};
275+
276+
Model.prototype.onSaving = function(instance, changes, callback) {
277+
278+
function doHook(hook, target, args, next) {
279+
if(!hook) return next();
280+
if(hook.length === 0) {
281+
try {
282+
hook.apply(target, args);
283+
return next();
284+
} catch(err) {
285+
return next(err);
286+
}
287+
} else {
288+
args.push(next);
289+
hook.apply(target, args);
290+
}
291+
}
292+
293+
var $ = this;
294+
295+
doHook($.options.hooks.saving, instance, [changes], callback);
296+
};
297+
164298
Model.prototype.find = function (conditions, callback) {
165299
/// <signature>
166300
/// <summary>Gets all objects in the collection.</summary>
@@ -189,7 +323,7 @@ Model.prototype.find = function (conditions, callback) {
189323
this.collection.find(conditions).toArray(function (err, results) {
190324
if (err) return callback(err);
191325
if (!results) return callback(null, null);
192-
return callback(null, _.map(results, function (result) { return $.wrap(result, false); }, $));
326+
return $.onRetrieved(results, callback);
193327
});
194328
};
195329

@@ -223,7 +357,7 @@ Model.prototype.findOne = Model.prototype.get = function (conditions, callback)
223357
if (err) return callback(err);
224358
if (!results) return callback(null, null);
225359

226-
return callback(null, $.wrap.call($, results));
360+
return $.onRetrieved(results, callback);
227361
});
228362
};
229363

@@ -256,7 +390,6 @@ Model.prototype.insert = Model.prototype.create = function (object, callback) {
256390
returnArray = false;
257391
}
258392

259-
260393
var prepped = [];
261394

262395
var end = function(err, results) {
@@ -273,7 +406,7 @@ Model.prototype.insert = Model.prototype.create = function (object, callback) {
273406
var prepComplete = function() {
274407
$.collection.insert(prepped, { w: callback ? 1 : 0 }, function(err, inserted) {
275408
if(err) return end(err);
276-
return end(null, inserted.map(function(item) { return $.wrap(item, false); }));
409+
return $.onRetrieved(inserted, end);
277410
});
278411
};
279412

@@ -297,16 +430,7 @@ Model.prototype.insert = Model.prototype.create = function (object, callback) {
297430
return prepNext();
298431
}
299432

300-
// Run the beforeCreate hook
301-
if($.options.hooks.beforeCreate) {
302-
if($.options.hooks.beforeCreate.length > 0) return $.options.hooks.beforeCreate.call(obj, postHook);
303-
else try {
304-
$.options.hooks.beforeCreate.call(obj);
305-
postHook();
306-
} catch(ex) {
307-
postHook(ex);
308-
}
309-
} else postHook();
433+
$.onCreating(obj, postHook);
310434
};
311435

312436
prepNext();

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "iridium",
3-
"version": "2.4.3",
3+
"version": "2.5.0",
44
"author": "Benjamin Pannell <admin@sierrasoftworks.com>",
55
"description": "A custom lightweight ORM for MongoDB designed for power-users",
66
"homepage": "https://sierrasoftworks.com/iridium",

0 commit comments

Comments
 (0)