11var util = require ( 'util' )
22 , events = require ( 'events' )
3- , jsonpatch = require ( 'fast-json-patch' )
43 , uuid = require ( 'uuid' ) ;
54
65function Model ( db , name ) {
@@ -22,17 +21,19 @@ Model.prototype.post = function( data, cb /* error, resource */ ) {
2221 data . _id = uuid . v4 ( ) ;
2322 data . doctype = this . _name ;
2423
25- model . _db . post ( data , onComplete ) ;
24+ model . _db . post ( data , onCreate ) ;
2625
27- function onComplete ( err , info ) {
26+ function onCreate ( err , info ) {
2827 if ( err ) return handleError ( err , cb ) ;
2928
30- return cb && cb ( undefined , data ) ;
29+ model . get ( info . id , onComplete ) ;
3130 }
32- } ;
3331
34- Model . prototype . postMany = function ( updates , cb /* error, resources */ ) {
35- this . putMany ( updates , cb ) ;
32+ function onComplete ( err , resource ) {
33+ if ( err ) return handleError ( err , cb ) ;
34+
35+ return cb && cb ( undefined , resource ) ;
36+ }
3637} ;
3738
3839Model . prototype . put = function ( update , id , cb /* error, resource */ ) {
@@ -45,72 +46,110 @@ Model.prototype.put = function( update, id, cb /* error, resource */ ) {
4546
4647 update . doctype = model . _name ;
4748
48- model . _db . get ( id , function ( err , resource ) {
49+ model . get ( id , onFind ) ;
50+
51+ function onFind ( err , resource ) {
4952 if ( err ) return handleError ( err , cb ) ;
5053
51- model . _db . put ( update , id , resource . _rev , onComplete ) ;
54+ model . _db . put ( update , id , resource . _rev , onUpdate ) ;
55+ }
5256
53- update . _id = id ;
57+ function onUpdate ( err , info ) {
58+ if ( err ) return handleError ( err , cb ) ;
5459
55- function onComplete ( err , info ) {
56- if ( err ) return handleError ( err , cb ) ;
60+ model . get ( info . id , onComplete ) ;
61+ }
5762
58- return cb && cb ( undefined , update ) ;
59- }
60- } ) ;
63+ function onComplete ( err , resource ) {
64+ if ( err ) return handleError ( err , cb ) ;
65+
66+ return cb && cb ( undefined , resource ) ;
67+ }
6168} ;
6269
63- Model . prototype . patch = function ( query , patch , cb /* error, resource */ ) {
70+ Model . prototype . patchMany = function ( query , patch , cb /* error, resource */ ) {
6471 var model = this ;
6572
66- if ( ! Array . isArray ( patch ) ) patch = [ patch ] ;
67-
68- var validationErrors = jsonpatch . validate ( patch ) ;
69- if ( validationErrors ) return handleError ( validationError , cb ) ;
70-
7173 model . allDocs ( query , onFind ) ;
7274
7375 function onFind ( err , resources ) {
7476 if ( err ) return handleError ( err , cb ) ;
7577
7678 if ( ! resources . length ) return cb && cb ( undefined , [ ] ) ;
7779
78- var updates = resources . map ( function ( doc ) {
79- if ( ! jsonpatch . apply ( doc , patch ) ) return handleError ( new Error ( 'Failed to apply patch' ) , cb ) ;
80+ var updates = resources . map ( function ( resource ) {
81+ try {
82+ var doc = patch ( resource ) ;
83+
84+ return doc ;
85+ }
86+ catch ( e ) {
87+ console . error ( e ) ;
8088
81- return doc ;
89+ handleError ( new Error ( 'Failed to patch document ' + resource . _id ) , cb ) ;
90+ }
8291 } ) ;
8392
84- model . _db . bulkDocs ( updates , onComplete ) ;
93+ model . putMany ( updates , onComplete ) ;
94+ }
8595
86- function onComplete ( err , info ) {
87- if ( err ) return handleError ( err , cb ) ;
96+ function onComplete ( err , resources ) {
97+ if ( err ) return handleError ( err , cb ) ;
8898
89- return cb && cb ( undefined , updates ) ;
90- }
99+ return cb && cb ( undefined , resources ) ;
91100 }
92101} ;
93102
94103Model . prototype . putMany = function ( updates , cb /* error, resources */ ) {
95104 var model = this ;
96105
97- updates . forEach ( function ( update ) {
98- update . doctype = model . _name ;
99- } ) ;
106+ var query = { keys : updates . map ( function ( update ) { return update . _id ; } ) } ;
107+
108+ model . allDocs ( query , onFind ) ;
109+
110+ function onFind ( err , resources ) {
111+ if ( err ) return handleError ( err , cb ) ;
112+
113+ if ( ! resources . length ) return cb && cb ( undefined , [ ] ) ;
114+
115+ updates = updates . map ( function ( update ) {
116+ var rev , doctype ;
117+
118+ resources . forEach ( function ( resource ) {
119+ if ( resource . _id == update . _id ) {
120+ rev = resource . _rev ;
121+ doctype = resource . doctype ;
122+
123+ return false ;
124+ }
125+ } ) ;
126+
127+ update . _rev = rev ;
128+ update . doctype = doctype ;
129+
130+ return update ;
131+ } ) ;
100132
101- model . _db . bulkDocs ( updates , onComplete ) ;
133+ model . _db . bulkDocs ( updates , onUpdate ) ;
134+ }
102135
103- function onComplete ( err , info ) {
136+ function onUpdate ( err , info ) {
104137 if ( err ) return handleError ( err , cb ) ;
105138
106- return cb && cb ( undefined , updates ) ;
139+ model . allDocs ( query , onComplete ) ;
140+ }
141+
142+ function onComplete ( err , resources ) {
143+ if ( err ) return handleError ( err , cb ) ;
144+
145+ return cb && cb ( undefined , resources ) ;
107146 }
108147} ;
109148
110149Model . prototype . remove = function ( id , cb /* error, resource */ ) {
111150 var model = this ;
112151
113- model . _db . get ( id , function ( error , resource ) {
152+ model . get ( id , function ( error , resource ) {
114153 if ( error ) return handleError ( error , cb ) ;
115154
116155 model . _db . remove ( id , resource . _rev , onComplete ) ;
@@ -192,16 +231,27 @@ Model.prototype.allDocs = function( query, cb /* error, resources */ ) {
192231 var model = this ;
193232 var options = { include_docs : true } ;
194233
195- if ( query . keys && ! Array . isArray ( query . keys ) ) {
196- query . keys = [ query . keys ] ;
234+ if ( query . keys ) {
235+ if ( Array . isArray ( query . keys ) ) {
236+ options . keys = query . keys ;
237+ } else {
238+ query . key = query . keys ;
239+ delete query . keys ;
240+ }
197241 }
198242
199- options . keys = query . keys ;
243+ if ( query . key ) {
244+ options . key = query . key ;
245+ }
200246
201247 if ( Array . isArray ( query ) ) {
202248 options . keys = query ;
203249 }
204250
251+ if ( typeof query === 'string' ) {
252+ options . key = query ;
253+ }
254+
205255 query . doctype = model . _name ;
206256
207257 model . _db . allDocs ( options , onComplete ) ;
@@ -232,9 +282,27 @@ function _docMatchesQuery( model, doc, query ) {
232282 if ( typeof query === 'function' ) return query ( doc ) ;
233283
234284 for ( var key in query ) {
235- if ( key === 'keys' ) continue ;
285+ if ( key === 'keys' || key === 'key' ) continue ;
286+
287+ if ( ! doc . hasOwnProperty ( key ) ) {
288+ return false ;
289+ }
236290
237- if ( ! doc . hasOwnProperty ( key ) || doc [ key ] !== query [ key ] ) return false ;
291+ if ( ! Array . isArray ( doc [ key ] ) ) {
292+ if ( ! Array . isArray ( query [ key ] ) ) {
293+ if ( doc [ key ] !== query [ key ] ) {
294+ return false ;
295+ }
296+ } else {
297+ if ( ! ~ query [ key ] . indexOf ( doc [ key ] ) ) {
298+ return false ;
299+ }
300+ }
301+ } else {
302+ if ( ! ~ doc [ key ] . indexOf ( query [ key ] ) ) {
303+ return false ;
304+ }
305+ }
238306 }
239307
240308 return true ;
0 commit comments