@@ -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+
164298Model . 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 ( ) ;
0 commit comments