mongodb 3.5.3 → 3.5.7
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 +60 -0
- package/README.md +1 -1
- package/lib/change_stream.js +12 -13
- package/lib/cmap/connection_pool.js +1 -1
- package/lib/collection.js +1 -1
- package/lib/core/cursor.js +0 -9
- package/lib/core/sdam/server.js +4 -2
- package/lib/core/sdam/server_selection.js +4 -0
- package/lib/core/sdam/topology.js +37 -31
- package/lib/core/sdam/topology_description.js +27 -5
- package/lib/core/sessions.js +18 -8
- package/lib/core/topologies/shared.js +9 -2
- package/lib/core/uri_parser.js +3 -3
- package/lib/core/utils.js +4 -1
- package/lib/cursor.js +88 -19
- package/lib/mongo_client.js +62 -19
- package/lib/operations/connect.js +1 -26
- package/lib/operations/count.js +0 -4
- package/lib/operations/cursor_ops.js +1 -72
- package/lib/operations/db_ops.js +0 -361
- package/lib/operations/execute_operation.js +2 -6
- package/lib/operations/find.js +1 -2
- package/lib/operations/operation.js +1 -3
- package/lib/operations/remove_user.js +1 -1
- package/lib/utils.js +43 -1
- package/package.json +5 -5
- package/lib/operations/close.js +0 -50
- package/lib/operations/explain.js +0 -23
- package/lib/operations/has_next.js +0 -40
- package/lib/operations/next.js +0 -32
- package/lib/operations/to_array.js +0 -66
package/lib/cursor.js
CHANGED
|
@@ -9,16 +9,12 @@ const MongoError = require('./core').MongoError;
|
|
|
9
9
|
const CoreCursor = require('./core/cursor').CoreCursor;
|
|
10
10
|
const CursorState = require('./core/cursor').CursorState;
|
|
11
11
|
const Map = require('./core').BSON.Map;
|
|
12
|
+
const maybePromise = require('./utils').maybePromise;
|
|
13
|
+
const executeOperation = require('./operations/execute_operation');
|
|
14
|
+
const formattedOrderClause = require('./utils').formattedOrderClause;
|
|
12
15
|
|
|
13
16
|
const each = require('./operations/cursor_ops').each;
|
|
14
|
-
|
|
15
17
|
const CountOperation = require('./operations/count');
|
|
16
|
-
const ExplainOperation = require('./operations/explain');
|
|
17
|
-
const HasNextOperation = require('./operations/has_next');
|
|
18
|
-
const NextOperation = require('./operations/next');
|
|
19
|
-
const ToArrayOperation = require('./operations/to_array');
|
|
20
|
-
|
|
21
|
-
const executeOperation = require('./operations/execute_operation');
|
|
22
18
|
|
|
23
19
|
/**
|
|
24
20
|
* @fileOverview The **Cursor** class is an internal class that embodies a cursor on MongoDB
|
|
@@ -128,8 +124,6 @@ class Cursor extends CoreCursor {
|
|
|
128
124
|
state: CursorState.INIT,
|
|
129
125
|
// Promise library
|
|
130
126
|
promiseLibrary,
|
|
131
|
-
// Current doc
|
|
132
|
-
currentDoc: null,
|
|
133
127
|
// explicitlyIgnoreSession
|
|
134
128
|
explicitlyIgnoreSession: !!options.explicitlyIgnoreSession
|
|
135
129
|
};
|
|
@@ -199,9 +193,33 @@ class Cursor extends CoreCursor {
|
|
|
199
193
|
* @return {Promise} returns Promise if no callback passed
|
|
200
194
|
*/
|
|
201
195
|
hasNext(callback) {
|
|
202
|
-
|
|
196
|
+
if (this.s.state === CursorState.CLOSED || (this.isDead && this.isDead())) {
|
|
197
|
+
throw MongoError.create({ message: 'Cursor is closed', driver: true });
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return maybePromise(this, callback, cb => {
|
|
201
|
+
const cursor = this;
|
|
202
|
+
if (cursor.isNotified()) {
|
|
203
|
+
return cb(null, false);
|
|
204
|
+
}
|
|
203
205
|
|
|
204
|
-
|
|
206
|
+
cursor._next((err, doc) => {
|
|
207
|
+
if (err) return cb(err);
|
|
208
|
+
if (doc == null || cursor.s.state === Cursor.CLOSED || cursor.isDead()) {
|
|
209
|
+
return cb(null, false);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
cursor.s.state = CursorState.OPEN;
|
|
213
|
+
|
|
214
|
+
// NODE-2482: merge this into the core cursor implementation
|
|
215
|
+
cursor.cursorState.cursorIndex--;
|
|
216
|
+
if (cursor.cursorState.limit > 0) {
|
|
217
|
+
cursor.cursorState.currentLimit--;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
cb(null, true);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
205
223
|
}
|
|
206
224
|
|
|
207
225
|
/**
|
|
@@ -212,9 +230,27 @@ class Cursor extends CoreCursor {
|
|
|
212
230
|
* @return {Promise} returns Promise if no callback passed
|
|
213
231
|
*/
|
|
214
232
|
next(callback) {
|
|
215
|
-
|
|
233
|
+
return maybePromise(this, callback, cb => {
|
|
234
|
+
const cursor = this;
|
|
235
|
+
if (cursor.s.state === CursorState.CLOSED || (cursor.isDead && cursor.isDead())) {
|
|
236
|
+
cb(MongoError.create({ message: 'Cursor is closed', driver: true }));
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
216
239
|
|
|
217
|
-
|
|
240
|
+
if (cursor.s.state === CursorState.INIT && cursor.cmd.sort) {
|
|
241
|
+
try {
|
|
242
|
+
cursor.cmd.sort = formattedOrderClause(cursor.cmd.sort);
|
|
243
|
+
} catch (err) {
|
|
244
|
+
return cb(err);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
cursor._next((err, doc) => {
|
|
249
|
+
if (err) return cb(err);
|
|
250
|
+
cursor.s.state = CursorState.OPEN;
|
|
251
|
+
cb(null, doc);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
218
254
|
}
|
|
219
255
|
|
|
220
256
|
/**
|
|
@@ -784,9 +820,43 @@ class Cursor extends CoreCursor {
|
|
|
784
820
|
});
|
|
785
821
|
}
|
|
786
822
|
|
|
787
|
-
|
|
823
|
+
return maybePromise(this, callback, cb => {
|
|
824
|
+
const cursor = this;
|
|
825
|
+
const items = [];
|
|
826
|
+
|
|
827
|
+
// Reset cursor
|
|
828
|
+
cursor.rewind();
|
|
829
|
+
cursor.s.state = CursorState.INIT;
|
|
830
|
+
|
|
831
|
+
// Fetch all the documents
|
|
832
|
+
const fetchDocs = () => {
|
|
833
|
+
cursor._next((err, doc) => {
|
|
834
|
+
if (err) {
|
|
835
|
+
return cursor._endSession
|
|
836
|
+
? cursor._endSession(() => handleCallback(cb, err))
|
|
837
|
+
: handleCallback(cb, err);
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (doc == null) {
|
|
841
|
+
return cursor.close({ skipKillCursors: true }, () => handleCallback(cb, null, items));
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// Add doc to items
|
|
845
|
+
items.push(doc);
|
|
846
|
+
|
|
847
|
+
// Get all buffered objects
|
|
848
|
+
if (cursor.bufferedCount() > 0) {
|
|
849
|
+
let docs = cursor.readBufferedDocuments(cursor.bufferedCount());
|
|
850
|
+
Array.prototype.push.apply(items, docs);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// Attempt a fetch
|
|
854
|
+
fetchDocs();
|
|
855
|
+
});
|
|
856
|
+
};
|
|
788
857
|
|
|
789
|
-
|
|
858
|
+
fetchDocs();
|
|
859
|
+
});
|
|
790
860
|
}
|
|
791
861
|
|
|
792
862
|
/**
|
|
@@ -971,10 +1041,9 @@ class Cursor extends CoreCursor {
|
|
|
971
1041
|
if (this.cmd.readConcern) {
|
|
972
1042
|
delete this.cmd['readConcern'];
|
|
973
1043
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
return executeOperation(this.topology, explainOperation, callback);
|
|
1044
|
+
return maybePromise(this, callback, cb => {
|
|
1045
|
+
CoreCursor.prototype._next.apply(this, [cb]);
|
|
1046
|
+
});
|
|
978
1047
|
}
|
|
979
1048
|
|
|
980
1049
|
/**
|
package/lib/mongo_client.js
CHANGED
|
@@ -3,17 +3,16 @@
|
|
|
3
3
|
const ChangeStream = require('./change_stream');
|
|
4
4
|
const Db = require('./db');
|
|
5
5
|
const EventEmitter = require('events').EventEmitter;
|
|
6
|
-
const executeOperation = require('./operations/execute_operation');
|
|
7
6
|
const inherits = require('util').inherits;
|
|
8
7
|
const MongoError = require('./core').MongoError;
|
|
9
8
|
const deprecate = require('util').deprecate;
|
|
10
9
|
const WriteConcern = require('./write_concern');
|
|
11
10
|
const MongoDBNamespace = require('./utils').MongoDBNamespace;
|
|
12
11
|
const ReadPreference = require('./core/topologies/read_preference');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
12
|
+
const maybePromise = require('./utils').maybePromise;
|
|
13
|
+
const NativeTopology = require('./topologies/native_topology');
|
|
14
|
+
const connect = require('./operations/connect').connect;
|
|
15
|
+
const validOptions = require('./operations/connect').validOptions;
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* @fileOverview The **MongoClient** class is a class that allows for making Connections to MongoDB.
|
|
@@ -144,6 +143,9 @@ const CloseOperation = require('./operations/close');
|
|
|
144
143
|
* @param {number} [options.minSize] If present, the connection pool will be initialized with minSize connections, and will never dip below minSize connections
|
|
145
144
|
* @param {boolean} [options.useNewUrlParser=true] Determines whether or not to use the new url parser. Enables the new, spec-compliant, url parser shipped in the core driver. This url parser fixes a number of problems with the original parser, and aims to outright replace that parser in the near future. Defaults to true, and must be explicitly set to false to use the legacy url parser.
|
|
146
145
|
* @param {boolean} [options.useUnifiedTopology] Enables the new unified topology layer
|
|
146
|
+
* @param {Number} [options.localThresholdMS=15] **Only applies to the unified topology** The size of the latency window for selecting among multiple suitable servers
|
|
147
|
+
* @param {Number} [options.serverSelectionTimeoutMS=30000] **Only applies to the unified topology** How long to block for server selection before throwing an error
|
|
148
|
+
* @param {Number} [options.heartbeatFrequencyMS=10000] **Only applies to the unified topology** The frequency with which topology updates are scheduled
|
|
147
149
|
* @param {AutoEncrypter~AutoEncryptionOptions} [options.autoEncryption] Optionally enable client side auto encryption
|
|
148
150
|
* @param {DriverInfoOptions} [options.driverInfo] Allows a wrapping driver to amend the client metadata generated by the driver to include information about the wrapping driver
|
|
149
151
|
* @param {MongoClient~connectCallback} [callback] The command result callback
|
|
@@ -158,18 +160,12 @@ function MongoClient(url, options) {
|
|
|
158
160
|
this.s = {
|
|
159
161
|
url: url,
|
|
160
162
|
options: options || {},
|
|
161
|
-
promiseLibrary:
|
|
163
|
+
promiseLibrary: (options && options.promiseLibrary) || Promise,
|
|
162
164
|
dbCache: new Map(),
|
|
163
165
|
sessions: new Set(),
|
|
164
166
|
writeConcern: WriteConcern.fromOptions(options),
|
|
165
167
|
namespace: new MongoDBNamespace('admin')
|
|
166
168
|
};
|
|
167
|
-
|
|
168
|
-
// Get the promiseLibrary
|
|
169
|
-
const promiseLibrary = this.s.options.promiseLibrary || Promise;
|
|
170
|
-
|
|
171
|
-
// Add the promise to the internal state
|
|
172
|
-
this.s.promiseLibrary = promiseLibrary;
|
|
173
169
|
}
|
|
174
170
|
|
|
175
171
|
/**
|
|
@@ -214,9 +210,16 @@ MongoClient.prototype.connect = function(callback) {
|
|
|
214
210
|
throw new TypeError('`connect` only accepts a callback');
|
|
215
211
|
}
|
|
216
212
|
|
|
217
|
-
const
|
|
213
|
+
const client = this;
|
|
214
|
+
return maybePromise(this, callback, cb => {
|
|
215
|
+
const err = validOptions(client.s.options);
|
|
216
|
+
if (err) return cb(err);
|
|
218
217
|
|
|
219
|
-
|
|
218
|
+
connect(client, client.s.url, client.s.options, err => {
|
|
219
|
+
if (err) return cb(err);
|
|
220
|
+
cb(null, client);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
220
223
|
};
|
|
221
224
|
|
|
222
225
|
MongoClient.prototype.logout = deprecate(function(options, callback) {
|
|
@@ -232,9 +235,41 @@ MongoClient.prototype.logout = deprecate(function(options, callback) {
|
|
|
232
235
|
* @return {Promise} returns Promise if no callback passed
|
|
233
236
|
*/
|
|
234
237
|
MongoClient.prototype.close = function(force, callback) {
|
|
235
|
-
if (typeof force === 'function')
|
|
236
|
-
|
|
237
|
-
|
|
238
|
+
if (typeof force === 'function') {
|
|
239
|
+
callback = force;
|
|
240
|
+
force = false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const client = this;
|
|
244
|
+
return maybePromise(this, callback, cb => {
|
|
245
|
+
const completeClose = err => {
|
|
246
|
+
client.emit('close', client);
|
|
247
|
+
|
|
248
|
+
if (!(client.topology instanceof NativeTopology)) {
|
|
249
|
+
for (const item of client.s.dbCache) {
|
|
250
|
+
item[1].emit('close', client);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
client.removeAllListeners('close');
|
|
255
|
+
cb(err);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
if (client.topology == null) {
|
|
259
|
+
completeClose();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
client.topology.close(force, err => {
|
|
264
|
+
const autoEncrypter = client.topology.s.options.autoEncrypter;
|
|
265
|
+
if (!autoEncrypter) {
|
|
266
|
+
completeClose(err);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
autoEncrypter.teardown(force, err2 => completeClose(err || err2));
|
|
271
|
+
});
|
|
272
|
+
});
|
|
238
273
|
};
|
|
239
274
|
|
|
240
275
|
/**
|
|
@@ -312,7 +347,7 @@ MongoClient.prototype.isConnected = function(options) {
|
|
|
312
347
|
* @param {object} [options] Optional settings
|
|
313
348
|
* @param {number} [options.poolSize=5] The maximum size of the individual server pool
|
|
314
349
|
* @param {boolean} [options.ssl=false] Enable SSL connection. *deprecated* use `tls` variants
|
|
315
|
-
* @param {boolean} [options.sslValidate=false] Validate mongod server certificate against Certificate Authority
|
|
350
|
+
* @param {boolean} [options.sslValidate=false] Validate mongod server certificate against Certificate Authority
|
|
316
351
|
* @param {buffer} [options.sslCA=undefined] SSL Certificate store binary buffer *deprecated* use `tls` variants
|
|
317
352
|
* @param {buffer} [options.sslCert=undefined] SSL Certificate binary buffer *deprecated* use `tls` variants
|
|
318
353
|
* @param {buffer} [options.sslKey=undefined] SSL Key file binary buffer *deprecated* use `tls` variants
|
|
@@ -329,7 +364,7 @@ MongoClient.prototype.isConnected = function(options) {
|
|
|
329
364
|
* @param {boolean} [options.autoReconnect=true] Enable autoReconnect for single server instances
|
|
330
365
|
* @param {boolean} [options.noDelay=true] TCP Connection no delay
|
|
331
366
|
* @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
|
|
332
|
-
* @param {
|
|
367
|
+
* @param {number} [options.keepAliveInitialDelay=30000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
333
368
|
* @param {number} [options.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
334
369
|
* @param {number} [options.socketTimeoutMS=360000] How long a send or receive on a socket can take before timing out
|
|
335
370
|
* @param {number} [options.family] Version of IP stack. Can be 4, 6 or null (default).
|
|
@@ -373,7 +408,15 @@ MongoClient.prototype.isConnected = function(options) {
|
|
|
373
408
|
* @param {array} [options.readPreferenceTags] Read preference tags
|
|
374
409
|
* @param {number} [options.numberOfRetries=5] The number of retries for a tailable cursor
|
|
375
410
|
* @param {boolean} [options.auto_reconnect=true] Enable auto reconnecting for single server instances
|
|
411
|
+
* @param {boolean} [options.monitorCommands=false] Enable command monitoring for this client
|
|
376
412
|
* @param {number} [options.minSize] If present, the connection pool will be initialized with minSize connections, and will never dip below minSize connections
|
|
413
|
+
* @param {boolean} [options.useNewUrlParser=true] Determines whether or not to use the new url parser. Enables the new, spec-compliant, url parser shipped in the core driver. This url parser fixes a number of problems with the original parser, and aims to outright replace that parser in the near future. Defaults to true, and must be explicitly set to false to use the legacy url parser.
|
|
414
|
+
* @param {boolean} [options.useUnifiedTopology] Enables the new unified topology layer
|
|
415
|
+
* @param {Number} [options.localThresholdMS=15] **Only applies to the unified topology** The size of the latency window for selecting among multiple suitable servers
|
|
416
|
+
* @param {Number} [options.serverSelectionTimeoutMS=30000] **Only applies to the unified topology** How long to block for server selection before throwing an error
|
|
417
|
+
* @param {Number} [options.heartbeatFrequencyMS=10000] **Only applies to the unified topology** The frequency with which topology updates are scheduled
|
|
418
|
+
* @param {AutoEncrypter~AutoEncryptionOptions} [options.autoEncryption] Optionally enable client side auto encryption
|
|
419
|
+
* @param {DriverInfoOptions} [options.driverInfo] Allows a wrapping driver to amend the client metadata generated by the driver to include information about the wrapping driver
|
|
377
420
|
* @param {MongoClient~connectCallback} [callback] The command result callback
|
|
378
421
|
* @return {Promise<MongoClient>} returns Promise if no callback passed
|
|
379
422
|
*/
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const OperationBase = require('./operation').OperationBase;
|
|
4
|
-
const defineAspects = require('./operation').defineAspects;
|
|
5
|
-
const Aspect = require('./operation').Aspect;
|
|
6
3
|
const deprecate = require('util').deprecate;
|
|
7
4
|
const Logger = require('../core').Logger;
|
|
8
5
|
const MongoCredentials = require('../core').MongoCredentials;
|
|
@@ -191,28 +188,6 @@ const LEGACY_OPTIONS_MAP = validOptionNames.reduce((obj, name) => {
|
|
|
191
188
|
return obj;
|
|
192
189
|
}, {});
|
|
193
190
|
|
|
194
|
-
class ConnectOperation extends OperationBase {
|
|
195
|
-
constructor(mongoClient) {
|
|
196
|
-
super();
|
|
197
|
-
|
|
198
|
-
this.mongoClient = mongoClient;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
execute(callback) {
|
|
202
|
-
const mongoClient = this.mongoClient;
|
|
203
|
-
const err = validOptions(mongoClient.s.options);
|
|
204
|
-
|
|
205
|
-
// Did we have a validation error
|
|
206
|
-
if (err) return callback(err);
|
|
207
|
-
// Fallback to callback based connect
|
|
208
|
-
connect(mongoClient, mongoClient.s.url, mongoClient.s.options, err => {
|
|
209
|
-
if (err) return callback(err);
|
|
210
|
-
callback(null, mongoClient);
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
defineAspects(ConnectOperation, [Aspect.SKIP_SESSION]);
|
|
215
|
-
|
|
216
191
|
function addListeners(mongoClient, topology) {
|
|
217
192
|
topology.on('authenticated', createListener(mongoClient, 'authenticated'));
|
|
218
193
|
topology.on('error', createListener(mongoClient, 'error'));
|
|
@@ -820,4 +795,4 @@ function translateOptions(options, translationOptions) {
|
|
|
820
795
|
});
|
|
821
796
|
}
|
|
822
797
|
|
|
823
|
-
module.exports =
|
|
798
|
+
module.exports = { validOptions, connect };
|
package/lib/operations/count.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const Aspect = require('./operation').Aspect;
|
|
4
3
|
const buildCountCommand = require('./common_functions').buildCountCommand;
|
|
5
|
-
const defineAspects = require('./operation').defineAspects;
|
|
6
4
|
const OperationBase = require('./operation').OperationBase;
|
|
7
5
|
|
|
8
6
|
class CountOperation extends OperationBase {
|
|
@@ -67,6 +65,4 @@ class CountOperation extends OperationBase {
|
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
|
|
70
|
-
defineAspects(CountOperation, Aspect.SKIP_SESSION);
|
|
71
|
-
|
|
72
68
|
module.exports = CountOperation;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const buildCountCommand = require('./collection_ops').buildCountCommand;
|
|
4
|
-
const formattedOrderClause = require('../utils').formattedOrderClause;
|
|
5
4
|
const handleCallback = require('../utils').handleCallback;
|
|
6
5
|
const MongoError = require('../core').MongoError;
|
|
7
6
|
const push = Array.prototype.push;
|
|
@@ -106,34 +105,6 @@ function each(cursor, callback) {
|
|
|
106
105
|
}
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
/**
|
|
110
|
-
* Check if there is any document still available in the cursor.
|
|
111
|
-
*
|
|
112
|
-
* @method
|
|
113
|
-
* @param {Cursor} cursor The Cursor instance on which to run.
|
|
114
|
-
* @param {Cursor~resultCallback} [callback] The result callback.
|
|
115
|
-
*/
|
|
116
|
-
function hasNext(cursor, callback) {
|
|
117
|
-
if (cursor.s.currentDoc) {
|
|
118
|
-
return callback(null, true);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (cursor.isNotified()) {
|
|
122
|
-
return callback(null, false);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
nextObject(cursor, (err, doc) => {
|
|
126
|
-
if (err) return callback(err, null);
|
|
127
|
-
if (cursor.s.state === CursorState.CLOSED || cursor.isDead()) {
|
|
128
|
-
return callback(null, false);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (!doc) return callback(null, false);
|
|
132
|
-
cursor.s.currentDoc = doc;
|
|
133
|
-
callback(null, true);
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
108
|
// Trampoline emptying the number of retrieved items
|
|
138
109
|
// without incurring a nextTick operation
|
|
139
110
|
function loop(cursor, callback) {
|
|
@@ -145,48 +116,6 @@ function loop(cursor, callback) {
|
|
|
145
116
|
return loop;
|
|
146
117
|
}
|
|
147
118
|
|
|
148
|
-
/**
|
|
149
|
-
* Get the next available document from the cursor. Returns null if no more documents are available.
|
|
150
|
-
*
|
|
151
|
-
* @method
|
|
152
|
-
* @param {Cursor} cursor The Cursor instance from which to get the next document.
|
|
153
|
-
* @param {Cursor~resultCallback} [callback] The result callback.
|
|
154
|
-
*/
|
|
155
|
-
function next(cursor, callback) {
|
|
156
|
-
// Return the currentDoc if someone called hasNext first
|
|
157
|
-
if (cursor.s.currentDoc) {
|
|
158
|
-
const doc = cursor.s.currentDoc;
|
|
159
|
-
cursor.s.currentDoc = null;
|
|
160
|
-
return callback(null, doc);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Return the next object
|
|
164
|
-
nextObject(cursor, callback);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Get the next available document from the cursor, returns null if no more documents are available.
|
|
168
|
-
function nextObject(cursor, callback) {
|
|
169
|
-
if (cursor.s.state === CursorState.CLOSED || (cursor.isDead && cursor.isDead()))
|
|
170
|
-
return handleCallback(
|
|
171
|
-
callback,
|
|
172
|
-
MongoError.create({ message: 'Cursor is closed', driver: true })
|
|
173
|
-
);
|
|
174
|
-
if (cursor.s.state === CursorState.INIT && cursor.cmd.sort) {
|
|
175
|
-
try {
|
|
176
|
-
cursor.cmd.sort = formattedOrderClause(cursor.cmd.sort);
|
|
177
|
-
} catch (err) {
|
|
178
|
-
return handleCallback(callback, err);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Get the next object
|
|
183
|
-
cursor._next((err, doc) => {
|
|
184
|
-
cursor.s.state = CursorState.OPEN;
|
|
185
|
-
if (err) return handleCallback(callback, err);
|
|
186
|
-
handleCallback(callback, null, doc);
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
119
|
/**
|
|
191
120
|
* Returns an array of documents. See Cursor.prototype.toArray for more information.
|
|
192
121
|
*
|
|
@@ -236,4 +165,4 @@ function toArray(cursor, callback) {
|
|
|
236
165
|
fetchDocs();
|
|
237
166
|
}
|
|
238
167
|
|
|
239
|
-
module.exports = { count, each,
|
|
168
|
+
module.exports = { count, each, toArray };
|