Skip to content

Commit 35768bb

Browse files
committed
faster
1 parent f00c363 commit 35768bb

6 files changed

Lines changed: 825 additions & 574 deletions

File tree

lib/model.js

Lines changed: 109 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
var util = require('util')
22
, events = require('events')
3-
, jsonpatch = require('fast-json-patch')
43
, uuid = require('uuid');
54

65
function 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

3839
Model.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

94103
Model.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

110149
Model.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

Comments
 (0)