mongodb 2.2.23 → 2.2.27
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/.vscode/last.sql +0 -0
- package/HISTORY.md +58 -0
- package/README.md +1 -1
- package/conf.json +4 -1
- package/index.js +1 -0
- package/lib/admin.js +18 -15
- package/lib/aggregation_cursor.js +9 -0
- package/lib/apm.js +3 -1
- package/lib/authenticate.js +109 -0
- package/lib/bulk/unordered.js +3 -3
- package/lib/collection.js +23 -7
- package/lib/command_cursor.js +11 -2
- package/lib/cursor.js +22 -1
- package/lib/db.js +15 -107
- package/lib/mongo_client.js +67 -22
- package/lib/mongos.js +5 -3
- package/lib/replset.js +85 -58
- package/lib/server.js +5 -3
- package/lib/utils.js +66 -3
- package/package.json +4 -4
package/.vscode/last.sql
ADDED
|
File without changes
|
package/HISTORY.md
CHANGED
|
@@ -1,3 +1,61 @@
|
|
|
1
|
+
2.2.27 2017-05-22
|
|
2
|
+
-----------------
|
|
3
|
+
* Updated mongodb-core to 2.1.11
|
|
4
|
+
* NODE-987 Clear out old intervalIds on when calling topologyMonitor.
|
|
5
|
+
* NODE-987 Moved filtering to pingServer method and added test case.
|
|
6
|
+
* Check for connection destroyed just before writing out and flush out operations correctly if it is (Issue #179, https://github.com/jmholzinger).
|
|
7
|
+
* NODE-989 Refactored Replicaset monitoring to correcly monitor newly added servers, Also extracted setTimeout and setInterval to use custom wrappers Timeout and Interval.
|
|
8
|
+
* NODE-985 Deprecated Db.authenticate and Admin.authenticate and moved auth methods into authenticate.js to ensure MongoClient.connect does not print deprecation warnings.
|
|
9
|
+
* NODE-988 Merged readConcern and hint correctly on collection(...).find(...).count()
|
|
10
|
+
* Fix passing the readConcern option to MongoClient.connect (Issue #1514, https://github.com/bausmeier).
|
|
11
|
+
* NODE-996 Propegate all events up to a MongoClient instance.
|
|
12
|
+
* Allow saving doc with null `_id` (Issue #1517, https://github.com/vkarpov15).
|
|
13
|
+
* NODE-993 Expose hasNext for command cursor and add docs for both CommandCursor and Aggregation Cursor.
|
|
14
|
+
|
|
15
|
+
2.2.26 2017-04-18
|
|
16
|
+
-----------------
|
|
17
|
+
* Updated mongodb-core to 2.1.10
|
|
18
|
+
* NODE-981 delegate auth to replset/mongos if inTopology is set.
|
|
19
|
+
* NODE-978 Wrap connection.end in try/catch for node 0.10.x issue causing exceptions to be thrown, Also surfaced getConnection for mongos and replset.
|
|
20
|
+
* Remove dynamic require (Issue #175, https://github.com/tellnes).
|
|
21
|
+
* NODE-696 Handle interrupted error for createIndexes.
|
|
22
|
+
* Fixed isse when user is executing find command using Server.command and it get interpreted as a wire protcol message, #172.
|
|
23
|
+
* NODE-966 promoteValues not being promoted correctly to getMore.
|
|
24
|
+
* Merged in fix for flushing out monitoring operations.
|
|
25
|
+
* NODE-983 Add cursorId to aggregate and listCollections commands (Issue, #1510).
|
|
26
|
+
* Mark group and profilingInfo as deprecated methods
|
|
27
|
+
* NODE-956 DOCS Examples.
|
|
28
|
+
* Update readable-stream to version 2.2.7.
|
|
29
|
+
* NODE-978 Added test case to uncover connection.end issue for node 0.10.x.
|
|
30
|
+
* NODE-972 Fix(db): don't remove database name if collectionName == dbName (Issue, #1502)
|
|
31
|
+
* Fixed merging of writeConcerns on db.collection method.
|
|
32
|
+
* NODE-970 mix in readPreference for strict mode listCollections callback.
|
|
33
|
+
* NODE-966 added testcase for promoteValues being applied to getMore commands.
|
|
34
|
+
* NODE-962 Merge in ignoreUndefined from collection level for find/findOne.
|
|
35
|
+
* Remove multi option from updateMany tests/docs (Issue #1499, https://github.com/spratt).
|
|
36
|
+
* NODE-963 Correctly handle cursor.count when using APM.
|
|
37
|
+
|
|
38
|
+
2.2.25 2017-03-17
|
|
39
|
+
-----------------
|
|
40
|
+
* Don't rely on global toString() for checking if object (Issue #1494, https://github.com/vkarpov15).
|
|
41
|
+
* Remove obsolete option uri_decode_auth (Issue #1488, https://github.com/kamagatos).
|
|
42
|
+
* NODE-936 Correctly translate ReadPreference to CoreReadPreference for mongos queries.
|
|
43
|
+
* Exposed BSONRegExp type.
|
|
44
|
+
* NODE-950 push correct index for INSERT ops (https://github.com/mbroadst).
|
|
45
|
+
* NODE-951 Added support for sslCRL option and added a test case for it.
|
|
46
|
+
* NODE-953 Made batchSize issue general at cursor level.
|
|
47
|
+
* NODE-954 Remove write concern from reindex helper as it will not be supported in 3.6.
|
|
48
|
+
* Updated mongodb-core to 2.1.9.
|
|
49
|
+
* Return lastIsMaster correctly when connecting with secondaryOnlyConnectionAllowed is set to true and only a secondary is available in replica state.
|
|
50
|
+
* Clone options when passed to wireProtocol handler to avoid intermittent modifications causing errors.
|
|
51
|
+
* Ensure SSL error propegates better for Replset connections when there is a SSL validation error.
|
|
52
|
+
* NODE-957 Fixed issue where < batchSize not causing cursor to be closed on execution of first batch.
|
|
53
|
+
* NODE-958 Store reconnectConnection on pool object to allow destroy to close immediately.
|
|
54
|
+
|
|
55
|
+
2.2.24 2017-02-14
|
|
56
|
+
-----------------
|
|
57
|
+
* NODE-935, NODE-931 Make MongoClient strict options validation optional and instead print annoying console.warn entries.
|
|
58
|
+
|
|
1
59
|
2.2.23 2017-02-13
|
|
2
60
|
-----------------
|
|
3
61
|
* Updated mongodb-core to 2.1.8.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](http://travis-ci.org/mongodb/node-mongodb-native)
|
|
4
4
|
[](https://coveralls.io/github/mongodb/node-mongodb-native?branch=2.1)
|
|
5
|
-
[](https://gitter.im/mongodb/node-mongodb-native?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
|
6
6
|
|
|
7
7
|
# Description
|
|
8
8
|
|
package/conf.json
CHANGED
|
@@ -36,7 +36,10 @@
|
|
|
36
36
|
"node_modules/bson/lib/bson/symbol.js",
|
|
37
37
|
"node_modules/bson/lib/bson/timestamp.js",
|
|
38
38
|
"node_modules/bson/lib/bson/max_key.js",
|
|
39
|
-
"node_modules/bson/lib/bson/min_key.js"
|
|
39
|
+
"node_modules/bson/lib/bson/min_key.js",
|
|
40
|
+
"node_modules/bson/lib/bson/decimal128.js",
|
|
41
|
+
"node_modules/bson/lib/bson/int_32.js",
|
|
42
|
+
"node_modules/bson/lib/bson/regexp.js"
|
|
40
43
|
]
|
|
41
44
|
},
|
|
42
45
|
"templates": {
|
package/index.js
CHANGED
|
@@ -40,6 +40,7 @@ connect.ObjectID = core.BSON.ObjectID;
|
|
|
40
40
|
connect.ObjectId = core.BSON.ObjectID;
|
|
41
41
|
connect.Symbol = core.BSON.Symbol;
|
|
42
42
|
connect.Timestamp = core.BSON.Timestamp;
|
|
43
|
+
connect.BSONRegExp = core.BSON.BSONRegExp;
|
|
43
44
|
connect.Decimal128 = core.BSON.Decimal128;
|
|
44
45
|
|
|
45
46
|
// Add connect method
|
package/lib/admin.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var toError = require('./utils').toError,
|
|
4
4
|
Define = require('./metadata'),
|
|
5
|
-
shallowClone = require('./utils').shallowClone
|
|
5
|
+
shallowClone = require('./utils').shallowClone,
|
|
6
|
+
assign = require('./utils').assign,
|
|
7
|
+
authenticate = require('./authenticate');
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* @fileOverview The **Admin** class is an internal class that allows convenient access to
|
|
@@ -239,23 +241,23 @@ define.classMethod('ping', {callback: true, promise:true});
|
|
|
239
241
|
* @param {string} [password] The password.
|
|
240
242
|
* @param {Admin~resultCallback} [callback] The command result callback
|
|
241
243
|
* @return {Promise} returns Promise if no callback passed
|
|
244
|
+
* @deprecated This method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate using MongoClient.connect with auth credentials.
|
|
242
245
|
*/
|
|
243
246
|
Admin.prototype.authenticate = function(username, password, options, callback) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
console.warn("Admin.prototype.authenticate method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate using MongoClient.connect with auth credentials.");
|
|
248
|
+
var finalArguments = [this.s.db];
|
|
249
|
+
if(typeof username == 'string') finalArguments.push(username);
|
|
250
|
+
if(typeof password == 'string') finalArguments.push(password);
|
|
251
|
+
if(typeof options == 'function') {
|
|
252
|
+
finalArguments.push({ authdb: 'admin' });
|
|
253
|
+
finalArguments.push(options);
|
|
254
|
+
} else {
|
|
255
|
+
finalArguments.push(assign({}, options, { authdb: 'admin' }));
|
|
256
|
+
}
|
|
251
257
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if(err) return reject(err);
|
|
256
|
-
resolve(r);
|
|
257
|
-
});
|
|
258
|
-
});
|
|
258
|
+
if(typeof callback == 'function') finalArguments.push(callback);
|
|
259
|
+
// Excute authenticate method
|
|
260
|
+
return authenticate.apply(this.s.db, finalArguments);
|
|
259
261
|
}
|
|
260
262
|
|
|
261
263
|
define.classMethod('authenticate', {callback: true, promise:true});
|
|
@@ -437,6 +439,7 @@ define.classMethod('setProfilingLevel', {callback: true, promise:true});
|
|
|
437
439
|
*
|
|
438
440
|
* @param {Admin~resultCallback} [callback] The command result callback.
|
|
439
441
|
* @return {Promise} returns Promise if no callback passed
|
|
442
|
+
* @deprecated Query the system.profile collection directly.
|
|
440
443
|
*/
|
|
441
444
|
Admin.prototype.profilingInfo = function(callback) {
|
|
442
445
|
var self = this;
|
|
@@ -316,6 +316,7 @@ AggregationCursor.prototype.get = AggregationCursor.prototype.toArray;
|
|
|
316
316
|
define.classMethod('toArray', {callback: true, promise:true});
|
|
317
317
|
define.classMethod('each', {callback: true, promise:false});
|
|
318
318
|
define.classMethod('forEach', {callback: true, promise:false});
|
|
319
|
+
define.classMethod('hasNext', {callback: true, promise:true});
|
|
319
320
|
define.classMethod('next', {callback: true, promise:true});
|
|
320
321
|
define.classMethod('close', {callback: true, promise:true});
|
|
321
322
|
define.classMethod('isClosed', {callback: false, promise:false, returns: [Boolean]});
|
|
@@ -331,6 +332,14 @@ define.classMethod('readBufferedDocuments', {callback: false, promise:false, ret
|
|
|
331
332
|
* @return {Promise} returns Promise if no callback passed
|
|
332
333
|
*/
|
|
333
334
|
|
|
335
|
+
/**
|
|
336
|
+
* Check if there is any document still available in the cursor
|
|
337
|
+
* @function AggregationCursor.prototype.hasNext
|
|
338
|
+
* @param {AggregationCursor~resultCallback} [callback] The result callback.
|
|
339
|
+
* @throws {MongoError}
|
|
340
|
+
* @return {Promise} returns Promise if no callback passed
|
|
341
|
+
*/
|
|
342
|
+
|
|
334
343
|
/**
|
|
335
344
|
* The callback format for results
|
|
336
345
|
* @callback AggregationCursor~toArrayResultCallback
|
package/lib/apm.js
CHANGED
|
@@ -493,7 +493,9 @@ var Instrumentation = function(core, options, callback) {
|
|
|
493
493
|
nextBatch: cursor.cursorState.documents
|
|
494
494
|
}, ok:1
|
|
495
495
|
}
|
|
496
|
-
} else if(commandName.toLowerCase() == 'find'
|
|
496
|
+
} else if((commandName.toLowerCase() == 'find'
|
|
497
|
+
|| commandName.toLowerCase() == 'aggregate'
|
|
498
|
+
|| commandName.toLowerCase() == 'listcollections') && r == null) {
|
|
497
499
|
r = {
|
|
498
500
|
cursor: {
|
|
499
501
|
id: cursor.cursorState.cursorId,
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var shallowClone = require('./utils').shallowClone
|
|
2
|
+
, handleCallback = require('./utils').handleCallback
|
|
3
|
+
, MongoError = require('mongodb-core').MongoError;
|
|
4
|
+
|
|
5
|
+
var authenticate = function(self, username, password, options, callback) {
|
|
6
|
+
// Did the user destroy the topology
|
|
7
|
+
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
8
|
+
|
|
9
|
+
// the default db to authenticate against is 'self'
|
|
10
|
+
// if authententicate is called from a retry context, it may be another one, like admin
|
|
11
|
+
var authdb = options.dbName ? options.dbName : self.databaseName;
|
|
12
|
+
authdb = self.authSource ? self.authSource : authdb;
|
|
13
|
+
authdb = options.authdb ? options.authdb : authdb;
|
|
14
|
+
authdb = options.authSource ? options.authSource : authdb;
|
|
15
|
+
|
|
16
|
+
// Callback
|
|
17
|
+
var _callback = function(err, result) {
|
|
18
|
+
if(self.listeners('authenticated').length > 0) {
|
|
19
|
+
self.emit('authenticated', err, result);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Return to caller
|
|
23
|
+
handleCallback(callback, err, result);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// authMechanism
|
|
27
|
+
var authMechanism = options.authMechanism || '';
|
|
28
|
+
authMechanism = authMechanism.toUpperCase();
|
|
29
|
+
|
|
30
|
+
// If classic auth delegate to auth command
|
|
31
|
+
if(authMechanism == 'MONGODB-CR') {
|
|
32
|
+
self.s.topology.auth('mongocr', authdb, username, password, function(err) {
|
|
33
|
+
if(err) return handleCallback(callback, err, false);
|
|
34
|
+
_callback(null, true);
|
|
35
|
+
});
|
|
36
|
+
} else if(authMechanism == 'PLAIN') {
|
|
37
|
+
self.s.topology.auth('plain', authdb, username, password, function(err) {
|
|
38
|
+
if(err) return handleCallback(callback, err, false);
|
|
39
|
+
_callback(null, true);
|
|
40
|
+
});
|
|
41
|
+
} else if(authMechanism == 'MONGODB-X509') {
|
|
42
|
+
self.s.topology.auth('x509', authdb, username, password, function(err) {
|
|
43
|
+
if(err) return handleCallback(callback, err, false);
|
|
44
|
+
_callback(null, true);
|
|
45
|
+
});
|
|
46
|
+
} else if(authMechanism == 'SCRAM-SHA-1') {
|
|
47
|
+
self.s.topology.auth('scram-sha-1', authdb, username, password, function(err) {
|
|
48
|
+
if(err) return handleCallback(callback, err, false);
|
|
49
|
+
_callback(null, true);
|
|
50
|
+
});
|
|
51
|
+
} else if(authMechanism == 'GSSAPI') {
|
|
52
|
+
if(process.platform == 'win32') {
|
|
53
|
+
self.s.topology.auth('sspi', authdb, username, password, options, function(err) {
|
|
54
|
+
if(err) return handleCallback(callback, err, false);
|
|
55
|
+
_callback(null, true);
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
self.s.topology.auth('gssapi', authdb, username, password, options, function(err) {
|
|
59
|
+
if(err) return handleCallback(callback, err, false);
|
|
60
|
+
_callback(null, true);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
} else if(authMechanism == 'DEFAULT') {
|
|
64
|
+
self.s.topology.auth('default', authdb, username, password, function(err) {
|
|
65
|
+
if(err) return handleCallback(callback, err, false);
|
|
66
|
+
_callback(null, true);
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
handleCallback(callback, MongoError.create({message: f("authentication mechanism %s not supported", options.authMechanism), driver:true}));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = function(self, username, password, options, callback) {
|
|
74
|
+
if(typeof options == 'function') callback = options, options = {};
|
|
75
|
+
// Shallow copy the options
|
|
76
|
+
options = shallowClone(options);
|
|
77
|
+
|
|
78
|
+
// Set default mechanism
|
|
79
|
+
if(!options.authMechanism) {
|
|
80
|
+
options.authMechanism = 'DEFAULT';
|
|
81
|
+
} else if(options.authMechanism != 'GSSAPI'
|
|
82
|
+
&& options.authMechanism != 'DEFAULT'
|
|
83
|
+
&& options.authMechanism != 'MONGODB-CR'
|
|
84
|
+
&& options.authMechanism != 'MONGODB-X509'
|
|
85
|
+
&& options.authMechanism != 'SCRAM-SHA-1'
|
|
86
|
+
&& options.authMechanism != 'PLAIN') {
|
|
87
|
+
return handleCallback(callback, MongoError.create({message: "only DEFAULT, GSSAPI, PLAIN, MONGODB-X509, SCRAM-SHA-1 or MONGODB-CR is supported by authMechanism", driver:true}));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// If we have a callback fallback
|
|
91
|
+
if(typeof callback == 'function') return authenticate(self, username, password, options, function(err, r) {
|
|
92
|
+
// Support failed auth method
|
|
93
|
+
if(err && err.message && err.message.indexOf('saslStart') != -1) err.code = 59;
|
|
94
|
+
// Reject error
|
|
95
|
+
if(err) return callback(err, r);
|
|
96
|
+
callback(null, r);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Return a promise
|
|
100
|
+
return new self.s.promiseLibrary(function(resolve, reject) {
|
|
101
|
+
authenticate(self, username, password, options, function(err, r) {
|
|
102
|
+
// Support failed auth method
|
|
103
|
+
if(err && err.message && err.message.indexOf('saslStart') != -1) err.code = 59;
|
|
104
|
+
// Reject error
|
|
105
|
+
if(err) return reject(err);
|
|
106
|
+
resolve(r);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
};
|
package/lib/bulk/unordered.js
CHANGED
|
@@ -95,7 +95,7 @@ FindOperatorsUnordered.prototype.replaceOne = function(updateDocument) {
|
|
|
95
95
|
*
|
|
96
96
|
* @method
|
|
97
97
|
* @throws {MongoError}
|
|
98
|
-
* @return {
|
|
98
|
+
* @return {FindOperatorsUnordered}
|
|
99
99
|
*/
|
|
100
100
|
FindOperatorsUnordered.prototype.upsert = function() {
|
|
101
101
|
this.s.currentOp.upsert = true;
|
|
@@ -148,7 +148,7 @@ FindOperatorsUnordered.prototype.remove = function() {
|
|
|
148
148
|
var addToOperationsList = function(_self, docType, document) {
|
|
149
149
|
// Get the bsonSize
|
|
150
150
|
var bsonSize = bson.calculateObjectSize(document, {
|
|
151
|
-
checkKeys: false,
|
|
151
|
+
checkKeys: false,
|
|
152
152
|
});
|
|
153
153
|
// Throw error if the doc is bigger than the max BSON size
|
|
154
154
|
if(bsonSize >= _self.s.maxBatchSizeBytes) throw toError("document is larger than the maximum size " + _self.s.maxBatchSizeBytes);
|
|
@@ -189,7 +189,7 @@ var addToOperationsList = function(_self, docType, document) {
|
|
|
189
189
|
// Save back the current Batch to the right type
|
|
190
190
|
if(docType == common.INSERT) {
|
|
191
191
|
_self.s.currentInsertBatch = _self.s.currentBatch;
|
|
192
|
-
_self.s.bulkResult.insertedIds.push({index: _self.s.
|
|
192
|
+
_self.s.bulkResult.insertedIds.push({index: _self.s.bulkResult.insertedIds.length, _id: document._id});
|
|
193
193
|
} else if(docType == common.UPDATE) {
|
|
194
194
|
_self.s.currentUpdateBatch = _self.s.currentBatch;
|
|
195
195
|
} else if(docType == common.REMOVE) {
|
package/lib/collection.js
CHANGED
|
@@ -21,7 +21,8 @@ var checkCollectionName = require('./utils').checkCollectionName
|
|
|
21
21
|
, Cursor = require('./cursor')
|
|
22
22
|
, unordered = require('./bulk/unordered')
|
|
23
23
|
, ordered = require('./bulk/ordered')
|
|
24
|
-
, assign = require('./utils').assign
|
|
24
|
+
, assign = require('./utils').assign
|
|
25
|
+
, mergeOptions = require('./utils').mergeOptions;
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* @fileOverview The **Collection** class is an internal class that embodies a MongoDB collection
|
|
@@ -46,6 +47,8 @@ var checkCollectionName = require('./utils').checkCollectionName
|
|
|
46
47
|
* });
|
|
47
48
|
*/
|
|
48
49
|
|
|
50
|
+
var mergeKeys = ['readPreference', 'ignoreUndefined'];
|
|
51
|
+
|
|
49
52
|
/**
|
|
50
53
|
* Create a new Collection instance (INTERNAL TYPE, do not instantiate directly)
|
|
51
54
|
* @class
|
|
@@ -274,6 +277,14 @@ Collection.prototype.find = function() {
|
|
|
274
277
|
if (!options) options = {};
|
|
275
278
|
|
|
276
279
|
var newOptions = {};
|
|
280
|
+
|
|
281
|
+
// Make a shallow copy of the collection options
|
|
282
|
+
for(var key in this.s.options) {
|
|
283
|
+
if(mergeKeys.indexOf(key) != -1) {
|
|
284
|
+
newOptions[key] = this.s.options[key];
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
277
288
|
// Make a shallow copy of options
|
|
278
289
|
for (var key in options) {
|
|
279
290
|
newOptions[key] = options[key];
|
|
@@ -725,7 +736,7 @@ var insertDocuments = function(self, docs, options, callback) {
|
|
|
725
736
|
// Add _id if not specified
|
|
726
737
|
if(forceServerObjectId !== true){
|
|
727
738
|
for(var i = 0; i < docs.length; i++) {
|
|
728
|
-
if(docs[i]._id
|
|
739
|
+
if(docs[i]._id === void 0) docs[i]._id = self.s.pkFactory.createPk();
|
|
729
740
|
}
|
|
730
741
|
}
|
|
731
742
|
|
|
@@ -1787,9 +1798,6 @@ var reIndex = function(self, options, callback) {
|
|
|
1787
1798
|
// Reindex
|
|
1788
1799
|
var cmd = {'reIndex':self.s.name};
|
|
1789
1800
|
|
|
1790
|
-
// Decorate command with writeConcern if supported
|
|
1791
|
-
decorateWithWriteConcern(cmd, self, options);
|
|
1792
|
-
|
|
1793
1801
|
// Execute the command
|
|
1794
1802
|
self.s.db.command(cmd, options, function(err, result) {
|
|
1795
1803
|
if(callback == null) return;
|
|
@@ -2032,7 +2040,7 @@ var count = function(self, query, options, callback) {
|
|
|
2032
2040
|
if(typeof skip == 'number') cmd.skip = skip;
|
|
2033
2041
|
if(typeof limit == 'number') cmd.limit = limit;
|
|
2034
2042
|
if(typeof maxTimeMS == 'number') cmd.maxTimeMS = maxTimeMS;
|
|
2035
|
-
if(hint)
|
|
2043
|
+
if(hint) cmd.hint = hint;
|
|
2036
2044
|
|
|
2037
2045
|
options = shallowClone(options);
|
|
2038
2046
|
// Ensure we have the right read preference inheritance
|
|
@@ -2980,6 +2988,7 @@ var groupFunction = 'function () {\nvar c = db[ns].find(condition);\nvar map = n
|
|
|
2980
2988
|
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
|
2981
2989
|
* @param {Collection~resultCallback} [callback] The command result callback
|
|
2982
2990
|
* @return {Promise} returns Promise if no callback passed
|
|
2991
|
+
* @deprecated MongoDB 3.6 or higher will no longer support the group command. We recommend rewriting using the aggregation framework.
|
|
2983
2992
|
*/
|
|
2984
2993
|
Collection.prototype.group = function(keys, condition, initial, reduce, finalize, command, options, callback) {
|
|
2985
2994
|
var self = this;
|
|
@@ -3185,16 +3194,23 @@ var mapReduce = function(self, map, reduce, options, callback) {
|
|
|
3185
3194
|
, reduce: reduce
|
|
3186
3195
|
};
|
|
3187
3196
|
|
|
3197
|
+
// Exclusion list
|
|
3198
|
+
var exclusionList = ['readPreference'];
|
|
3199
|
+
|
|
3188
3200
|
// Add any other options passed in
|
|
3189
3201
|
for(var n in options) {
|
|
3190
3202
|
if('scope' == n) {
|
|
3191
3203
|
mapCommandHash[n] = processScope(options[n]);
|
|
3192
3204
|
} else {
|
|
3193
|
-
|
|
3205
|
+
// Only include if not in exclusion list
|
|
3206
|
+
if(exclusionList.indexOf(n) == -1) {
|
|
3207
|
+
mapCommandHash[n] = options[n];
|
|
3208
|
+
}
|
|
3194
3209
|
}
|
|
3195
3210
|
}
|
|
3196
3211
|
|
|
3197
3212
|
options = shallowClone(options);
|
|
3213
|
+
|
|
3198
3214
|
// Ensure we have the right read preference inheritance
|
|
3199
3215
|
options = getReadPreference(self, options, self.s.db, self);
|
|
3200
3216
|
|
package/lib/command_cursor.js
CHANGED
|
@@ -131,8 +131,8 @@ var CommandCursor = function(bson, ns, cmd, options, topology, topologyOptions)
|
|
|
131
131
|
inherits(CommandCursor, Readable);
|
|
132
132
|
|
|
133
133
|
// Set the methods to inherit from prototype
|
|
134
|
-
var methodsToInherit = ['_next', 'next', 'each', 'forEach', 'toArray'
|
|
135
|
-
, 'rewind', 'bufferedCount', 'readBufferedDocuments', 'close', 'isClosed', 'kill'
|
|
134
|
+
var methodsToInherit = ['_next', 'next', 'hasNext', 'each', 'forEach', 'toArray'
|
|
135
|
+
, 'rewind', 'bufferedCount', 'readBufferedDocuments', 'close', 'isClosed', 'kill', 'setCursorBatchSize'
|
|
136
136
|
, '_find', '_getmore', '_killcursor', 'isDead', 'explain', 'isNotified', 'isKilled'];
|
|
137
137
|
|
|
138
138
|
// Only inherit the types we need
|
|
@@ -207,6 +207,7 @@ define.classMethod('toArray', {callback: true, promise:true});
|
|
|
207
207
|
define.classMethod('each', {callback: true, promise:false});
|
|
208
208
|
define.classMethod('forEach', {callback: true, promise:false});
|
|
209
209
|
define.classMethod('next', {callback: true, promise:true});
|
|
210
|
+
define.classMethod('hasNext', {callback: true, promise:true});
|
|
210
211
|
define.classMethod('close', {callback: true, promise:true});
|
|
211
212
|
define.classMethod('isClosed', {callback: false, promise:false, returns: [Boolean]});
|
|
212
213
|
define.classMethod('rewind', {callback: false, promise:false});
|
|
@@ -221,6 +222,14 @@ define.classMethod('readBufferedDocuments', {callback: false, promise:false, ret
|
|
|
221
222
|
* @return {Promise} returns Promise if no callback passed
|
|
222
223
|
*/
|
|
223
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Check if there is any document still available in the cursor
|
|
227
|
+
* @function CommandCursor.prototype.hasNext
|
|
228
|
+
* @param {CommandCursor~resultCallback} [callback] The result callback.
|
|
229
|
+
* @throws {MongoError}
|
|
230
|
+
* @return {Promise} returns Promise if no callback passed
|
|
231
|
+
*/
|
|
232
|
+
|
|
224
233
|
/**
|
|
225
234
|
* The callback format for results
|
|
226
235
|
* @callback CommandCursor~toArrayResultCallback
|
package/lib/cursor.js
CHANGED
|
@@ -155,6 +155,14 @@ var Cursor = function(bson, ns, cmd, options, topology, topologyOptions) {
|
|
|
155
155
|
|
|
156
156
|
// Set the sort value
|
|
157
157
|
this.sortValue = self.s.cmd.sort;
|
|
158
|
+
|
|
159
|
+
// Get the batchSize
|
|
160
|
+
var batchSize = cmd.cursor && cmd.cursor.batchSize
|
|
161
|
+
? cmd.cursor && cmd.cursor.batchSize
|
|
162
|
+
: (options.cursor && options.cursor.batchSize ? options.cursor.batchSize : 1000);
|
|
163
|
+
|
|
164
|
+
// Set the batchSize
|
|
165
|
+
this.setCursorBatchSize(batchSize);
|
|
158
166
|
}
|
|
159
167
|
|
|
160
168
|
/**
|
|
@@ -933,6 +941,16 @@ var count = function(self, applySkipLimit, opts, callback) {
|
|
|
933
941
|
'count': self.s.ns.substr(delimiter+1), 'query': self.s.cmd.query
|
|
934
942
|
}
|
|
935
943
|
|
|
944
|
+
// Apply a readConcern if set
|
|
945
|
+
if(self.s.cmd.readConcern) {
|
|
946
|
+
command.readConcern = self.s.cmd.readConcern;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// Apply a hint if set
|
|
950
|
+
if(self.s.cmd.hint) {
|
|
951
|
+
command.hint = self.s.cmd.hint;
|
|
952
|
+
}
|
|
953
|
+
|
|
936
954
|
if(typeof opts.maxTimeMS == 'number') {
|
|
937
955
|
command.maxTimeMS = opts.maxTimeMS;
|
|
938
956
|
} else if(self.s.cmd && typeof self.s.cmd.maxTimeMS == 'number') {
|
|
@@ -944,11 +962,14 @@ var count = function(self, applySkipLimit, opts, callback) {
|
|
|
944
962
|
if(opts.limit) command.limit = opts.limit;
|
|
945
963
|
if(self.s.options.hint) command.hint = self.s.options.hint;
|
|
946
964
|
|
|
965
|
+
// Set cursor server to the same as the topology
|
|
966
|
+
self.server = self.topology;
|
|
967
|
+
|
|
947
968
|
// Execute the command
|
|
948
969
|
self.topology.command(f("%s.$cmd", self.s.ns.substr(0, delimiter))
|
|
949
970
|
, command, function(err, result) {
|
|
950
971
|
callback(err, result ? result.result.n : null)
|
|
951
|
-
});
|
|
972
|
+
}, self.options);
|
|
952
973
|
}
|
|
953
974
|
|
|
954
975
|
define.classMethod('count', {callback: true, promise:true});
|