mongodb 2.2.36 → 3.0.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/.eslintrc +24 -10
- package/CHANGES_3.0.0.md +288 -0
- package/HISTORY.md +120 -25
- package/README.md +247 -176
- package/conf.json +15 -14
- package/index.js +12 -6
- package/lib/admin.js +156 -364
- package/lib/aggregation_cursor.js +86 -88
- package/lib/apm.js +192 -149
- package/lib/authenticate.js +73 -53
- package/lib/bulk/common.js +140 -115
- package/lib/bulk/ordered.js +273 -195
- package/lib/bulk/unordered.js +291 -201
- package/lib/change_stream.js +359 -0
- package/lib/collection.js +1128 -1368
- package/lib/command_cursor.js +100 -73
- package/lib/cursor.js +454 -358
- package/lib/db.js +775 -771
- package/lib/gridfs/chunk.js +38 -34
- package/lib/gridfs/grid_store.js +590 -593
- package/lib/gridfs-stream/download.js +46 -40
- package/lib/gridfs-stream/index.js +24 -45
- package/lib/gridfs-stream/upload.js +28 -26
- package/lib/metadata.js +22 -16
- package/lib/mongo_client.js +708 -285
- package/lib/topologies/mongos.js +444 -0
- package/lib/topologies/replset.js +501 -0
- package/lib/topologies/server.js +448 -0
- package/lib/topologies/topology_base.js +441 -0
- package/lib/url_parser.js +334 -257
- package/lib/utils.js +210 -132
- package/package.json +20 -32
- package/yarn.lock +3728 -0
- package/lib/mongos.js +0 -533
- package/lib/read_preference.js +0 -131
- package/lib/replset.js +0 -582
- package/lib/server.js +0 -518
- package/lib/topology_base.js +0 -191
package/lib/cursor.js
CHANGED
|
@@ -1,44 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var inherits = require('util').inherits
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var inherits = require('util').inherits,
|
|
4
|
+
f = require('util').format,
|
|
5
|
+
formattedOrderClause = require('./utils').formattedOrderClause,
|
|
6
|
+
handleCallback = require('./utils').handleCallback,
|
|
7
|
+
ReadPreference = require('mongodb-core').ReadPreference,
|
|
8
|
+
MongoError = require('mongodb-core').MongoError,
|
|
9
|
+
Readable = require('stream').Readable,
|
|
10
|
+
Define = require('./metadata'),
|
|
11
|
+
CoreCursor = require('mongodb-core').Cursor,
|
|
12
|
+
Map = require('mongodb-core').BSON.Map,
|
|
13
|
+
executeOperation = require('./utils').executeOperation;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @fileOverview The **Cursor** class is an internal class that embodies a cursor on MongoDB
|
|
17
17
|
* allowing for iteration over the results returned from the underlying query. It supports
|
|
18
|
-
* one by one document iteration, conversion to an array or can be iterated as a Node
|
|
18
|
+
* one by one document iteration, conversion to an array or can be iterated as a Node 4.X
|
|
19
19
|
* or higher stream
|
|
20
20
|
*
|
|
21
21
|
* **CURSORS Cannot directly be instantiated**
|
|
22
22
|
* @example
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* const MongoClient = require('mongodb').MongoClient;
|
|
24
|
+
* const test = require('assert');
|
|
25
25
|
* // Connection url
|
|
26
|
-
*
|
|
26
|
+
* const url = 'mongodb://localhost:27017';
|
|
27
|
+
* // Database Name
|
|
28
|
+
* const dbName = 'test';
|
|
27
29
|
* // Connect using MongoClient
|
|
28
|
-
* MongoClient.connect(url, function(err,
|
|
30
|
+
* MongoClient.connect(url, function(err, client) {
|
|
29
31
|
* // Create a collection we want to drop later
|
|
30
|
-
*
|
|
32
|
+
* const col = client.db(dbName).collection('createIndexExample1');
|
|
31
33
|
* // Insert a bunch of documents
|
|
32
34
|
* col.insert([{a:1, b:1}
|
|
33
35
|
* , {a:2, b:2}, {a:3, b:3}
|
|
34
36
|
* , {a:4, b:4}], {w:1}, function(err, result) {
|
|
35
37
|
* test.equal(null, err);
|
|
36
|
-
*
|
|
37
38
|
* // Show that duplicate records got dropped
|
|
38
39
|
* col.find({}).toArray(function(err, items) {
|
|
39
40
|
* test.equal(null, err);
|
|
40
41
|
* test.equal(4, items.length);
|
|
41
|
-
*
|
|
42
|
+
* client.close();
|
|
42
43
|
* });
|
|
43
44
|
* });
|
|
44
45
|
* });
|
|
@@ -99,7 +100,6 @@ var push = Array.prototype.push;
|
|
|
99
100
|
*/
|
|
100
101
|
var Cursor = function(bson, ns, cmd, options, topology, topologyOptions) {
|
|
101
102
|
CoreCursor.apply(this, Array.prototype.slice.call(arguments, 0));
|
|
102
|
-
var self = this;
|
|
103
103
|
var state = Cursor.INIT;
|
|
104
104
|
var streamOptions = {};
|
|
105
105
|
|
|
@@ -109,61 +109,58 @@ var Cursor = function(bson, ns, cmd, options, topology, topologyOptions) {
|
|
|
109
109
|
var currentNumberOfRetries = numberOfRetries;
|
|
110
110
|
|
|
111
111
|
// Get the promiseLibrary
|
|
112
|
-
var promiseLibrary = options.promiseLibrary;
|
|
113
|
-
|
|
114
|
-
// No promise library selected fall back
|
|
115
|
-
if(!promiseLibrary) {
|
|
116
|
-
promiseLibrary = typeof global.Promise == 'function' ?
|
|
117
|
-
global.Promise : require('es6-promise').Promise;
|
|
118
|
-
}
|
|
112
|
+
var promiseLibrary = options.promiseLibrary || Promise;
|
|
119
113
|
|
|
120
114
|
// Set up
|
|
121
|
-
Readable.call(this, {objectMode: true});
|
|
115
|
+
Readable.call(this, { objectMode: true });
|
|
122
116
|
|
|
123
117
|
// Internal cursor state
|
|
124
118
|
this.s = {
|
|
125
119
|
// Tailable cursor options
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
numberOfRetries: numberOfRetries,
|
|
121
|
+
tailableRetryInterval: tailableRetryInterval,
|
|
122
|
+
currentNumberOfRetries: currentNumberOfRetries,
|
|
129
123
|
// State
|
|
130
|
-
|
|
124
|
+
state: state,
|
|
131
125
|
// Stream options
|
|
132
|
-
|
|
126
|
+
streamOptions: streamOptions,
|
|
133
127
|
// BSON
|
|
134
|
-
|
|
128
|
+
bson: bson,
|
|
135
129
|
// Namespace
|
|
136
|
-
|
|
130
|
+
ns: ns,
|
|
137
131
|
// Command
|
|
138
|
-
|
|
132
|
+
cmd: cmd,
|
|
139
133
|
// Options
|
|
140
|
-
|
|
134
|
+
options: options,
|
|
141
135
|
// Topology
|
|
142
|
-
|
|
136
|
+
topology: topology,
|
|
143
137
|
// Topology options
|
|
144
|
-
|
|
138
|
+
topologyOptions: topologyOptions,
|
|
145
139
|
// Promise library
|
|
146
|
-
|
|
140
|
+
promiseLibrary: promiseLibrary,
|
|
147
141
|
// Current doc
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
currentDoc: null,
|
|
143
|
+
// Optional ClientSession
|
|
144
|
+
session: options.session
|
|
145
|
+
};
|
|
150
146
|
|
|
151
147
|
// Translate correctly
|
|
152
|
-
if(
|
|
153
|
-
|
|
148
|
+
if (this.s.options.noCursorTimeout === true) {
|
|
149
|
+
this.addCursorFlag('noCursorTimeout', true);
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
// Set the sort value
|
|
157
|
-
this.sortValue =
|
|
153
|
+
this.sortValue = this.s.cmd.sort;
|
|
158
154
|
|
|
159
155
|
// Get the batchSize
|
|
160
|
-
var batchSize =
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
var batchSize =
|
|
157
|
+
cmd.cursor && cmd.cursor.batchSize
|
|
158
|
+
? cmd.cursor && cmd.cursor.batchSize
|
|
159
|
+
: options.cursor && options.cursor.batchSize ? options.cursor.batchSize : 1000;
|
|
163
160
|
|
|
164
161
|
// Set the batchSize
|
|
165
162
|
this.setCursorBatchSize(batchSize);
|
|
166
|
-
}
|
|
163
|
+
};
|
|
167
164
|
|
|
168
165
|
/**
|
|
169
166
|
* Cursor stream data event, fired for each document in the cursor.
|
|
@@ -199,11 +196,11 @@ inherits(Cursor, Readable);
|
|
|
199
196
|
// Map core cursor _next method so we can apply mapping
|
|
200
197
|
CoreCursor.prototype._next = CoreCursor.prototype.next;
|
|
201
198
|
|
|
202
|
-
for(var name in CoreCursor.prototype) {
|
|
199
|
+
for (var name in CoreCursor.prototype) {
|
|
203
200
|
Cursor.prototype[name] = CoreCursor.prototype[name];
|
|
204
201
|
}
|
|
205
202
|
|
|
206
|
-
var define = Cursor.define = new Define('Cursor', Cursor, true);
|
|
203
|
+
var define = (Cursor.define = new Define('Cursor', Cursor, true));
|
|
207
204
|
|
|
208
205
|
/**
|
|
209
206
|
* Check if there is any document still available in the cursor
|
|
@@ -213,39 +210,26 @@ var define = Cursor.define = new Define('Cursor', Cursor, true);
|
|
|
213
210
|
* @return {Promise} returns Promise if no callback passed
|
|
214
211
|
*/
|
|
215
212
|
Cursor.prototype.hasNext = function(callback) {
|
|
216
|
-
|
|
213
|
+
return executeOperation(this.s.topology, hasNext, [this, callback], {
|
|
214
|
+
skipSessions: true
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
if(
|
|
220
|
-
|
|
221
|
-
return callback(null, true);
|
|
222
|
-
} else {
|
|
223
|
-
return nextObject(self, function(err, doc) {
|
|
224
|
-
if (err) return callback(err, null);
|
|
225
|
-
if (!doc) return callback(null, false);
|
|
226
|
-
self.s.currentDoc = doc;
|
|
227
|
-
callback(null, true);
|
|
228
|
-
});
|
|
229
|
-
}
|
|
218
|
+
const hasNext = (self, callback) => {
|
|
219
|
+
if (self.s.currentDoc) {
|
|
220
|
+
return callback(null, true);
|
|
230
221
|
}
|
|
231
222
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if(self.s.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if(self.s.state == Cursor.CLOSED || self.isDead()) return resolve(false);
|
|
239
|
-
if(err) return reject(err);
|
|
240
|
-
if(!doc) return resolve(false);
|
|
241
|
-
self.s.currentDoc = doc;
|
|
242
|
-
resolve(true);
|
|
243
|
-
});
|
|
244
|
-
}
|
|
223
|
+
nextObject(self, function(err, doc) {
|
|
224
|
+
if (err) return callback(err, null);
|
|
225
|
+
if (self.s.state === Cursor.CLOSED || self.isDead()) return callback(null, false);
|
|
226
|
+
if (!doc) return callback(null, false);
|
|
227
|
+
self.s.currentDoc = doc;
|
|
228
|
+
callback(null, true);
|
|
245
229
|
});
|
|
246
|
-
}
|
|
230
|
+
};
|
|
247
231
|
|
|
248
|
-
define.classMethod('hasNext', {callback: true, promise:true});
|
|
232
|
+
define.classMethod('hasNext', { callback: true, promise: true });
|
|
249
233
|
|
|
250
234
|
/**
|
|
251
235
|
* Get the next available document from the cursor, returns null if no more documents are available.
|
|
@@ -255,38 +239,24 @@ define.classMethod('hasNext', {callback: true, promise:true});
|
|
|
255
239
|
* @return {Promise} returns Promise if no callback passed
|
|
256
240
|
*/
|
|
257
241
|
Cursor.prototype.next = function(callback) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
// Return the currentDoc if someone called hasNext first
|
|
263
|
-
if(self.s.currentDoc) {
|
|
264
|
-
var doc = self.s.currentDoc;
|
|
265
|
-
self.s.currentDoc = null;
|
|
266
|
-
return callback(null, doc);
|
|
267
|
-
}
|
|
242
|
+
return executeOperation(this.s.topology, next, [this, callback], {
|
|
243
|
+
skipSessions: true
|
|
244
|
+
});
|
|
245
|
+
};
|
|
268
246
|
|
|
269
|
-
|
|
270
|
-
|
|
247
|
+
const next = (self, callback) => {
|
|
248
|
+
// Return the currentDoc if someone called hasNext first
|
|
249
|
+
if (self.s.currentDoc) {
|
|
250
|
+
var doc = self.s.currentDoc;
|
|
251
|
+
self.s.currentDoc = null;
|
|
252
|
+
return callback(null, doc);
|
|
271
253
|
}
|
|
272
254
|
|
|
273
|
-
// Return
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if(self.s.currentDoc) {
|
|
277
|
-
var doc = self.s.currentDoc;
|
|
278
|
-
self.s.currentDoc = null;
|
|
279
|
-
return resolve(doc);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
nextObject(self, function(err, r) {
|
|
283
|
-
if(err) return reject(err);
|
|
284
|
-
resolve(r);
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
}
|
|
255
|
+
// Return the next object
|
|
256
|
+
nextObject(self, callback);
|
|
257
|
+
};
|
|
288
258
|
|
|
289
|
-
define.classMethod('next', {callback: true, promise:true});
|
|
259
|
+
define.classMethod('next', { callback: true, promise: true });
|
|
290
260
|
|
|
291
261
|
/**
|
|
292
262
|
* Set the cursor query
|
|
@@ -295,12 +265,15 @@ define.classMethod('next', {callback: true, promise:true});
|
|
|
295
265
|
* @return {Cursor}
|
|
296
266
|
*/
|
|
297
267
|
Cursor.prototype.filter = function(filter) {
|
|
298
|
-
if(this.s.state
|
|
268
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
269
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
270
|
+
}
|
|
271
|
+
|
|
299
272
|
this.s.cmd.query = filter;
|
|
300
273
|
return this;
|
|
301
|
-
}
|
|
274
|
+
};
|
|
302
275
|
|
|
303
|
-
define.classMethod('filter', {callback: false, promise:false, returns: [Cursor]});
|
|
276
|
+
define.classMethod('filter', { callback: false, promise: false, returns: [Cursor] });
|
|
304
277
|
|
|
305
278
|
/**
|
|
306
279
|
* Set the cursor maxScan
|
|
@@ -309,12 +282,15 @@ define.classMethod('filter', {callback: false, promise:false, returns: [Cursor]}
|
|
|
309
282
|
* @return {Cursor}
|
|
310
283
|
*/
|
|
311
284
|
Cursor.prototype.maxScan = function(maxScan) {
|
|
312
|
-
if(this.s.state
|
|
285
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
286
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
287
|
+
}
|
|
288
|
+
|
|
313
289
|
this.s.cmd.maxScan = maxScan;
|
|
314
290
|
return this;
|
|
315
|
-
}
|
|
291
|
+
};
|
|
316
292
|
|
|
317
|
-
define.classMethod('maxScan', {callback: false, promise:false, returns: [Cursor]});
|
|
293
|
+
define.classMethod('maxScan', { callback: false, promise: false, returns: [Cursor] });
|
|
318
294
|
|
|
319
295
|
/**
|
|
320
296
|
* Set the cursor hint
|
|
@@ -323,12 +299,15 @@ define.classMethod('maxScan', {callback: false, promise:false, returns: [Cursor]
|
|
|
323
299
|
* @return {Cursor}
|
|
324
300
|
*/
|
|
325
301
|
Cursor.prototype.hint = function(hint) {
|
|
326
|
-
if(this.s.state
|
|
302
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
303
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
304
|
+
}
|
|
305
|
+
|
|
327
306
|
this.s.cmd.hint = hint;
|
|
328
307
|
return this;
|
|
329
|
-
}
|
|
308
|
+
};
|
|
330
309
|
|
|
331
|
-
define.classMethod('hint', {callback: false, promise:false, returns: [Cursor]});
|
|
310
|
+
define.classMethod('hint', { callback: false, promise: false, returns: [Cursor] });
|
|
332
311
|
|
|
333
312
|
/**
|
|
334
313
|
* Set the cursor min
|
|
@@ -337,12 +316,13 @@ define.classMethod('hint', {callback: false, promise:false, returns: [Cursor]});
|
|
|
337
316
|
* @return {Cursor}
|
|
338
317
|
*/
|
|
339
318
|
Cursor.prototype.min = function(min) {
|
|
340
|
-
if(this.s.state
|
|
319
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead())
|
|
320
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
341
321
|
this.s.cmd.min = min;
|
|
342
322
|
return this;
|
|
343
|
-
}
|
|
323
|
+
};
|
|
344
324
|
|
|
345
|
-
define.classMethod('min', {callback: false, promise:false, returns: [Cursor]});
|
|
325
|
+
define.classMethod('min', { callback: false, promise: false, returns: [Cursor] });
|
|
346
326
|
|
|
347
327
|
/**
|
|
348
328
|
* Set the cursor max
|
|
@@ -351,12 +331,15 @@ define.classMethod('min', {callback: false, promise:false, returns: [Cursor]});
|
|
|
351
331
|
* @return {Cursor}
|
|
352
332
|
*/
|
|
353
333
|
Cursor.prototype.max = function(max) {
|
|
354
|
-
if(this.s.state
|
|
334
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
335
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
336
|
+
}
|
|
337
|
+
|
|
355
338
|
this.s.cmd.max = max;
|
|
356
339
|
return this;
|
|
357
|
-
}
|
|
340
|
+
};
|
|
358
341
|
|
|
359
|
-
define.classMethod('max', {callback: false, promise:false, returns: [Cursor]});
|
|
342
|
+
define.classMethod('max', { callback: false, promise: false, returns: [Cursor] });
|
|
360
343
|
|
|
361
344
|
/**
|
|
362
345
|
* Set the cursor returnKey
|
|
@@ -365,12 +348,15 @@ define.classMethod('max', {callback: false, promise:false, returns: [Cursor]});
|
|
|
365
348
|
* @return {Cursor}
|
|
366
349
|
*/
|
|
367
350
|
Cursor.prototype.returnKey = function(value) {
|
|
368
|
-
if(this.s.state
|
|
351
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
352
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
353
|
+
}
|
|
354
|
+
|
|
369
355
|
this.s.cmd.returnKey = value;
|
|
370
356
|
return this;
|
|
371
|
-
}
|
|
357
|
+
};
|
|
372
358
|
|
|
373
|
-
define.classMethod('returnKey', {callback: false, promise:false, returns: [Cursor]});
|
|
359
|
+
define.classMethod('returnKey', { callback: false, promise: false, returns: [Cursor] });
|
|
374
360
|
|
|
375
361
|
/**
|
|
376
362
|
* Set the cursor showRecordId
|
|
@@ -379,12 +365,15 @@ define.classMethod('returnKey', {callback: false, promise:false, returns: [Curso
|
|
|
379
365
|
* @return {Cursor}
|
|
380
366
|
*/
|
|
381
367
|
Cursor.prototype.showRecordId = function(value) {
|
|
382
|
-
if(this.s.state
|
|
368
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
369
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
370
|
+
}
|
|
371
|
+
|
|
383
372
|
this.s.cmd.showDiskLoc = value;
|
|
384
373
|
return this;
|
|
385
|
-
}
|
|
374
|
+
};
|
|
386
375
|
|
|
387
|
-
define.classMethod('showRecordId', {callback: false, promise:false, returns: [Cursor]});
|
|
376
|
+
define.classMethod('showRecordId', { callback: false, promise: false, returns: [Cursor] });
|
|
388
377
|
|
|
389
378
|
/**
|
|
390
379
|
* Set the cursor snapshot
|
|
@@ -393,12 +382,15 @@ define.classMethod('showRecordId', {callback: false, promise:false, returns: [Cu
|
|
|
393
382
|
* @return {Cursor}
|
|
394
383
|
*/
|
|
395
384
|
Cursor.prototype.snapshot = function(value) {
|
|
396
|
-
if(this.s.state
|
|
385
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
386
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
387
|
+
}
|
|
388
|
+
|
|
397
389
|
this.s.cmd.snapshot = value;
|
|
398
390
|
return this;
|
|
399
|
-
}
|
|
391
|
+
};
|
|
400
392
|
|
|
401
|
-
define.classMethod('snapshot', {callback: false, promise:false, returns: [Cursor]});
|
|
393
|
+
define.classMethod('snapshot', { callback: false, promise: false, returns: [Cursor] });
|
|
402
394
|
|
|
403
395
|
/**
|
|
404
396
|
* Set a node.js specific cursor option
|
|
@@ -409,15 +401,23 @@ define.classMethod('snapshot', {callback: false, promise:false, returns: [Cursor
|
|
|
409
401
|
* @return {Cursor}
|
|
410
402
|
*/
|
|
411
403
|
Cursor.prototype.setCursorOption = function(field, value) {
|
|
412
|
-
if(this.s.state
|
|
413
|
-
|
|
404
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
405
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (fields.indexOf(field) === -1) {
|
|
409
|
+
throw MongoError.create({
|
|
410
|
+
message: f('option %s not a supported option %s', field, fields),
|
|
411
|
+
driver: true
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
|
|
414
415
|
this.s[field] = value;
|
|
415
|
-
if(field
|
|
416
|
-
this.s.currentNumberOfRetries = value;
|
|
416
|
+
if (field === 'numberOfRetries') this.s.currentNumberOfRetries = value;
|
|
417
417
|
return this;
|
|
418
|
-
}
|
|
418
|
+
};
|
|
419
419
|
|
|
420
|
-
define.classMethod('setCursorOption', {callback: false, promise:false, returns: [Cursor]});
|
|
420
|
+
define.classMethod('setCursorOption', { callback: false, promise: false, returns: [Cursor] });
|
|
421
421
|
|
|
422
422
|
/**
|
|
423
423
|
* Add a cursor flag to the cursor
|
|
@@ -428,14 +428,26 @@ define.classMethod('setCursorOption', {callback: false, promise:false, returns:
|
|
|
428
428
|
* @return {Cursor}
|
|
429
429
|
*/
|
|
430
430
|
Cursor.prototype.addCursorFlag = function(flag, value) {
|
|
431
|
-
if(this.s.state
|
|
432
|
-
|
|
433
|
-
|
|
431
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
432
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (flags.indexOf(flag) === -1) {
|
|
436
|
+
throw MongoError.create({
|
|
437
|
+
message: f('flag %s not a supported flag %s', flag, flags),
|
|
438
|
+
driver: true
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (typeof value !== 'boolean') {
|
|
443
|
+
throw MongoError.create({ message: f('flag %s must be a boolean value', flag), driver: true });
|
|
444
|
+
}
|
|
445
|
+
|
|
434
446
|
this.s.cmd[flag] = value;
|
|
435
447
|
return this;
|
|
436
|
-
}
|
|
448
|
+
};
|
|
437
449
|
|
|
438
|
-
define.classMethod('addCursorFlag', {callback: false, promise:false, returns: [Cursor]});
|
|
450
|
+
define.classMethod('addCursorFlag', { callback: false, promise: false, returns: [Cursor] });
|
|
439
451
|
|
|
440
452
|
/**
|
|
441
453
|
* Add a query modifier to the cursor query
|
|
@@ -446,18 +458,24 @@ define.classMethod('addCursorFlag', {callback: false, promise:false, returns: [C
|
|
|
446
458
|
* @return {Cursor}
|
|
447
459
|
*/
|
|
448
460
|
Cursor.prototype.addQueryModifier = function(name, value) {
|
|
449
|
-
if(this.s.state
|
|
450
|
-
|
|
461
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
462
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (name[0] !== '$') {
|
|
466
|
+
throw MongoError.create({ message: f('%s is not a valid query modifier'), driver: true });
|
|
467
|
+
}
|
|
468
|
+
|
|
451
469
|
// Strip of the $
|
|
452
470
|
var field = name.substr(1);
|
|
453
471
|
// Set on the command
|
|
454
472
|
this.s.cmd[field] = value;
|
|
455
473
|
// Deal with the special case for sort
|
|
456
|
-
if(field
|
|
474
|
+
if (field === 'orderby') this.s.cmd.sort = this.s.cmd[field];
|
|
457
475
|
return this;
|
|
458
|
-
}
|
|
476
|
+
};
|
|
459
477
|
|
|
460
|
-
define.classMethod('addQueryModifier', {callback: false, promise:false, returns: [Cursor]});
|
|
478
|
+
define.classMethod('addQueryModifier', { callback: false, promise: false, returns: [Cursor] });
|
|
461
479
|
|
|
462
480
|
/**
|
|
463
481
|
* Add a comment to the cursor query allowing for tracking the comment in the log.
|
|
@@ -467,12 +485,15 @@ define.classMethod('addQueryModifier', {callback: false, promise:false, returns:
|
|
|
467
485
|
* @return {Cursor}
|
|
468
486
|
*/
|
|
469
487
|
Cursor.prototype.comment = function(value) {
|
|
470
|
-
if(this.s.state
|
|
488
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
489
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
490
|
+
}
|
|
491
|
+
|
|
471
492
|
this.s.cmd.comment = value;
|
|
472
493
|
return this;
|
|
473
|
-
}
|
|
494
|
+
};
|
|
474
495
|
|
|
475
|
-
define.classMethod('comment', {callback: false, promise:false, returns: [Cursor]});
|
|
496
|
+
define.classMethod('comment', { callback: false, promise: false, returns: [Cursor] });
|
|
476
497
|
|
|
477
498
|
/**
|
|
478
499
|
* 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)
|
|
@@ -482,13 +503,19 @@ define.classMethod('comment', {callback: false, promise:false, returns: [Cursor]
|
|
|
482
503
|
* @return {Cursor}
|
|
483
504
|
*/
|
|
484
505
|
Cursor.prototype.maxAwaitTimeMS = function(value) {
|
|
485
|
-
if(typeof value
|
|
486
|
-
|
|
506
|
+
if (typeof value !== 'number') {
|
|
507
|
+
throw MongoError.create({ message: 'maxAwaitTimeMS must be a number', driver: true });
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
511
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
512
|
+
}
|
|
513
|
+
|
|
487
514
|
this.s.cmd.maxAwaitTimeMS = value;
|
|
488
515
|
return this;
|
|
489
|
-
}
|
|
516
|
+
};
|
|
490
517
|
|
|
491
|
-
define.classMethod('maxAwaitTimeMS', {callback: false, promise:false, returns: [Cursor]});
|
|
518
|
+
define.classMethod('maxAwaitTimeMS', { callback: false, promise: false, returns: [Cursor] });
|
|
492
519
|
|
|
493
520
|
/**
|
|
494
521
|
* Set a maxTimeMS on the cursor query, allowing for hard timeout limits on queries (Only supported on MongoDB 2.6 or higher)
|
|
@@ -498,17 +525,23 @@ define.classMethod('maxAwaitTimeMS', {callback: false, promise:false, returns: [
|
|
|
498
525
|
* @return {Cursor}
|
|
499
526
|
*/
|
|
500
527
|
Cursor.prototype.maxTimeMS = function(value) {
|
|
501
|
-
if(typeof value
|
|
502
|
-
|
|
528
|
+
if (typeof value !== 'number') {
|
|
529
|
+
throw MongoError.create({ message: 'maxTimeMS must be a number', driver: true });
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
533
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
534
|
+
}
|
|
535
|
+
|
|
503
536
|
this.s.cmd.maxTimeMS = value;
|
|
504
537
|
return this;
|
|
505
|
-
}
|
|
538
|
+
};
|
|
506
539
|
|
|
507
|
-
define.classMethod('maxTimeMS', {callback: false, promise:false, returns: [Cursor]});
|
|
540
|
+
define.classMethod('maxTimeMS', { callback: false, promise: false, returns: [Cursor] });
|
|
508
541
|
|
|
509
542
|
Cursor.prototype.maxTimeMs = Cursor.prototype.maxTimeMS;
|
|
510
543
|
|
|
511
|
-
define.classMethod('maxTimeMs', {callback: false, promise:false, returns: [Cursor]});
|
|
544
|
+
define.classMethod('maxTimeMs', { callback: false, promise: false, returns: [Cursor] });
|
|
512
545
|
|
|
513
546
|
/**
|
|
514
547
|
* Sets a field projection for the query.
|
|
@@ -518,12 +551,15 @@ define.classMethod('maxTimeMs', {callback: false, promise:false, returns: [Curso
|
|
|
518
551
|
* @return {Cursor}
|
|
519
552
|
*/
|
|
520
553
|
Cursor.prototype.project = function(value) {
|
|
521
|
-
if(this.s.state
|
|
554
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
555
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
556
|
+
}
|
|
557
|
+
|
|
522
558
|
this.s.cmd.fields = value;
|
|
523
559
|
return this;
|
|
524
|
-
}
|
|
560
|
+
};
|
|
525
561
|
|
|
526
|
-
define.classMethod('project', {callback: false, promise:false, returns: [Cursor]});
|
|
562
|
+
define.classMethod('project', { callback: false, promise: false, returns: [Cursor] });
|
|
527
563
|
|
|
528
564
|
/**
|
|
529
565
|
* Sets the sort order of the cursor query.
|
|
@@ -534,39 +570,49 @@ define.classMethod('project', {callback: false, promise:false, returns: [Cursor]
|
|
|
534
570
|
* @return {Cursor}
|
|
535
571
|
*/
|
|
536
572
|
Cursor.prototype.sort = function(keyOrList, direction) {
|
|
537
|
-
if(this.s.options.tailable)
|
|
538
|
-
|
|
573
|
+
if (this.s.options.tailable) {
|
|
574
|
+
throw MongoError.create({ message: "Tailable cursor doesn't support sorting", driver: true });
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (this.s.state === Cursor.CLOSED || this.s.state === Cursor.OPEN || this.isDead()) {
|
|
578
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
579
|
+
}
|
|
580
|
+
|
|
539
581
|
var order = keyOrList;
|
|
540
582
|
|
|
541
583
|
// We have an array of arrays, we need to preserve the order of the sort
|
|
542
584
|
// so we will us a Map
|
|
543
|
-
if(Array.isArray(order) && Array.isArray(order[0])) {
|
|
544
|
-
order = new Map(
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
585
|
+
if (Array.isArray(order) && Array.isArray(order[0])) {
|
|
586
|
+
order = new Map(
|
|
587
|
+
order.map(function(x) {
|
|
588
|
+
var value = [x[0], null];
|
|
589
|
+
if (x[1] === 'asc') {
|
|
590
|
+
value[1] = 1;
|
|
591
|
+
} else if (x[1] === 'desc') {
|
|
592
|
+
value[1] = -1;
|
|
593
|
+
} else if (x[1] === 1 || x[1] === -1) {
|
|
594
|
+
value[1] = x[1];
|
|
595
|
+
} else {
|
|
596
|
+
throw new MongoError(
|
|
597
|
+
"Illegal sort clause, must be of the form [['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"
|
|
598
|
+
);
|
|
599
|
+
}
|
|
555
600
|
|
|
556
|
-
|
|
557
|
-
|
|
601
|
+
return value;
|
|
602
|
+
})
|
|
603
|
+
);
|
|
558
604
|
}
|
|
559
605
|
|
|
560
|
-
if(direction != null) {
|
|
606
|
+
if (direction != null) {
|
|
561
607
|
order = [[keyOrList, direction]];
|
|
562
608
|
}
|
|
563
609
|
|
|
564
610
|
this.s.cmd.sort = order;
|
|
565
611
|
this.sortValue = order;
|
|
566
612
|
return this;
|
|
567
|
-
}
|
|
613
|
+
};
|
|
568
614
|
|
|
569
|
-
define.classMethod('sort', {callback: false, promise:false, returns: [Cursor]});
|
|
615
|
+
define.classMethod('sort', { callback: false, promise: false, returns: [Cursor] });
|
|
570
616
|
|
|
571
617
|
/**
|
|
572
618
|
* Set the batch size for the cursor.
|
|
@@ -576,15 +622,24 @@ define.classMethod('sort', {callback: false, promise:false, returns: [Cursor]});
|
|
|
576
622
|
* @return {Cursor}
|
|
577
623
|
*/
|
|
578
624
|
Cursor.prototype.batchSize = function(value) {
|
|
579
|
-
if(this.s.options.tailable)
|
|
580
|
-
|
|
581
|
-
|
|
625
|
+
if (this.s.options.tailable) {
|
|
626
|
+
throw MongoError.create({ message: "Tailable cursor doesn't support batchSize", driver: true });
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
if (this.s.state === Cursor.CLOSED || this.isDead()) {
|
|
630
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
if (typeof value !== 'number') {
|
|
634
|
+
throw MongoError.create({ message: 'batchSize requires an integer', driver: true });
|
|
635
|
+
}
|
|
636
|
+
|
|
582
637
|
this.s.cmd.batchSize = value;
|
|
583
638
|
this.setCursorBatchSize(value);
|
|
584
639
|
return this;
|
|
585
|
-
}
|
|
640
|
+
};
|
|
586
641
|
|
|
587
|
-
define.classMethod('batchSize', {callback: false, promise:false, returns: [Cursor]});
|
|
642
|
+
define.classMethod('batchSize', { callback: false, promise: false, returns: [Cursor] });
|
|
588
643
|
|
|
589
644
|
/**
|
|
590
645
|
* Set the collation options for the cursor.
|
|
@@ -596,9 +651,9 @@ define.classMethod('batchSize', {callback: false, promise:false, returns: [Curso
|
|
|
596
651
|
Cursor.prototype.collation = function(value) {
|
|
597
652
|
this.s.cmd.collation = value;
|
|
598
653
|
return this;
|
|
599
|
-
}
|
|
654
|
+
};
|
|
600
655
|
|
|
601
|
-
define.classMethod('collation', {callback: false, promise:false, returns: [Cursor]});
|
|
656
|
+
define.classMethod('collation', { callback: false, promise: false, returns: [Cursor] });
|
|
602
657
|
|
|
603
658
|
/**
|
|
604
659
|
* Set the limit for the cursor.
|
|
@@ -608,16 +663,25 @@ define.classMethod('collation', {callback: false, promise:false, returns: [Curso
|
|
|
608
663
|
* @return {Cursor}
|
|
609
664
|
*/
|
|
610
665
|
Cursor.prototype.limit = function(value) {
|
|
611
|
-
if(this.s.options.tailable)
|
|
612
|
-
|
|
613
|
-
|
|
666
|
+
if (this.s.options.tailable) {
|
|
667
|
+
throw MongoError.create({ message: "Tailable cursor doesn't support limit", driver: true });
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (this.s.state === Cursor.OPEN || this.s.state === Cursor.CLOSED || this.isDead()) {
|
|
671
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
if (typeof value !== 'number') {
|
|
675
|
+
throw MongoError.create({ message: 'limit requires an integer', driver: true });
|
|
676
|
+
}
|
|
677
|
+
|
|
614
678
|
this.s.cmd.limit = value;
|
|
615
679
|
// this.cursorLimit = value;
|
|
616
680
|
this.setCursorLimit(value);
|
|
617
681
|
return this;
|
|
618
|
-
}
|
|
682
|
+
};
|
|
619
683
|
|
|
620
|
-
define.classMethod('limit', {callback: false, promise:false, returns: [Cursor]});
|
|
684
|
+
define.classMethod('limit', { callback: false, promise: false, returns: [Cursor] });
|
|
621
685
|
|
|
622
686
|
/**
|
|
623
687
|
* Set the skip for the cursor.
|
|
@@ -627,15 +691,24 @@ define.classMethod('limit', {callback: false, promise:false, returns: [Cursor]})
|
|
|
627
691
|
* @return {Cursor}
|
|
628
692
|
*/
|
|
629
693
|
Cursor.prototype.skip = function(value) {
|
|
630
|
-
if(this.s.options.tailable)
|
|
631
|
-
|
|
632
|
-
|
|
694
|
+
if (this.s.options.tailable) {
|
|
695
|
+
throw MongoError.create({ message: "Tailable cursor doesn't support skip", driver: true });
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (this.s.state === Cursor.OPEN || this.s.state === Cursor.CLOSED || this.isDead()) {
|
|
699
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (typeof value !== 'number') {
|
|
703
|
+
throw MongoError.create({ message: 'skip requires an integer', driver: true });
|
|
704
|
+
}
|
|
705
|
+
|
|
633
706
|
this.s.cmd.skip = value;
|
|
634
707
|
this.setCursorSkip(value);
|
|
635
708
|
return this;
|
|
636
|
-
}
|
|
709
|
+
};
|
|
637
710
|
|
|
638
|
-
define.classMethod('skip', {callback: false, promise:false, returns: [Cursor]});
|
|
711
|
+
define.classMethod('skip', { callback: false, promise: false, returns: [Cursor] });
|
|
639
712
|
|
|
640
713
|
/**
|
|
641
714
|
* The callback format for results
|
|
@@ -656,22 +729,17 @@ define.classMethod('skip', {callback: false, promise:false, returns: [Cursor]});
|
|
|
656
729
|
* @return {null}
|
|
657
730
|
*/
|
|
658
731
|
|
|
659
|
-
|
|
660
|
-
* Get the next available document from the cursor, returns null if no more documents are available.
|
|
661
|
-
* @method
|
|
662
|
-
* @param {Cursor~resultCallback} [callback] The result callback.
|
|
663
|
-
* @throws {MongoError}
|
|
664
|
-
* @deprecated
|
|
665
|
-
* @return {Promise} returns Promise if no callback passed
|
|
666
|
-
*/
|
|
667
|
-
Cursor.prototype.nextObject = Cursor.prototype.next;
|
|
668
|
-
|
|
732
|
+
// Get the next available document from the cursor, returns null if no more documents are available.
|
|
669
733
|
var nextObject = function(self, callback) {
|
|
670
|
-
if(self.s.state
|
|
671
|
-
|
|
734
|
+
if (self.s.state === Cursor.CLOSED || (self.isDead && self.isDead()))
|
|
735
|
+
return handleCallback(
|
|
736
|
+
callback,
|
|
737
|
+
MongoError.create({ message: 'Cursor is closed', driver: true })
|
|
738
|
+
);
|
|
739
|
+
if (self.s.state === Cursor.INIT && self.s.cmd.sort) {
|
|
672
740
|
try {
|
|
673
741
|
self.s.cmd.sort = formattedOrderClause(self.s.cmd.sort);
|
|
674
|
-
} catch(err) {
|
|
742
|
+
} catch (err) {
|
|
675
743
|
return handleCallback(callback, err);
|
|
676
744
|
}
|
|
677
745
|
}
|
|
@@ -679,31 +747,25 @@ var nextObject = function(self, callback) {
|
|
|
679
747
|
// Get the next object
|
|
680
748
|
self._next(function(err, doc) {
|
|
681
749
|
self.s.state = Cursor.OPEN;
|
|
682
|
-
if(err) return handleCallback(callback, err);
|
|
750
|
+
if (err) return handleCallback(callback, err);
|
|
683
751
|
handleCallback(callback, null, doc);
|
|
684
752
|
});
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
define.classMethod('nextObject', {callback: true, promise:true});
|
|
753
|
+
};
|
|
688
754
|
|
|
689
755
|
// Trampoline emptying the number of retrieved items
|
|
690
756
|
// without incurring a nextTick operation
|
|
691
757
|
var loop = function(self, callback) {
|
|
692
758
|
// No more items we are done
|
|
693
|
-
if(self.bufferedCount()
|
|
759
|
+
if (self.bufferedCount() === 0) return;
|
|
694
760
|
// Get the next document
|
|
695
761
|
self._next(callback);
|
|
696
762
|
// Loop
|
|
697
763
|
return loop;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
Cursor.prototype.next = Cursor.prototype.nextObject;
|
|
701
|
-
|
|
702
|
-
define.classMethod('next', {callback: true, promise:true});
|
|
764
|
+
};
|
|
703
765
|
|
|
704
766
|
/**
|
|
705
767
|
* Iterates over all the documents for this cursor. As with **{cursor.toArray}**,
|
|
706
|
-
* not all of the elements will be iterated if this cursor had been
|
|
768
|
+
* not all of the elements will be iterated if this cursor had been previouly accessed.
|
|
707
769
|
* In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike
|
|
708
770
|
* **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements
|
|
709
771
|
* at any given time if batch size is specified. Otherwise, the caller is responsible
|
|
@@ -723,37 +785,39 @@ Cursor.prototype.each = function(callback) {
|
|
|
723
785
|
_each(this, callback);
|
|
724
786
|
};
|
|
725
787
|
|
|
726
|
-
define.classMethod('each', {callback: true, promise:false});
|
|
788
|
+
define.classMethod('each', { callback: true, promise: false });
|
|
727
789
|
|
|
728
790
|
// Run the each loop
|
|
729
791
|
var _each = function(self, callback) {
|
|
730
|
-
if(!callback) throw MongoError.create({message: 'callback is mandatory', driver:true});
|
|
731
|
-
if(self.isNotified()) return;
|
|
732
|
-
if(self.s.state
|
|
733
|
-
return handleCallback(
|
|
792
|
+
if (!callback) throw MongoError.create({ message: 'callback is mandatory', driver: true });
|
|
793
|
+
if (self.isNotified()) return;
|
|
794
|
+
if (self.s.state === Cursor.CLOSED || self.isDead()) {
|
|
795
|
+
return handleCallback(
|
|
796
|
+
callback,
|
|
797
|
+
MongoError.create({ message: 'Cursor is closed', driver: true })
|
|
798
|
+
);
|
|
734
799
|
}
|
|
735
800
|
|
|
736
|
-
if(self.s.state
|
|
801
|
+
if (self.s.state === Cursor.INIT) self.s.state = Cursor.OPEN;
|
|
737
802
|
|
|
738
803
|
// Define function to avoid global scope escape
|
|
739
804
|
var fn = null;
|
|
740
805
|
// Trampoline all the entries
|
|
741
|
-
if(self.bufferedCount() > 0) {
|
|
742
|
-
while(fn = loop(self, callback)) fn(self, callback);
|
|
806
|
+
if (self.bufferedCount() > 0) {
|
|
807
|
+
while ((fn = loop(self, callback))) fn(self, callback);
|
|
743
808
|
_each(self, callback);
|
|
744
809
|
} else {
|
|
745
810
|
self.next(function(err, item) {
|
|
746
|
-
if(err) return handleCallback(callback, err);
|
|
747
|
-
if(item == null) {
|
|
748
|
-
self.
|
|
749
|
-
return handleCallback(callback, null, null);
|
|
811
|
+
if (err) return handleCallback(callback, err);
|
|
812
|
+
if (item == null) {
|
|
813
|
+
return self.close({ skipKillCursors: true }, () => handleCallback(callback, null, null));
|
|
750
814
|
}
|
|
751
815
|
|
|
752
|
-
if(handleCallback(callback, null, item)
|
|
816
|
+
if (handleCallback(callback, null, item) === false) return;
|
|
753
817
|
_each(self, callback);
|
|
754
|
-
})
|
|
818
|
+
});
|
|
755
819
|
}
|
|
756
|
-
}
|
|
820
|
+
};
|
|
757
821
|
|
|
758
822
|
/**
|
|
759
823
|
* The callback format for the forEach iterator method
|
|
@@ -776,19 +840,25 @@ var _each = function(self, callback) {
|
|
|
776
840
|
* @return {null}
|
|
777
841
|
*/
|
|
778
842
|
Cursor.prototype.forEach = function(iterator, callback) {
|
|
779
|
-
this.each(function(err, doc){
|
|
780
|
-
if(err) {
|
|
781
|
-
|
|
782
|
-
|
|
843
|
+
this.each(function(err, doc) {
|
|
844
|
+
if (err) {
|
|
845
|
+
callback(err);
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
848
|
+
if (doc != null) {
|
|
849
|
+
iterator(doc);
|
|
850
|
+
return true;
|
|
851
|
+
}
|
|
852
|
+
if (doc == null && callback) {
|
|
783
853
|
var internalCallback = callback;
|
|
784
854
|
callback = null;
|
|
785
855
|
internalCallback(null);
|
|
786
856
|
return false;
|
|
787
857
|
}
|
|
788
858
|
});
|
|
789
|
-
}
|
|
859
|
+
};
|
|
790
860
|
|
|
791
|
-
define.classMethod('forEach', {callback: true, promise:false});
|
|
861
|
+
define.classMethod('forEach', { callback: true, promise: false });
|
|
792
862
|
|
|
793
863
|
/**
|
|
794
864
|
* Set the ReadPreference for the cursor.
|
|
@@ -797,20 +867,26 @@ define.classMethod('forEach', {callback: true, promise:false});
|
|
|
797
867
|
* @throws {MongoError}
|
|
798
868
|
* @return {Cursor}
|
|
799
869
|
*/
|
|
800
|
-
Cursor.prototype.setReadPreference = function(
|
|
801
|
-
if(this.s.state
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
}
|
|
807
|
-
|
|
870
|
+
Cursor.prototype.setReadPreference = function(readPreference) {
|
|
871
|
+
if (this.s.state !== Cursor.INIT) {
|
|
872
|
+
throw MongoError.create({
|
|
873
|
+
message: 'cannot change cursor readPreference after cursor has been accessed',
|
|
874
|
+
driver: true
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
if (readPreference instanceof ReadPreference) {
|
|
879
|
+
this.s.options.readPreference = readPreference;
|
|
880
|
+
} else if (typeof readPreference === 'string') {
|
|
881
|
+
this.s.options.readPreference = new ReadPreference(readPreference);
|
|
882
|
+
} else {
|
|
883
|
+
throw new TypeError('Invalid read preference: ' + readPreference);
|
|
808
884
|
}
|
|
809
885
|
|
|
810
886
|
return this;
|
|
811
|
-
}
|
|
887
|
+
};
|
|
812
888
|
|
|
813
|
-
define.classMethod('setReadPreference', {callback: false, promise:false, returns: [Cursor]});
|
|
889
|
+
define.classMethod('setReadPreference', { callback: false, promise: false, returns: [Cursor] });
|
|
814
890
|
|
|
815
891
|
/**
|
|
816
892
|
* The callback format for results
|
|
@@ -822,7 +898,7 @@ define.classMethod('setReadPreference', {callback: false, promise:false, returns
|
|
|
822
898
|
/**
|
|
823
899
|
* Returns an array of documents. The caller is responsible for making sure that there
|
|
824
900
|
* is enough memory to store the results. Note that the array only contain partial
|
|
825
|
-
* results when this cursor had been
|
|
901
|
+
* results when this cursor had been previouly accessed. In that case,
|
|
826
902
|
* cursor.rewind() can be used to reset the cursor.
|
|
827
903
|
* @method
|
|
828
904
|
* @param {Cursor~toArrayResultCallback} [callback] The result callback.
|
|
@@ -831,19 +907,17 @@ define.classMethod('setReadPreference', {callback: false, promise:false, returns
|
|
|
831
907
|
*/
|
|
832
908
|
Cursor.prototype.toArray = function(callback) {
|
|
833
909
|
var self = this;
|
|
834
|
-
if(self.s.options.tailable)
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
// Return a Promise
|
|
840
|
-
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
841
|
-
toArray(self, function(err, r) {
|
|
842
|
-
if(err) return reject(err);
|
|
843
|
-
resolve(r);
|
|
910
|
+
if (self.s.options.tailable) {
|
|
911
|
+
throw MongoError.create({
|
|
912
|
+
message: 'Tailable cursor cannot be converted to array',
|
|
913
|
+
driver: true
|
|
844
914
|
});
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
return executeOperation(this.s.topology, toArray, [this, callback], {
|
|
918
|
+
skipSessions: true
|
|
845
919
|
});
|
|
846
|
-
}
|
|
920
|
+
};
|
|
847
921
|
|
|
848
922
|
var toArray = function(self, callback) {
|
|
849
923
|
var items = [];
|
|
@@ -855,21 +929,20 @@ var toArray = function(self, callback) {
|
|
|
855
929
|
// Fetch all the documents
|
|
856
930
|
var fetchDocs = function() {
|
|
857
931
|
self._next(function(err, doc) {
|
|
858
|
-
if(err) return handleCallback(callback, err);
|
|
859
|
-
if(doc == null) {
|
|
860
|
-
self.
|
|
861
|
-
return handleCallback(callback, null, items);
|
|
932
|
+
if (err) return handleCallback(callback, err);
|
|
933
|
+
if (doc == null) {
|
|
934
|
+
return self.close({ skipKillCursors: true }, () => handleCallback(callback, null, items));
|
|
862
935
|
}
|
|
863
936
|
|
|
864
937
|
// Add doc to items
|
|
865
|
-
items.push(doc)
|
|
938
|
+
items.push(doc);
|
|
866
939
|
|
|
867
940
|
// Get all buffered objects
|
|
868
|
-
if(self.bufferedCount() > 0) {
|
|
869
|
-
var docs = self.readBufferedDocuments(self.bufferedCount())
|
|
941
|
+
if (self.bufferedCount() > 0) {
|
|
942
|
+
var docs = self.readBufferedDocuments(self.bufferedCount());
|
|
870
943
|
|
|
871
944
|
// Transform the doc if transform method added
|
|
872
|
-
if(self.s.transforms && typeof self.s.transforms.doc
|
|
945
|
+
if (self.s.transforms && typeof self.s.transforms.doc === 'function') {
|
|
873
946
|
docs = docs.map(self.s.transforms.doc);
|
|
874
947
|
}
|
|
875
948
|
|
|
@@ -878,13 +951,13 @@ var toArray = function(self, callback) {
|
|
|
878
951
|
|
|
879
952
|
// Attempt a fetch
|
|
880
953
|
fetchDocs();
|
|
881
|
-
})
|
|
882
|
-
}
|
|
954
|
+
});
|
|
955
|
+
};
|
|
883
956
|
|
|
884
957
|
fetchDocs();
|
|
885
|
-
}
|
|
958
|
+
};
|
|
886
959
|
|
|
887
|
-
define.classMethod('toArray', {callback: true, promise:true});
|
|
960
|
+
define.classMethod('toArray', { callback: true, promise: true });
|
|
888
961
|
|
|
889
962
|
/**
|
|
890
963
|
* The callback format for results
|
|
@@ -900,102 +973,120 @@ define.classMethod('toArray', {callback: true, promise:true});
|
|
|
900
973
|
* @param {object} [options=null] Optional settings.
|
|
901
974
|
* @param {number} [options.skip=null] The number of documents to skip.
|
|
902
975
|
* @param {number} [options.limit=null] The maximum amounts to count before aborting.
|
|
903
|
-
* @param {number} [options.maxTimeMS=null] Number of
|
|
976
|
+
* @param {number} [options.maxTimeMS=null] Number of miliseconds to wait before aborting the query.
|
|
904
977
|
* @param {string} [options.hint=null] An index name hint for the query.
|
|
905
978
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
906
979
|
* @param {Cursor~countResultCallback} [callback] The result callback.
|
|
907
980
|
* @return {Promise} returns Promise if no callback passed
|
|
908
981
|
*/
|
|
909
982
|
Cursor.prototype.count = function(applySkipLimit, opts, callback) {
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
if(typeof opts
|
|
983
|
+
if (this.s.cmd.query == null)
|
|
984
|
+
throw MongoError.create({ message: 'count can only be used with find command', driver: true });
|
|
985
|
+
if (typeof opts === 'function') (callback = opts), (opts = {});
|
|
913
986
|
opts = opts || {};
|
|
914
987
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
// Return a Promise
|
|
919
|
-
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
920
|
-
count(self, applySkipLimit, opts, function(err, r) {
|
|
921
|
-
if(err) return reject(err);
|
|
922
|
-
resolve(r);
|
|
923
|
-
});
|
|
988
|
+
return executeOperation(this.s.topology, count, [this, applySkipLimit, opts, callback], {
|
|
989
|
+
skipSessions: true
|
|
924
990
|
});
|
|
925
991
|
};
|
|
926
992
|
|
|
927
993
|
var count = function(self, applySkipLimit, opts, callback) {
|
|
928
|
-
if(typeof applySkipLimit
|
|
994
|
+
if (typeof applySkipLimit === 'function') {
|
|
929
995
|
callback = applySkipLimit;
|
|
930
996
|
applySkipLimit = true;
|
|
931
997
|
}
|
|
932
998
|
|
|
933
|
-
if(applySkipLimit) {
|
|
934
|
-
if(typeof self.cursorSkip()
|
|
935
|
-
if(typeof self.cursorLimit()
|
|
999
|
+
if (applySkipLimit) {
|
|
1000
|
+
if (typeof self.cursorSkip() === 'number') opts.skip = self.cursorSkip();
|
|
1001
|
+
if (typeof self.cursorLimit() === 'number') opts.limit = self.cursorLimit();
|
|
936
1002
|
}
|
|
937
1003
|
|
|
938
1004
|
// Command
|
|
939
1005
|
var delimiter = self.s.ns.indexOf('.');
|
|
940
1006
|
|
|
941
1007
|
var command = {
|
|
942
|
-
|
|
943
|
-
|
|
1008
|
+
count: self.s.ns.substr(delimiter + 1),
|
|
1009
|
+
query: self.s.cmd.query
|
|
1010
|
+
};
|
|
944
1011
|
|
|
945
1012
|
// Apply a readConcern if set
|
|
946
|
-
if(self.s.cmd.readConcern) {
|
|
1013
|
+
if (self.s.cmd.readConcern) {
|
|
947
1014
|
command.readConcern = self.s.cmd.readConcern;
|
|
948
1015
|
}
|
|
949
1016
|
|
|
950
1017
|
// Apply a hint if set
|
|
951
|
-
if(self.s.cmd.hint) {
|
|
1018
|
+
if (self.s.cmd.hint) {
|
|
952
1019
|
command.hint = self.s.cmd.hint;
|
|
953
1020
|
}
|
|
954
1021
|
|
|
955
|
-
if(typeof opts.maxTimeMS
|
|
1022
|
+
if (typeof opts.maxTimeMS === 'number') {
|
|
956
1023
|
command.maxTimeMS = opts.maxTimeMS;
|
|
957
|
-
} else if(self.s.cmd && typeof self.s.cmd.maxTimeMS
|
|
1024
|
+
} else if (self.s.cmd && typeof self.s.cmd.maxTimeMS === 'number') {
|
|
958
1025
|
command.maxTimeMS = self.s.cmd.maxTimeMS;
|
|
959
1026
|
}
|
|
960
1027
|
|
|
961
1028
|
// Merge in any options
|
|
962
|
-
if(opts.skip) command.skip = opts.skip;
|
|
963
|
-
if(opts.limit) command.limit = opts.limit;
|
|
964
|
-
if(self.s.options.hint) command.hint = self.s.options.hint;
|
|
1029
|
+
if (opts.skip) command.skip = opts.skip;
|
|
1030
|
+
if (opts.limit) command.limit = opts.limit;
|
|
1031
|
+
if (self.s.options.hint) command.hint = self.s.options.hint;
|
|
965
1032
|
|
|
966
1033
|
// Set cursor server to the same as the topology
|
|
967
|
-
self.server = self.topology;
|
|
1034
|
+
self.server = self.topology.s.coreTopology;
|
|
968
1035
|
|
|
969
1036
|
// Execute the command
|
|
970
|
-
self.topology.command(
|
|
971
|
-
,
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1037
|
+
self.s.topology.command(
|
|
1038
|
+
f('%s.$cmd', self.s.ns.substr(0, delimiter)),
|
|
1039
|
+
command,
|
|
1040
|
+
function(err, result) {
|
|
1041
|
+
callback(err, result ? result.result.n : null);
|
|
1042
|
+
},
|
|
1043
|
+
self.options
|
|
1044
|
+
);
|
|
1045
|
+
};
|
|
975
1046
|
|
|
976
|
-
define.classMethod('count', {callback: true, promise:true});
|
|
1047
|
+
define.classMethod('count', { callback: true, promise: true });
|
|
977
1048
|
|
|
978
1049
|
/**
|
|
979
1050
|
* Close the cursor, sending a KillCursor command and emitting close.
|
|
980
1051
|
* @method
|
|
1052
|
+
* @param {object} [options] Optional settings.
|
|
1053
|
+
* @param {boolean} [options.skipKillCursors] Bypass calling killCursors when closing the cursor.
|
|
981
1054
|
* @param {Cursor~resultCallback} [callback] The result callback.
|
|
982
1055
|
* @return {Promise} returns Promise if no callback passed
|
|
983
1056
|
*/
|
|
984
|
-
Cursor.prototype.close = function(callback) {
|
|
1057
|
+
Cursor.prototype.close = function(options, callback) {
|
|
1058
|
+
if (typeof options === 'function') (callback = options), (options = {});
|
|
1059
|
+
options = Object.assign({}, { skipKillCursors: false }, options);
|
|
1060
|
+
|
|
985
1061
|
this.s.state = Cursor.CLOSED;
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
// Callback if provided
|
|
991
|
-
if(typeof callback == 'function') return handleCallback(callback, null, this);
|
|
992
|
-
// Return a Promise
|
|
993
|
-
return new this.s.promiseLibrary(function(resolve) {
|
|
994
|
-
resolve();
|
|
995
|
-
});
|
|
996
|
-
}
|
|
1062
|
+
if (!options.skipKillCursors) {
|
|
1063
|
+
// Kill the cursor
|
|
1064
|
+
this.kill();
|
|
1065
|
+
}
|
|
997
1066
|
|
|
998
|
-
|
|
1067
|
+
const completeClose = () => {
|
|
1068
|
+
// Emit the close event for the cursor
|
|
1069
|
+
this.emit('close');
|
|
1070
|
+
|
|
1071
|
+
// Callback if provided
|
|
1072
|
+
if (typeof callback === 'function') {
|
|
1073
|
+
return handleCallback(callback, null, this);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// Return a Promise
|
|
1077
|
+
return new this.s.promiseLibrary(function(resolve) {
|
|
1078
|
+
resolve();
|
|
1079
|
+
});
|
|
1080
|
+
};
|
|
1081
|
+
|
|
1082
|
+
if (this.s.session) {
|
|
1083
|
+
return this.s.session.endSession(() => completeClose());
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
return completeClose();
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1089
|
+
define.classMethod('close', { callback: true, promise: true });
|
|
999
1090
|
|
|
1000
1091
|
/**
|
|
1001
1092
|
* Map all documents using the provided function
|
|
@@ -1004,16 +1095,18 @@ define.classMethod('close', {callback: true, promise:true});
|
|
|
1004
1095
|
* @return {Cursor}
|
|
1005
1096
|
*/
|
|
1006
1097
|
Cursor.prototype.map = function(transform) {
|
|
1007
|
-
if(this.cursorState.transforms && this.cursorState.transforms.doc) {
|
|
1098
|
+
if (this.cursorState.transforms && this.cursorState.transforms.doc) {
|
|
1008
1099
|
var oldTransform = this.cursorState.transforms.doc;
|
|
1009
|
-
this.cursorState.transforms.doc = function
|
|
1100
|
+
this.cursorState.transforms.doc = function(doc) {
|
|
1101
|
+
return transform(oldTransform(doc));
|
|
1102
|
+
};
|
|
1010
1103
|
} else {
|
|
1011
1104
|
this.cursorState.transforms = { doc: transform };
|
|
1012
1105
|
}
|
|
1013
1106
|
return this;
|
|
1014
|
-
}
|
|
1107
|
+
};
|
|
1015
1108
|
|
|
1016
|
-
define.classMethod('map', {callback: false, promise:false, returns: [Cursor]});
|
|
1109
|
+
define.classMethod('map', { callback: false, promise: false, returns: [Cursor] });
|
|
1017
1110
|
|
|
1018
1111
|
/**
|
|
1019
1112
|
* Is the cursor closed
|
|
@@ -1022,17 +1115,17 @@ define.classMethod('map', {callback: false, promise:false, returns: [Cursor]});
|
|
|
1022
1115
|
*/
|
|
1023
1116
|
Cursor.prototype.isClosed = function() {
|
|
1024
1117
|
return this.isDead();
|
|
1025
|
-
}
|
|
1118
|
+
};
|
|
1026
1119
|
|
|
1027
|
-
define.classMethod('isClosed', {callback: false, promise:false, returns: [Boolean]});
|
|
1120
|
+
define.classMethod('isClosed', { callback: false, promise: false, returns: [Boolean] });
|
|
1028
1121
|
|
|
1029
1122
|
Cursor.prototype.destroy = function(err) {
|
|
1030
|
-
if(err) this.emit('error', err);
|
|
1123
|
+
if (err) this.emit('error', err);
|
|
1031
1124
|
this.pause();
|
|
1032
1125
|
this.close();
|
|
1033
|
-
}
|
|
1126
|
+
};
|
|
1034
1127
|
|
|
1035
|
-
define.classMethod('destroy', {callback: false, promise:false});
|
|
1128
|
+
define.classMethod('destroy', { callback: false, promise: false });
|
|
1036
1129
|
|
|
1037
1130
|
/**
|
|
1038
1131
|
* Return a modified Readable stream including a possible transform method.
|
|
@@ -1044,9 +1137,9 @@ define.classMethod('destroy', {callback: false, promise:false});
|
|
|
1044
1137
|
Cursor.prototype.stream = function(options) {
|
|
1045
1138
|
this.s.streamOptions = options || {};
|
|
1046
1139
|
return this;
|
|
1047
|
-
}
|
|
1140
|
+
};
|
|
1048
1141
|
|
|
1049
|
-
define.classMethod('stream', {callback: false, promise:false, returns: [Cursor]});
|
|
1142
|
+
define.classMethod('stream', { callback: false, promise: false, returns: [Cursor] });
|
|
1050
1143
|
|
|
1051
1144
|
/**
|
|
1052
1145
|
* Execute the explain for the cursor
|
|
@@ -1055,41 +1148,33 @@ define.classMethod('stream', {callback: false, promise:false, returns: [Cursor]}
|
|
|
1055
1148
|
* @return {Promise} returns Promise if no callback passed
|
|
1056
1149
|
*/
|
|
1057
1150
|
Cursor.prototype.explain = function(callback) {
|
|
1058
|
-
var self = this;
|
|
1059
1151
|
this.s.cmd.explain = true;
|
|
1060
1152
|
|
|
1061
1153
|
// Do we have a readConcern
|
|
1062
|
-
if(this.s.cmd.readConcern) {
|
|
1154
|
+
if (this.s.cmd.readConcern) {
|
|
1063
1155
|
delete this.s.cmd['readConcern'];
|
|
1064
1156
|
}
|
|
1065
1157
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
// Return a Promise
|
|
1070
|
-
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
1071
|
-
self._next(function(err, r) {
|
|
1072
|
-
if(err) return reject(err);
|
|
1073
|
-
resolve(r);
|
|
1074
|
-
});
|
|
1158
|
+
return executeOperation(this.s.topology, this._next.bind(this), [callback], {
|
|
1159
|
+
skipSessions: true
|
|
1075
1160
|
});
|
|
1076
|
-
}
|
|
1161
|
+
};
|
|
1077
1162
|
|
|
1078
|
-
define.classMethod('explain', {callback: true, promise:true});
|
|
1163
|
+
define.classMethod('explain', { callback: true, promise: true });
|
|
1079
1164
|
|
|
1080
1165
|
Cursor.prototype._read = function() {
|
|
1081
1166
|
var self = this;
|
|
1082
|
-
if(self.s.state
|
|
1167
|
+
if (self.s.state === Cursor.CLOSED || self.isDead()) {
|
|
1083
1168
|
return self.push(null);
|
|
1084
1169
|
}
|
|
1085
1170
|
|
|
1086
1171
|
// Get the next item
|
|
1087
|
-
self.
|
|
1088
|
-
if(err) {
|
|
1089
|
-
if(self.listeners('error') && self.listeners('error').length > 0) {
|
|
1172
|
+
self.next(function(err, result) {
|
|
1173
|
+
if (err) {
|
|
1174
|
+
if (self.listeners('error') && self.listeners('error').length > 0) {
|
|
1090
1175
|
self.emit('error', err);
|
|
1091
1176
|
}
|
|
1092
|
-
if(!self.isDead()) self.close();
|
|
1177
|
+
if (!self.isDead()) self.close();
|
|
1093
1178
|
|
|
1094
1179
|
// Emit end event
|
|
1095
1180
|
self.emit('end');
|
|
@@ -1097,22 +1182,33 @@ Cursor.prototype._read = function() {
|
|
|
1097
1182
|
}
|
|
1098
1183
|
|
|
1099
1184
|
// If we provided a transformation method
|
|
1100
|
-
if(typeof self.s.streamOptions.transform
|
|
1185
|
+
if (typeof self.s.streamOptions.transform === 'function' && result != null) {
|
|
1101
1186
|
return self.push(self.s.streamOptions.transform(result));
|
|
1102
1187
|
}
|
|
1103
1188
|
|
|
1104
1189
|
// If we provided a map function
|
|
1105
|
-
if(
|
|
1190
|
+
if (
|
|
1191
|
+
self.cursorState.transforms &&
|
|
1192
|
+
typeof self.cursorState.transforms.doc === 'function' &&
|
|
1193
|
+
result != null
|
|
1194
|
+
) {
|
|
1106
1195
|
return self.push(self.cursorState.transforms.doc(result));
|
|
1107
1196
|
}
|
|
1108
1197
|
|
|
1109
1198
|
// Return the result
|
|
1110
1199
|
self.push(result);
|
|
1200
|
+
|
|
1201
|
+
if (result === null && self.isDead()) {
|
|
1202
|
+
self.once('end', () => {
|
|
1203
|
+
self.close();
|
|
1204
|
+
self.emit('finish');
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1111
1207
|
});
|
|
1112
|
-
}
|
|
1208
|
+
};
|
|
1113
1209
|
|
|
1114
1210
|
Object.defineProperty(Cursor.prototype, 'readPreference', {
|
|
1115
|
-
enumerable:true,
|
|
1211
|
+
enumerable: true,
|
|
1116
1212
|
get: function() {
|
|
1117
1213
|
if (!this || !this.s) {
|
|
1118
1214
|
return null;
|