mongodb 2.1.0-alpha → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +574 -429
- package/Makefile +2 -5
- package/README.md +108 -15
- package/conf.json +17 -13
- package/index.js +13 -2
- package/lib/admin.js +113 -47
- package/lib/aggregation_cursor.js +56 -28
- package/lib/apm.js +608 -0
- package/lib/bulk/common.js +7 -7
- package/lib/bulk/ordered.js +56 -17
- package/lib/bulk/unordered.js +52 -14
- package/lib/collection.js +671 -212
- package/lib/command_cursor.js +60 -32
- package/lib/cursor.js +313 -115
- package/lib/db.js +264 -105
- package/lib/gridfs/chunk.js +26 -29
- package/lib/gridfs/grid_store.js +150 -64
- package/lib/gridfs-stream/download.js +310 -0
- package/lib/gridfs-stream/index.js +335 -0
- package/lib/gridfs-stream/upload.js +450 -0
- package/lib/metadata.js +64 -0
- package/lib/mongo_client.js +69 -39
- package/lib/mongos.js +65 -20
- package/lib/replset.js +69 -34
- package/lib/server.js +35 -1
- package/lib/topology_base.js +22 -10
- package/lib/url_parser.js +111 -13
- package/lib/utils.js +9 -8
- package/mongolabs.js +427 -0
- package/package.json +8 -6
- package/t.js +68 -51
- package/test.js +12 -0
- package/test_boot/boot.sh +3 -0
- package/test_boot/ca.pem +49 -0
- package/test_boot/client.pem +48 -0
- package/test_boot/client_password.pem +51 -0
- package/test_boot/connect.js +29 -0
- package/test_boot/data/WiredTiger +2 -0
- package/test_boot/data/WiredTiger.lock +1 -0
- package/test_boot/data/WiredTiger.turtle +6 -0
- package/test_boot/data/WiredTiger.wt +0 -0
- package/test_boot/data/WiredTigerLAS.wt +0 -0
- package/test_boot/data/_mdb_catalog.wt +0 -0
- package/test_boot/data/collection-0-757073248613337118.wt +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-44-37Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-45-15Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-46-31Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-47-25Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-49-07Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-50-41Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-50-53Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-52-31Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-54-53Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-55-09Z-00000 +0 -0
- package/test_boot/data/diagnostic.data/metrics.2015-10-07T14-55-38Z-00000 +0 -0
- package/test_boot/data/index-1-757073248613337118.wt +0 -0
- package/test_boot/data/mongod.lock +0 -0
- package/test_boot/data/sizeStorer.wt +0 -0
- package/test_boot/data/storage.bson +0 -0
- package/test_boot/server_password.pem +51 -0
- package/.travis.yml +0 -10
- package/t1.js +0 -59
- package/wercker.yml +0 -19
package/lib/cursor.js
CHANGED
|
@@ -11,7 +11,9 @@ var inherits = require('util').inherits
|
|
|
11
11
|
, ReadPreference = require('./read_preference')
|
|
12
12
|
, MongoError = require('mongodb-core').MongoError
|
|
13
13
|
, Readable = require('stream').Readable || require('readable-stream').Readable
|
|
14
|
+
, Define = require('./metadata')
|
|
14
15
|
, CoreCursor = require('mongodb-core').Cursor
|
|
16
|
+
, Map = require('mongodb-core').BSON.Map
|
|
15
17
|
, Query = require('mongodb-core').Query
|
|
16
18
|
, CoreReadPreference = require('mongodb-core').ReadPreference;
|
|
17
19
|
|
|
@@ -71,7 +73,34 @@ var fields = ['numberOfRetries', 'tailableRetryInterval'];
|
|
|
71
73
|
* @fires Cursor#readable
|
|
72
74
|
* @return {Cursor} a Cursor instance.
|
|
73
75
|
* @example
|
|
74
|
-
*
|
|
76
|
+
* Cursor cursor options.
|
|
77
|
+
*
|
|
78
|
+
* collection.find({}).project({a:1}) // Create a projection of field a
|
|
79
|
+
* collection.find({}).skip(1).limit(10) // Skip 1 and limit 10
|
|
80
|
+
* collection.find({}).batchSize(5) // Set batchSize on cursor to 5
|
|
81
|
+
* collection.find({}).filter({a:1}) // Set query on the cursor
|
|
82
|
+
* collection.find({}).comment('add a comment') // Add a comment to the query, allowing to correlate queries
|
|
83
|
+
* collection.find({}).addCursorFlag('tailable', true) // Set cursor as tailable
|
|
84
|
+
* collection.find({}).addCursorFlag('oplogReplay', true) // Set cursor as oplogReplay
|
|
85
|
+
* collection.find({}).addCursorFlag('noCursorTimeout', true) // Set cursor as noCursorTimeout
|
|
86
|
+
* collection.find({}).addCursorFlag('awaitData', true) // Set cursor as awaitData
|
|
87
|
+
* collection.find({}).addCursorFlag('exhaust', true) // Set cursor as exhaust
|
|
88
|
+
* collection.find({}).addCursorFlag('partial', true) // Set cursor as partial
|
|
89
|
+
* collection.find({}).addQueryModifier('$orderby', {a:1}) // Set $orderby {a:1}
|
|
90
|
+
* collection.find({}).max(10) // Set the cursor maxScan
|
|
91
|
+
* collection.find({}).maxScan(10) // Set the cursor maxScan
|
|
92
|
+
* collection.find({}).maxTimeMS(1000) // Set the cursor maxTimeMS
|
|
93
|
+
* collection.find({}).min(100) // Set the cursor min
|
|
94
|
+
* collection.find({}).returnKey(10) // Set the cursor returnKey
|
|
95
|
+
* collection.find({}).setReadPreference(ReadPreference.PRIMARY) // Set the cursor readPreference
|
|
96
|
+
* collection.find({}).showRecordId(true) // Set the cursor showRecordId
|
|
97
|
+
* collection.find({}).snapshot(true) // Set the cursor snapshot
|
|
98
|
+
* collection.find({}).sort([['a', 1]]) // Sets the sort order of the cursor query
|
|
99
|
+
* collection.find({}).hint('a_1') // Set the cursor hint
|
|
100
|
+
*
|
|
101
|
+
* All options are chainable, so one can do the following.
|
|
102
|
+
*
|
|
103
|
+
* collection.find({}).maxTimeMS(1000).maxScan(100).skip(1).toArray(..)
|
|
75
104
|
*/
|
|
76
105
|
var Cursor = function(bson, ns, cmd, options, topology, topologyOptions) {
|
|
77
106
|
CoreCursor.apply(this, Array.prototype.slice.call(arguments, 0));
|
|
@@ -119,7 +148,7 @@ var Cursor = function(bson, ns, cmd, options, topology, topologyOptions) {
|
|
|
119
148
|
// Topology options
|
|
120
149
|
, topologyOptions: topologyOptions
|
|
121
150
|
// Promise library
|
|
122
|
-
, promiseLibrary: promiseLibrary
|
|
151
|
+
, promiseLibrary: promiseLibrary
|
|
123
152
|
// Current doc
|
|
124
153
|
, currentDoc: null
|
|
125
154
|
}
|
|
@@ -127,7 +156,6 @@ var Cursor = function(bson, ns, cmd, options, topology, topologyOptions) {
|
|
|
127
156
|
// Legacy fields
|
|
128
157
|
this.timeout = self.s.options.noCursorTimeout == true;
|
|
129
158
|
this.sortValue = self.s.cmd.sort;
|
|
130
|
-
this.readPreference = self.s.options.readPreference;
|
|
131
159
|
}
|
|
132
160
|
|
|
133
161
|
/**
|
|
@@ -168,43 +196,54 @@ for(var name in CoreCursor.prototype) {
|
|
|
168
196
|
Cursor.prototype[name] = CoreCursor.prototype[name];
|
|
169
197
|
}
|
|
170
198
|
|
|
199
|
+
var define = Cursor.define = new Define('Cursor', Cursor, true);
|
|
200
|
+
|
|
171
201
|
/**
|
|
172
202
|
* Check if there is any document still available in the cursor
|
|
173
203
|
* @method
|
|
174
|
-
* @param {Cursor~resultCallback} callback The result callback.
|
|
204
|
+
* @param {Cursor~resultCallback} [callback] The result callback.
|
|
175
205
|
* @throws {MongoError}
|
|
176
|
-
* @deprecated
|
|
177
206
|
* @return {Promise} returns Promise if no callback passed
|
|
178
207
|
*/
|
|
179
208
|
Cursor.prototype.hasNext = function(callback) {
|
|
180
209
|
var self = this;
|
|
181
210
|
|
|
182
211
|
// Execute using callback
|
|
183
|
-
if(typeof callback == 'function')
|
|
184
|
-
if(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
212
|
+
if(typeof callback == 'function') {
|
|
213
|
+
if(self.s.currentDoc){
|
|
214
|
+
return callback(null, true);
|
|
215
|
+
} else {
|
|
216
|
+
return nextObject(self, function(err, doc) {
|
|
217
|
+
if(!doc) return callback(null, false);
|
|
218
|
+
self.s.currentDoc = doc;
|
|
219
|
+
callback(null, true);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
188
223
|
|
|
189
224
|
// Return a Promise
|
|
190
225
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
226
|
+
if(self.s.currentDoc){
|
|
227
|
+
resolve(true);
|
|
228
|
+
} else {
|
|
229
|
+
nextObject(self, function(err, doc) {
|
|
230
|
+
if(self.s.state == Cursor.CLOSED || self.isDead()) return resolve(false);
|
|
231
|
+
if(err) return reject(err);
|
|
232
|
+
if(!doc) return resolve(false);
|
|
233
|
+
self.s.currentDoc = doc;
|
|
234
|
+
resolve(true);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
198
237
|
});
|
|
199
238
|
}
|
|
200
239
|
|
|
240
|
+
define.classMethod('hasNext', {callback: true, promise:true});
|
|
201
241
|
|
|
202
242
|
/**
|
|
203
243
|
* Get the next available document from the cursor, returns null if no more documents are available.
|
|
204
244
|
* @method
|
|
205
|
-
* @param {Cursor~resultCallback} callback The result callback.
|
|
245
|
+
* @param {Cursor~resultCallback} [callback] The result callback.
|
|
206
246
|
* @throws {MongoError}
|
|
207
|
-
* @deprecated
|
|
208
247
|
* @return {Promise} returns Promise if no callback passed
|
|
209
248
|
*/
|
|
210
249
|
Cursor.prototype.next = function(callback) {
|
|
@@ -234,11 +273,13 @@ Cursor.prototype.next = function(callback) {
|
|
|
234
273
|
|
|
235
274
|
nextObject(self, function(err, r) {
|
|
236
275
|
if(err) return reject(err);
|
|
237
|
-
resolve(r);
|
|
276
|
+
resolve(r);
|
|
238
277
|
});
|
|
239
278
|
});
|
|
240
279
|
}
|
|
241
280
|
|
|
281
|
+
define.classMethod('next', {callback: true, promise:true});
|
|
282
|
+
|
|
242
283
|
/**
|
|
243
284
|
* Set the cursor query
|
|
244
285
|
* @method
|
|
@@ -246,11 +287,111 @@ Cursor.prototype.next = function(callback) {
|
|
|
246
287
|
* @return {Cursor}
|
|
247
288
|
*/
|
|
248
289
|
Cursor.prototype.filter = function(filter) {
|
|
249
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
290
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
250
291
|
this.s.cmd.query = filter;
|
|
251
292
|
return this;
|
|
252
293
|
}
|
|
253
294
|
|
|
295
|
+
define.classMethod('filter', {callback: false, promise:false, returns: [Cursor]});
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Set the cursor maxScan
|
|
299
|
+
* @method
|
|
300
|
+
* @param {object} maxScan Constrains the query to only scan the specified number of documents when fulfilling the query
|
|
301
|
+
* @return {Cursor}
|
|
302
|
+
*/
|
|
303
|
+
Cursor.prototype.maxScan = function(maxScan) {
|
|
304
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
305
|
+
this.s.cmd.maxScan = maxScan;
|
|
306
|
+
return this;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
define.classMethod('maxScan', {callback: false, promise:false, returns: [Cursor]});
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Set the cursor hint
|
|
313
|
+
* @method
|
|
314
|
+
* @param {object} hint If specified, then the query system will only consider plans using the hinted index.
|
|
315
|
+
* @return {Cursor}
|
|
316
|
+
*/
|
|
317
|
+
Cursor.prototype.hint = function(hint) {
|
|
318
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
319
|
+
this.s.cmd.hint = hint;
|
|
320
|
+
return this;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
define.classMethod('hint', {callback: false, promise:false, returns: [Cursor]});
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Set the cursor min
|
|
327
|
+
* @method
|
|
328
|
+
* @param {object} min Specify a $min value to specify the inclusive lower bound for a specific index in order to constrain the results of find(). The $min specifies the lower bound for all keys of a specific index in order.
|
|
329
|
+
* @return {Cursor}
|
|
330
|
+
*/
|
|
331
|
+
Cursor.prototype.min = function(min) {
|
|
332
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
333
|
+
this.s.cmd.min = min;
|
|
334
|
+
return this;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
define.classMethod('min', {callback: false, promise:false, returns: [Cursor]});
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Set the cursor max
|
|
341
|
+
* @method
|
|
342
|
+
* @param {object} max Specify a $max value to specify the exclusive upper bound for a specific index in order to constrain the results of find(). The $max specifies the upper bound for all keys of a specific index in order.
|
|
343
|
+
* @return {Cursor}
|
|
344
|
+
*/
|
|
345
|
+
Cursor.prototype.max = function(max) {
|
|
346
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
347
|
+
this.s.cmd.max = max;
|
|
348
|
+
return this;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
define.classMethod('max', {callback: false, promise:false, returns: [Cursor]});
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Set the cursor returnKey
|
|
355
|
+
* @method
|
|
356
|
+
* @param {object} returnKey Only return the index field or fields for the results of the query. If $returnKey is set to true and the query does not use an index to perform the read operation, the returned documents will not contain any fields. Use one of the following forms:
|
|
357
|
+
* @return {Cursor}
|
|
358
|
+
*/
|
|
359
|
+
Cursor.prototype.returnKey = function(value) {
|
|
360
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
361
|
+
this.s.cmd.returnKey = value;
|
|
362
|
+
return this;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
define.classMethod('returnKey', {callback: false, promise:false, returns: [Cursor]});
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Set the cursor showRecordId
|
|
369
|
+
* @method
|
|
370
|
+
* @param {object} showRecordId The $showDiskLoc option has now been deprecated and replaced with the showRecordId field. $showDiskLoc will still be accepted for OP_QUERY stye find.
|
|
371
|
+
* @return {Cursor}
|
|
372
|
+
*/
|
|
373
|
+
Cursor.prototype.showRecordId = function(value) {
|
|
374
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
375
|
+
this.s.cmd.showDiskLoc = value;
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
define.classMethod('showRecordId', {callback: false, promise:false, returns: [Cursor]});
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Set the cursor snapshot
|
|
383
|
+
* @method
|
|
384
|
+
* @param {object} snapshot The $snapshot operator prevents the cursor from returning a document more than once because an intervening write operation results in a move of the document.
|
|
385
|
+
* @return {Cursor}
|
|
386
|
+
*/
|
|
387
|
+
Cursor.prototype.snapshot = function(value) {
|
|
388
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
389
|
+
this.s.cmd.snapshot = value;
|
|
390
|
+
return this;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
define.classMethod('snapshot', {callback: false, promise:false, returns: [Cursor]});
|
|
394
|
+
|
|
254
395
|
/**
|
|
255
396
|
* Set a node.js specific cursor option
|
|
256
397
|
* @method
|
|
@@ -260,14 +401,16 @@ Cursor.prototype.filter = function(filter) {
|
|
|
260
401
|
* @return {Cursor}
|
|
261
402
|
*/
|
|
262
403
|
Cursor.prototype.setCursorOption = function(field, value) {
|
|
263
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
264
|
-
if(fields.indexOf(field) == -1) throw
|
|
404
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
405
|
+
if(fields.indexOf(field) == -1) throw MongoError.create({message: f("option %s not a supported option %s", field, fields), driver:true });
|
|
265
406
|
this.s[field] = value;
|
|
266
|
-
if(field == 'numberOfRetries')
|
|
407
|
+
if(field == 'numberOfRetries')
|
|
267
408
|
this.s.currentNumberOfRetries = value;
|
|
268
409
|
return this;
|
|
269
410
|
}
|
|
270
411
|
|
|
412
|
+
define.classMethod('setCursorOption', {callback: false, promise:false, returns: [Cursor]});
|
|
413
|
+
|
|
271
414
|
/**
|
|
272
415
|
* Add a cursor flag to the cursor
|
|
273
416
|
* @method
|
|
@@ -277,13 +420,15 @@ Cursor.prototype.setCursorOption = function(field, value) {
|
|
|
277
420
|
* @return {Cursor}
|
|
278
421
|
*/
|
|
279
422
|
Cursor.prototype.addCursorFlag = function(flag, value) {
|
|
280
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
281
|
-
if(flags.indexOf(flag) == -1) throw
|
|
282
|
-
if(typeof value != 'boolean') throw
|
|
423
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
424
|
+
if(flags.indexOf(flag) == -1) throw MongoError.create({message: f("flag %s not a supported flag %s", flag, flags), driver:true });
|
|
425
|
+
if(typeof value != 'boolean') throw MongoError.create({message: f("flag %s must be a boolean value", flag), driver:true});
|
|
283
426
|
this.s.cmd[flag] = value;
|
|
284
427
|
return this;
|
|
285
428
|
}
|
|
286
429
|
|
|
430
|
+
define.classMethod('addCursorFlag', {callback: false, promise:false, returns: [Cursor]});
|
|
431
|
+
|
|
287
432
|
/**
|
|
288
433
|
* Add a query modifier to the cursor query
|
|
289
434
|
* @method
|
|
@@ -293,8 +438,8 @@ Cursor.prototype.addCursorFlag = function(flag, value) {
|
|
|
293
438
|
* @return {Cursor}
|
|
294
439
|
*/
|
|
295
440
|
Cursor.prototype.addQueryModifier = function(name, value) {
|
|
296
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
297
|
-
if(name[0] != '$') throw
|
|
441
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
442
|
+
if(name[0] != '$') throw MongoError.create({message: f("%s is not a valid query modifier"), driver:true});
|
|
298
443
|
// Strip of the $
|
|
299
444
|
var field = name.substr(1);
|
|
300
445
|
// Set on the command
|
|
@@ -304,6 +449,8 @@ Cursor.prototype.addQueryModifier = function(name, value) {
|
|
|
304
449
|
return this;
|
|
305
450
|
}
|
|
306
451
|
|
|
452
|
+
define.classMethod('addQueryModifier', {callback: false, promise:false, returns: [Cursor]});
|
|
453
|
+
|
|
307
454
|
/**
|
|
308
455
|
* Add a comment to the cursor query allowing for tracking the comment in the log.
|
|
309
456
|
* @method
|
|
@@ -312,11 +459,29 @@ Cursor.prototype.addQueryModifier = function(name, value) {
|
|
|
312
459
|
* @return {Cursor}
|
|
313
460
|
*/
|
|
314
461
|
Cursor.prototype.comment = function(value) {
|
|
315
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
462
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
316
463
|
this.s.cmd.comment = value;
|
|
317
464
|
return this;
|
|
318
465
|
}
|
|
319
466
|
|
|
467
|
+
define.classMethod('comment', {callback: false, promise:false, returns: [Cursor]});
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Set a maxAwaitTimeMS on a tailing cursor query to allow to customize the timeout value for the option awaitData (Only supported on MongoDB 3.2 or higher, ignored otherwise)
|
|
471
|
+
* @method
|
|
472
|
+
* @param {number} value Number of milliseconds to wait before aborting the tailed query.
|
|
473
|
+
* @throws {MongoError}
|
|
474
|
+
* @return {Cursor}
|
|
475
|
+
*/
|
|
476
|
+
Cursor.prototype.maxAwaitTimeMS = function(value) {
|
|
477
|
+
if(typeof value != 'number') throw MongoError.create({message: "maxAwaitTimeMS must be a number", driver:true});
|
|
478
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
479
|
+
this.s.cmd.maxAwaitTimeMS = value;
|
|
480
|
+
return this;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
define.classMethod('maxAwaitTimeMS', {callback: false, promise:false, returns: [Cursor]});
|
|
484
|
+
|
|
320
485
|
/**
|
|
321
486
|
* Set a maxTimeMS on the cursor query, allowing for hard timeout limits on queries (Only supported on MongoDB 2.6 or higher)
|
|
322
487
|
* @method
|
|
@@ -325,14 +490,18 @@ Cursor.prototype.comment = function(value) {
|
|
|
325
490
|
* @return {Cursor}
|
|
326
491
|
*/
|
|
327
492
|
Cursor.prototype.maxTimeMS = function(value) {
|
|
328
|
-
if(typeof value != 'number') throw
|
|
329
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
493
|
+
if(typeof value != 'number') throw MongoError.create({message: "maxTimeMS must be a number", driver:true});
|
|
494
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
330
495
|
this.s.cmd.maxTimeMS = value;
|
|
331
496
|
return this;
|
|
332
497
|
}
|
|
333
498
|
|
|
499
|
+
define.classMethod('maxTimeMS', {callback: false, promise:false, returns: [Cursor]});
|
|
500
|
+
|
|
334
501
|
Cursor.prototype.maxTimeMs = Cursor.prototype.maxTimeMS;
|
|
335
502
|
|
|
503
|
+
define.classMethod('maxTimeMs', {callback: false, promise:false, returns: [Cursor]});
|
|
504
|
+
|
|
336
505
|
/**
|
|
337
506
|
* Sets a field projection for the query.
|
|
338
507
|
* @method
|
|
@@ -341,11 +510,13 @@ Cursor.prototype.maxTimeMs = Cursor.prototype.maxTimeMS;
|
|
|
341
510
|
* @return {Cursor}
|
|
342
511
|
*/
|
|
343
512
|
Cursor.prototype.project = function(value) {
|
|
344
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
513
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
345
514
|
this.s.cmd.fields = value;
|
|
346
515
|
return this;
|
|
347
516
|
}
|
|
348
517
|
|
|
518
|
+
define.classMethod('project', {callback: false, promise:false, returns: [Cursor]});
|
|
519
|
+
|
|
349
520
|
/**
|
|
350
521
|
* Sets the sort order of the cursor query.
|
|
351
522
|
* @method
|
|
@@ -355,10 +526,29 @@ Cursor.prototype.project = function(value) {
|
|
|
355
526
|
* @return {Cursor}
|
|
356
527
|
*/
|
|
357
528
|
Cursor.prototype.sort = function(keyOrList, direction) {
|
|
358
|
-
if(this.s.options.tailable) throw
|
|
359
|
-
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw
|
|
529
|
+
if(this.s.options.tailable) throw MongoError.create({message: "Tailable cursor doesn't support sorting", driver:true});
|
|
530
|
+
if(this.s.state == Cursor.CLOSED || this.s.state == Cursor.OPEN || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
360
531
|
var order = keyOrList;
|
|
361
532
|
|
|
533
|
+
// We have an array of arrays, we need to preserve the order of the sort
|
|
534
|
+
// so we will us a Map
|
|
535
|
+
if(Array.isArray(order) && Array.isArray(order[0])) {
|
|
536
|
+
order = new Map(order.map(function(x) {
|
|
537
|
+
var value = [x[0], null];
|
|
538
|
+
if(x[1] == 'asc') {
|
|
539
|
+
value[1] = 1;
|
|
540
|
+
} else if(x[1] == 'desc') {
|
|
541
|
+
value[1] = -1;
|
|
542
|
+
} else if(x[1] == 1 || x[1] == -1) {
|
|
543
|
+
value[1] = x[1];
|
|
544
|
+
} else {
|
|
545
|
+
throw new MongoError("Illegal sort clause, must be of the form [['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]");
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
return value;
|
|
549
|
+
}));
|
|
550
|
+
}
|
|
551
|
+
|
|
362
552
|
if(direction != null) {
|
|
363
553
|
order = [[keyOrList, direction]];
|
|
364
554
|
}
|
|
@@ -368,6 +558,8 @@ Cursor.prototype.sort = function(keyOrList, direction) {
|
|
|
368
558
|
return this;
|
|
369
559
|
}
|
|
370
560
|
|
|
561
|
+
define.classMethod('sort', {callback: false, promise:false, returns: [Cursor]});
|
|
562
|
+
|
|
371
563
|
/**
|
|
372
564
|
* Set the batch size for the cursor.
|
|
373
565
|
* @method
|
|
@@ -376,14 +568,16 @@ Cursor.prototype.sort = function(keyOrList, direction) {
|
|
|
376
568
|
* @return {Cursor}
|
|
377
569
|
*/
|
|
378
570
|
Cursor.prototype.batchSize = function(value) {
|
|
379
|
-
if(this.s.options.tailable) throw
|
|
380
|
-
if(this.s.state == Cursor.CLOSED || this.isDead()) throw
|
|
381
|
-
if(typeof value != 'number') throw
|
|
571
|
+
if(this.s.options.tailable) throw MongoError.create({message: "Tailable cursor doesn't support batchSize", driver:true});
|
|
572
|
+
if(this.s.state == Cursor.CLOSED || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
573
|
+
if(typeof value != 'number') throw MongoError.create({message: "batchSize requires an integer", driver:true});
|
|
382
574
|
this.s.cmd.batchSize = value;
|
|
383
575
|
this.setCursorBatchSize(value);
|
|
384
576
|
return this;
|
|
385
577
|
}
|
|
386
578
|
|
|
579
|
+
define.classMethod('batchSize', {callback: false, promise:false, returns: [Cursor]});
|
|
580
|
+
|
|
387
581
|
/**
|
|
388
582
|
* Set the limit for the cursor.
|
|
389
583
|
* @method
|
|
@@ -392,15 +586,17 @@ Cursor.prototype.batchSize = function(value) {
|
|
|
392
586
|
* @return {Cursor}
|
|
393
587
|
*/
|
|
394
588
|
Cursor.prototype.limit = function(value) {
|
|
395
|
-
if(this.s.options.tailable) throw
|
|
396
|
-
if(this.s.state == Cursor.OPEN || this.s.state == Cursor.CLOSED || this.isDead()) throw
|
|
397
|
-
if(typeof value != 'number') throw
|
|
589
|
+
if(this.s.options.tailable) throw MongoError.create({message: "Tailable cursor doesn't support limit", driver:true});
|
|
590
|
+
if(this.s.state == Cursor.OPEN || this.s.state == Cursor.CLOSED || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
591
|
+
if(typeof value != 'number') throw MongoError.create({message: "limit requires an integer", driver:true});
|
|
398
592
|
this.s.cmd.limit = value;
|
|
399
593
|
// this.cursorLimit = value;
|
|
400
594
|
this.setCursorLimit(value);
|
|
401
595
|
return this;
|
|
402
596
|
}
|
|
403
597
|
|
|
598
|
+
define.classMethod('limit', {callback: false, promise:false, returns: [Cursor]});
|
|
599
|
+
|
|
404
600
|
/**
|
|
405
601
|
* Set the skip for the cursor.
|
|
406
602
|
* @method
|
|
@@ -409,14 +605,16 @@ Cursor.prototype.limit = function(value) {
|
|
|
409
605
|
* @return {Cursor}
|
|
410
606
|
*/
|
|
411
607
|
Cursor.prototype.skip = function(value) {
|
|
412
|
-
if(this.s.options.tailable) throw
|
|
413
|
-
if(this.s.state == Cursor.OPEN || this.s.state == Cursor.CLOSED || this.isDead()) throw
|
|
414
|
-
if(typeof value != 'number') throw
|
|
608
|
+
if(this.s.options.tailable) throw MongoError.create({message: "Tailable cursor doesn't support skip", driver:true});
|
|
609
|
+
if(this.s.state == Cursor.OPEN || this.s.state == Cursor.CLOSED || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true});
|
|
610
|
+
if(typeof value != 'number') throw MongoError.create({message: "skip requires an integer", driver:true});
|
|
415
611
|
this.s.cmd.skip = value;
|
|
416
612
|
this.setCursorSkip(value);
|
|
417
613
|
return this;
|
|
418
614
|
}
|
|
419
615
|
|
|
616
|
+
define.classMethod('skip', {callback: false, promise:false, returns: [Cursor]});
|
|
617
|
+
|
|
420
618
|
/**
|
|
421
619
|
* The callback format for results
|
|
422
620
|
* @callback Cursor~resultCallback
|
|
@@ -424,48 +622,6 @@ Cursor.prototype.skip = function(value) {
|
|
|
424
622
|
* @param {(object|null|boolean)} result The result object if the command was executed successfully.
|
|
425
623
|
*/
|
|
426
624
|
|
|
427
|
-
/**
|
|
428
|
-
* Set the new batchSize of the cursor
|
|
429
|
-
* @function Cursor.prototype.setBatchSize
|
|
430
|
-
* @param {number} value The new batchSize for the cursor
|
|
431
|
-
* @return {null}
|
|
432
|
-
*/
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Get the batchSize of the cursor
|
|
436
|
-
* @function Cursor.prototype.batchSize
|
|
437
|
-
* @param {number} value The current batchSize for the cursor
|
|
438
|
-
* @return {null}
|
|
439
|
-
*/
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Set the new skip value of the cursor
|
|
443
|
-
* @function Cursor.prototype.setCursorSkip
|
|
444
|
-
* @param {number} value The new skip for the cursor
|
|
445
|
-
* @return {null}
|
|
446
|
-
*/
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* Get the skip value of the cursor
|
|
450
|
-
* @function Cursor.prototype.cursorSkip
|
|
451
|
-
* @param {number} value The current skip value for the cursor
|
|
452
|
-
* @return {null}
|
|
453
|
-
*/
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Set the new limit value of the cursor
|
|
457
|
-
* @function Cursor.prototype.setCursorLimit
|
|
458
|
-
* @param {number} value The new limit for the cursor
|
|
459
|
-
* @return {null}
|
|
460
|
-
*/
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Get the limit value of the cursor
|
|
464
|
-
* @function Cursor.prototype.cursorLimit
|
|
465
|
-
* @param {number} value The current limit value for the cursor
|
|
466
|
-
* @return {null}
|
|
467
|
-
*/
|
|
468
|
-
|
|
469
625
|
/**
|
|
470
626
|
* Clone the cursor
|
|
471
627
|
* @function external:CoreCursor#clone
|
|
@@ -481,7 +637,7 @@ Cursor.prototype.skip = function(value) {
|
|
|
481
637
|
/**
|
|
482
638
|
* Get the next available document from the cursor, returns null if no more documents are available.
|
|
483
639
|
* @method
|
|
484
|
-
* @param {Cursor~resultCallback} callback The result callback.
|
|
640
|
+
* @param {Cursor~resultCallback} [callback] The result callback.
|
|
485
641
|
* @throws {MongoError}
|
|
486
642
|
* @deprecated
|
|
487
643
|
* @return {Promise} returns Promise if no callback passed
|
|
@@ -489,7 +645,7 @@ Cursor.prototype.skip = function(value) {
|
|
|
489
645
|
Cursor.prototype.nextObject = Cursor.prototype.next;
|
|
490
646
|
|
|
491
647
|
var nextObject = function(self, callback) {
|
|
492
|
-
if(self.s.state == Cursor.CLOSED || self.isDead()) return handleCallback(callback,
|
|
648
|
+
if(self.s.state == Cursor.CLOSED || self.isDead && self.isDead()) return handleCallback(callback, MongoError.create({message: "Cursor is closed", driver:true}));
|
|
493
649
|
if(self.s.state == Cursor.INIT && self.s.cmd.sort) {
|
|
494
650
|
try {
|
|
495
651
|
self.s.cmd.sort = formattedOrderClause(self.s.cmd.sort);
|
|
@@ -497,12 +653,17 @@ var nextObject = function(self, callback) {
|
|
|
497
653
|
return handleCallback(callback, err);
|
|
498
654
|
}
|
|
499
655
|
}
|
|
656
|
+
|
|
500
657
|
// Get the next object
|
|
501
658
|
self._next(function(err, doc) {
|
|
502
659
|
if(err && err.tailable && self.s.currentNumberOfRetries == 0) return callback(err);
|
|
503
660
|
if(err && err.tailable && self.s.currentNumberOfRetries > 0) {
|
|
504
661
|
self.s.currentNumberOfRetries = self.s.currentNumberOfRetries - 1;
|
|
662
|
+
|
|
505
663
|
return setTimeout(function() {
|
|
664
|
+
// Rewind the cursor only when it has not actually read any documents yet
|
|
665
|
+
if(self.cursorState.currentLimit == 0) self.rewind();
|
|
666
|
+
// Read the next document, forcing a re-issue of query if no cursorId exists
|
|
506
667
|
self.nextObject(callback);
|
|
507
668
|
}, self.s.tailableRetryInterval);
|
|
508
669
|
}
|
|
@@ -510,9 +671,11 @@ var nextObject = function(self, callback) {
|
|
|
510
671
|
self.s.state = Cursor.OPEN;
|
|
511
672
|
if(err) return handleCallback(callback, err);
|
|
512
673
|
handleCallback(callback, null, doc);
|
|
513
|
-
});
|
|
674
|
+
});
|
|
514
675
|
}
|
|
515
676
|
|
|
677
|
+
define.classMethod('nextObject', {callback: true, promise:true});
|
|
678
|
+
|
|
516
679
|
// Trampoline emptying the number of retrieved items
|
|
517
680
|
// without incurring a nextTick operation
|
|
518
681
|
var loop = function(self, callback) {
|
|
@@ -524,16 +687,10 @@ var loop = function(self, callback) {
|
|
|
524
687
|
return loop;
|
|
525
688
|
}
|
|
526
689
|
|
|
527
|
-
/**
|
|
528
|
-
* Get the next available document from the cursor, returns null if no more documents are available.
|
|
529
|
-
* @method
|
|
530
|
-
* @param {Cursor~resultCallback} callback The result callback.
|
|
531
|
-
* @throws {MongoError}
|
|
532
|
-
* @deprecated
|
|
533
|
-
* @return {Promise} returns Promise if no callback passed
|
|
534
|
-
*/
|
|
535
690
|
Cursor.prototype.next = Cursor.prototype.nextObject;
|
|
536
691
|
|
|
692
|
+
define.classMethod('next', {callback: true, promise:true});
|
|
693
|
+
|
|
537
694
|
/**
|
|
538
695
|
* Iterates over all the documents for this cursor. As with **{cursor.toArray}**,
|
|
539
696
|
* not all of the elements will be iterated if this cursor had been previouly accessed.
|
|
@@ -556,12 +713,14 @@ Cursor.prototype.each = function(callback) {
|
|
|
556
713
|
_each(this, callback);
|
|
557
714
|
};
|
|
558
715
|
|
|
716
|
+
define.classMethod('each', {callback: true, promise:false});
|
|
717
|
+
|
|
559
718
|
// Run the each loop
|
|
560
719
|
var _each = function(self, callback) {
|
|
561
|
-
if(!callback) throw
|
|
720
|
+
if(!callback) throw MongoError.create({message: 'callback is mandatory', driver:true});
|
|
562
721
|
if(self.isNotified()) return;
|
|
563
722
|
if(self.s.state == Cursor.CLOSED || self.isDead()) {
|
|
564
|
-
return handleCallback(callback,
|
|
723
|
+
return handleCallback(callback, MongoError.create({message: "Cursor is closed", driver:true}));
|
|
565
724
|
}
|
|
566
725
|
|
|
567
726
|
if(self.s.state == Cursor.INIT) self.s.state = Cursor.OPEN;
|
|
@@ -573,7 +732,7 @@ var _each = function(self, callback) {
|
|
|
573
732
|
while(fn = loop(self, callback)) fn(self, callback);
|
|
574
733
|
_each(self, callback);
|
|
575
734
|
} else {
|
|
576
|
-
self.
|
|
735
|
+
self.next(function(err, item) {
|
|
577
736
|
if(err) return handleCallback(callback, err);
|
|
578
737
|
if(item == null) {
|
|
579
738
|
self.s.state = Cursor.CLOSED;
|
|
@@ -619,6 +778,8 @@ Cursor.prototype.forEach = function(iterator, callback) {
|
|
|
619
778
|
});
|
|
620
779
|
}
|
|
621
780
|
|
|
781
|
+
define.classMethod('forEach', {callback: true, promise:false});
|
|
782
|
+
|
|
622
783
|
/**
|
|
623
784
|
* Set the ReadPreference for the cursor.
|
|
624
785
|
* @method
|
|
@@ -627,7 +788,7 @@ Cursor.prototype.forEach = function(iterator, callback) {
|
|
|
627
788
|
* @return {Cursor}
|
|
628
789
|
*/
|
|
629
790
|
Cursor.prototype.setReadPreference = function(r) {
|
|
630
|
-
if(this.s.state != Cursor.INIT) throw
|
|
791
|
+
if(this.s.state != Cursor.INIT) throw MongoError.create({message: 'cannot change cursor readPreference after cursor has been accessed', driver:true});
|
|
631
792
|
if(r instanceof ReadPreference) {
|
|
632
793
|
this.s.options.readPreference = new CoreReadPreference(r.mode, r.tags);
|
|
633
794
|
} else {
|
|
@@ -637,6 +798,8 @@ Cursor.prototype.setReadPreference = function(r) {
|
|
|
637
798
|
return this;
|
|
638
799
|
}
|
|
639
800
|
|
|
801
|
+
define.classMethod('setReadPreference', {callback: false, promise:false, returns: [Cursor]});
|
|
802
|
+
|
|
640
803
|
/**
|
|
641
804
|
* The callback format for results
|
|
642
805
|
* @callback Cursor~toArrayResultCallback
|
|
@@ -650,13 +813,13 @@ Cursor.prototype.setReadPreference = function(r) {
|
|
|
650
813
|
* results when this cursor had been previouly accessed. In that case,
|
|
651
814
|
* cursor.rewind() can be used to reset the cursor.
|
|
652
815
|
* @method
|
|
653
|
-
* @param {Cursor~toArrayResultCallback} callback The result callback.
|
|
816
|
+
* @param {Cursor~toArrayResultCallback} [callback] The result callback.
|
|
654
817
|
* @throws {MongoError}
|
|
655
818
|
* @return {Promise} returns Promise if no callback passed
|
|
656
819
|
*/
|
|
657
820
|
Cursor.prototype.toArray = function(callback) {
|
|
658
821
|
var self = this;
|
|
659
|
-
if(self.s.options.tailable) throw
|
|
822
|
+
if(self.s.options.tailable) throw MongoError.create({message: 'Tailable cursor cannot be converted to array', driver:true});
|
|
660
823
|
|
|
661
824
|
// Execute using callback
|
|
662
825
|
if(typeof callback == 'function') return toArray(self, callback);
|
|
@@ -665,7 +828,7 @@ Cursor.prototype.toArray = function(callback) {
|
|
|
665
828
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
666
829
|
toArray(self, function(err, r) {
|
|
667
830
|
if(err) return reject(err);
|
|
668
|
-
resolve(r);
|
|
831
|
+
resolve(r);
|
|
669
832
|
});
|
|
670
833
|
});
|
|
671
834
|
}
|
|
@@ -677,7 +840,6 @@ var toArray = function(self, callback) {
|
|
|
677
840
|
self.rewind();
|
|
678
841
|
self.s.state = Cursor.INIT;
|
|
679
842
|
|
|
680
|
-
|
|
681
843
|
// Fetch all the documents
|
|
682
844
|
var fetchDocs = function() {
|
|
683
845
|
self._next(function(err, doc) {
|
|
@@ -689,6 +851,7 @@ var toArray = function(self, callback) {
|
|
|
689
851
|
|
|
690
852
|
// Add doc to items
|
|
691
853
|
items.push(doc)
|
|
854
|
+
|
|
692
855
|
// Get all buffered objects
|
|
693
856
|
if(self.bufferedCount() > 0) {
|
|
694
857
|
var docs = self.readBufferedDocuments(self.bufferedCount())
|
|
@@ -706,9 +869,11 @@ var toArray = function(self, callback) {
|
|
|
706
869
|
})
|
|
707
870
|
}
|
|
708
871
|
|
|
709
|
-
fetchDocs();
|
|
872
|
+
fetchDocs();
|
|
710
873
|
}
|
|
711
874
|
|
|
875
|
+
define.classMethod('toArray', {callback: true, promise:true});
|
|
876
|
+
|
|
712
877
|
/**
|
|
713
878
|
* The callback format for results
|
|
714
879
|
* @callback Cursor~countResultCallback
|
|
@@ -726,12 +891,12 @@ var toArray = function(self, callback) {
|
|
|
726
891
|
* @param {number} [options.maxTimeMS=null] Number of miliseconds to wait before aborting the query.
|
|
727
892
|
* @param {string} [options.hint=null] An index name hint for the query.
|
|
728
893
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
729
|
-
* @param {Cursor~countResultCallback} callback The result callback.
|
|
894
|
+
* @param {Cursor~countResultCallback} [callback] The result callback.
|
|
730
895
|
* @return {Promise} returns Promise if no callback passed
|
|
731
896
|
*/
|
|
732
897
|
Cursor.prototype.count = function(applySkipLimit, opts, callback) {
|
|
733
898
|
var self = this;
|
|
734
|
-
if(self.s.cmd.query == null) throw
|
|
899
|
+
if(self.s.cmd.query == null) throw MongoError.create({message: "count can only be used with find command", driver:true});
|
|
735
900
|
if(typeof opts == 'function') callback = opts, opts = {};
|
|
736
901
|
opts = opts || {};
|
|
737
902
|
|
|
@@ -742,7 +907,7 @@ Cursor.prototype.count = function(applySkipLimit, opts, callback) {
|
|
|
742
907
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
743
908
|
count(self, applySkipLimit, opts, function(err, r) {
|
|
744
909
|
if(err) return reject(err);
|
|
745
|
-
resolve(r);
|
|
910
|
+
resolve(r);
|
|
746
911
|
});
|
|
747
912
|
});
|
|
748
913
|
};
|
|
@@ -767,8 +932,8 @@ var count = function(self, applySkipLimit, opts, callback) {
|
|
|
767
932
|
|
|
768
933
|
if(typeof opts.maxTimeMS == 'number') {
|
|
769
934
|
command.maxTimeMS = opts.maxTimeMS;
|
|
770
|
-
} else if(typeof self.s.maxTimeMS == 'number') {
|
|
771
|
-
command.maxTimeMS = self.s.maxTimeMS;
|
|
935
|
+
} else if(self.s.cmd && typeof self.s.cmd.maxTimeMS == 'number') {
|
|
936
|
+
command.maxTimeMS = self.s.cmd.maxTimeMS;
|
|
772
937
|
}
|
|
773
938
|
|
|
774
939
|
// Get a server
|
|
@@ -795,14 +960,18 @@ var count = function(self, applySkipLimit, opts, callback) {
|
|
|
795
960
|
if(result.documents.length == 1
|
|
796
961
|
&& (result.documents[0].errmsg
|
|
797
962
|
|| result.documents[0].err
|
|
798
|
-
|| result.documents[0]['$err']))
|
|
963
|
+
|| result.documents[0]['$err'])) {
|
|
964
|
+
return handleCallback(callback, MongoError.create(result.documents[0]));
|
|
965
|
+
}
|
|
799
966
|
handleCallback(callback, null, result.documents[0].n);
|
|
800
967
|
});
|
|
801
968
|
|
|
802
969
|
// Write the initial command out
|
|
803
|
-
connection.write(query.toBin());
|
|
970
|
+
connection.write(query.toBin());
|
|
804
971
|
}
|
|
805
972
|
|
|
973
|
+
define.classMethod('count', {callback: true, promise:true});
|
|
974
|
+
|
|
806
975
|
/**
|
|
807
976
|
* Close the cursor, sending a KillCursor command and emitting close.
|
|
808
977
|
* @method
|
|
@@ -823,6 +992,8 @@ Cursor.prototype.close = function(callback) {
|
|
|
823
992
|
});
|
|
824
993
|
}
|
|
825
994
|
|
|
995
|
+
define.classMethod('close', {callback: true, promise:true});
|
|
996
|
+
|
|
826
997
|
/**
|
|
827
998
|
* Map all documents using the provided function
|
|
828
999
|
* @method
|
|
@@ -834,6 +1005,8 @@ Cursor.prototype.map = function(transform) {
|
|
|
834
1005
|
return this;
|
|
835
1006
|
}
|
|
836
1007
|
|
|
1008
|
+
define.classMethod('map', {callback: false, promise:false, returns: [Cursor]});
|
|
1009
|
+
|
|
837
1010
|
/**
|
|
838
1011
|
* Is the cursor closed
|
|
839
1012
|
* @method
|
|
@@ -843,12 +1016,16 @@ Cursor.prototype.isClosed = function() {
|
|
|
843
1016
|
return this.isDead();
|
|
844
1017
|
}
|
|
845
1018
|
|
|
1019
|
+
define.classMethod('isClosed', {callback: false, promise:false, returns: [Boolean]});
|
|
1020
|
+
|
|
846
1021
|
Cursor.prototype.destroy = function(err) {
|
|
847
1022
|
this.pause();
|
|
848
1023
|
this.close();
|
|
849
1024
|
if(err) this.emit('error', err);
|
|
850
1025
|
}
|
|
851
1026
|
|
|
1027
|
+
define.classMethod('destroy', {callback: false, promise:false});
|
|
1028
|
+
|
|
852
1029
|
/**
|
|
853
1030
|
* Return a modified Readable stream including a possible transform method.
|
|
854
1031
|
* @method
|
|
@@ -861,6 +1038,8 @@ Cursor.prototype.stream = function(options) {
|
|
|
861
1038
|
return this;
|
|
862
1039
|
}
|
|
863
1040
|
|
|
1041
|
+
define.classMethod('stream', {callback: false, promise:false, returns: [Cursor]});
|
|
1042
|
+
|
|
864
1043
|
/**
|
|
865
1044
|
* Execute the explain for the cursor
|
|
866
1045
|
* @method
|
|
@@ -871,6 +1050,11 @@ Cursor.prototype.explain = function(callback) {
|
|
|
871
1050
|
var self = this;
|
|
872
1051
|
this.s.cmd.explain = true;
|
|
873
1052
|
|
|
1053
|
+
// Do we have a readConcern
|
|
1054
|
+
if(this.s.cmd.readConcern) {
|
|
1055
|
+
delete this.s.cmd['readConcern'];
|
|
1056
|
+
}
|
|
1057
|
+
|
|
874
1058
|
// Execute using callback
|
|
875
1059
|
if(typeof callback == 'function') return this._next(callback);
|
|
876
1060
|
|
|
@@ -878,11 +1062,13 @@ Cursor.prototype.explain = function(callback) {
|
|
|
878
1062
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
879
1063
|
self._next(function(err, r) {
|
|
880
1064
|
if(err) return reject(err);
|
|
881
|
-
resolve(r);
|
|
1065
|
+
resolve(r);
|
|
882
1066
|
});
|
|
883
1067
|
});
|
|
884
1068
|
}
|
|
885
1069
|
|
|
1070
|
+
define.classMethod('explain', {callback: true, promise:true});
|
|
1071
|
+
|
|
886
1072
|
Cursor.prototype._read = function(n) {
|
|
887
1073
|
var self = this;
|
|
888
1074
|
if(self.s.state == Cursor.CLOSED || self.isDead()) {
|
|
@@ -898,7 +1084,8 @@ Cursor.prototype._read = function(n) {
|
|
|
898
1084
|
}
|
|
899
1085
|
|
|
900
1086
|
// Emit end event
|
|
901
|
-
|
|
1087
|
+
self.emit('end');
|
|
1088
|
+
return self.emit('finish');
|
|
902
1089
|
}
|
|
903
1090
|
|
|
904
1091
|
// If we provided a transformation method
|
|
@@ -916,6 +1103,17 @@ Cursor.prototype._read = function(n) {
|
|
|
916
1103
|
});
|
|
917
1104
|
}
|
|
918
1105
|
|
|
1106
|
+
Object.defineProperty(Cursor.prototype, 'readPreference', {
|
|
1107
|
+
enumerable:true,
|
|
1108
|
+
get: function() {
|
|
1109
|
+
if (!this || !this.s) {
|
|
1110
|
+
return null;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
return this.s.options.readPreference;
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
|
|
919
1117
|
Object.defineProperty(Cursor.prototype, 'namespace', {
|
|
920
1118
|
enumerable: true,
|
|
921
1119
|
get: function() {
|