mongodb 2.2.26 → 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 +14 -0
- package/README.md +1 -1
- package/lib/admin.js +17 -15
- package/lib/aggregation_cursor.js +9 -0
- package/lib/authenticate.js +109 -0
- package/lib/collection.js +2 -2
- package/lib/command_cursor.js +10 -1
- package/lib/cursor.js +10 -0
- package/lib/db.js +4 -104
- package/lib/mongo_client.js +57 -18
- package/lib/replset.js +80 -54
- package/package.json +2 -2
package/.vscode/last.sql
ADDED
|
File without changes
|
package/HISTORY.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
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
|
+
|
|
1
15
|
2.2.26 2017-04-18
|
|
2
16
|
-----------------
|
|
3
17
|
* Updated mongodb-core to 2.1.10
|
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/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});
|
|
@@ -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
|
|
@@ -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/collection.js
CHANGED
|
@@ -736,7 +736,7 @@ var insertDocuments = function(self, docs, options, callback) {
|
|
|
736
736
|
// Add _id if not specified
|
|
737
737
|
if(forceServerObjectId !== true){
|
|
738
738
|
for(var i = 0; i < docs.length; i++) {
|
|
739
|
-
if(docs[i]._id
|
|
739
|
+
if(docs[i]._id === void 0) docs[i]._id = self.s.pkFactory.createPk();
|
|
740
740
|
}
|
|
741
741
|
}
|
|
742
742
|
|
|
@@ -2040,7 +2040,7 @@ var count = function(self, query, options, callback) {
|
|
|
2040
2040
|
if(typeof skip == 'number') cmd.skip = skip;
|
|
2041
2041
|
if(typeof limit == 'number') cmd.limit = limit;
|
|
2042
2042
|
if(typeof maxTimeMS == 'number') cmd.maxTimeMS = maxTimeMS;
|
|
2043
|
-
if(hint)
|
|
2043
|
+
if(hint) cmd.hint = hint;
|
|
2044
2044
|
|
|
2045
2045
|
options = shallowClone(options);
|
|
2046
2046
|
// Ensure we have the right read preference inheritance
|
package/lib/command_cursor.js
CHANGED
|
@@ -131,7 +131,7 @@ 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'
|
|
134
|
+
var methodsToInherit = ['_next', 'next', 'hasNext', 'each', 'forEach', 'toArray'
|
|
135
135
|
, 'rewind', 'bufferedCount', 'readBufferedDocuments', 'close', 'isClosed', 'kill', 'setCursorBatchSize'
|
|
136
136
|
, '_find', '_getmore', '_killcursor', 'isDead', 'explain', 'isNotified', 'isKilled'];
|
|
137
137
|
|
|
@@ -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
|
@@ -941,6 +941,16 @@ var count = function(self, applySkipLimit, opts, callback) {
|
|
|
941
941
|
'count': self.s.ns.substr(delimiter+1), 'query': self.s.cmd.query
|
|
942
942
|
}
|
|
943
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
|
+
|
|
944
954
|
if(typeof opts.maxTimeMS == 'number') {
|
|
945
955
|
command.maxTimeMS = opts.maxTimeMS;
|
|
946
956
|
} else if(self.s.cmd && typeof self.s.cmd.maxTimeMS == 'number') {
|
package/lib/db.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var EventEmitter = require('events').EventEmitter
|
|
4
|
+
, authenticate = require('./authenticate')
|
|
4
5
|
, inherits = require('util').inherits
|
|
5
6
|
, getSingleProperty = require('./utils').getSingleProperty
|
|
6
7
|
, shallowClone = require('./utils').shallowClone
|
|
@@ -1469,74 +1470,6 @@ Db.prototype.removeUser = function(username, options, callback) {
|
|
|
1469
1470
|
});
|
|
1470
1471
|
};
|
|
1471
1472
|
|
|
1472
|
-
var authenticate = function(self, username, password, options, callback) {
|
|
1473
|
-
// Did the user destroy the topology
|
|
1474
|
-
if(self.serverConfig && self.serverConfig.isDestroyed()) return callback(new MongoError('topology was destroyed'));
|
|
1475
|
-
|
|
1476
|
-
// the default db to authenticate against is 'self'
|
|
1477
|
-
// if authententicate is called from a retry context, it may be another one, like admin
|
|
1478
|
-
var authdb = options.dbName ? options.dbName : self.databaseName;
|
|
1479
|
-
authdb = self.authSource ? self.authSource : authdb;
|
|
1480
|
-
authdb = options.authdb ? options.authdb : authdb;
|
|
1481
|
-
authdb = options.authSource ? options.authSource : authdb;
|
|
1482
|
-
|
|
1483
|
-
// Callback
|
|
1484
|
-
var _callback = function(err, result) {
|
|
1485
|
-
if(self.listeners('authenticated').length > 0) {
|
|
1486
|
-
self.emit('authenticated', err, result);
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
// Return to caller
|
|
1490
|
-
handleCallback(callback, err, result);
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
// authMechanism
|
|
1494
|
-
var authMechanism = options.authMechanism || '';
|
|
1495
|
-
authMechanism = authMechanism.toUpperCase();
|
|
1496
|
-
|
|
1497
|
-
// If classic auth delegate to auth command
|
|
1498
|
-
if(authMechanism == 'MONGODB-CR') {
|
|
1499
|
-
self.s.topology.auth('mongocr', authdb, username, password, function(err) {
|
|
1500
|
-
if(err) return handleCallback(callback, err, false);
|
|
1501
|
-
_callback(null, true);
|
|
1502
|
-
});
|
|
1503
|
-
} else if(authMechanism == 'PLAIN') {
|
|
1504
|
-
self.s.topology.auth('plain', authdb, username, password, function(err) {
|
|
1505
|
-
if(err) return handleCallback(callback, err, false);
|
|
1506
|
-
_callback(null, true);
|
|
1507
|
-
});
|
|
1508
|
-
} else if(authMechanism == 'MONGODB-X509') {
|
|
1509
|
-
self.s.topology.auth('x509', authdb, username, password, function(err) {
|
|
1510
|
-
if(err) return handleCallback(callback, err, false);
|
|
1511
|
-
_callback(null, true);
|
|
1512
|
-
});
|
|
1513
|
-
} else if(authMechanism == 'SCRAM-SHA-1') {
|
|
1514
|
-
self.s.topology.auth('scram-sha-1', authdb, username, password, function(err) {
|
|
1515
|
-
if(err) return handleCallback(callback, err, false);
|
|
1516
|
-
_callback(null, true);
|
|
1517
|
-
});
|
|
1518
|
-
} else if(authMechanism == 'GSSAPI') {
|
|
1519
|
-
if(process.platform == 'win32') {
|
|
1520
|
-
self.s.topology.auth('sspi', authdb, username, password, options, function(err) {
|
|
1521
|
-
if(err) return handleCallback(callback, err, false);
|
|
1522
|
-
_callback(null, true);
|
|
1523
|
-
});
|
|
1524
|
-
} else {
|
|
1525
|
-
self.s.topology.auth('gssapi', authdb, username, password, options, function(err) {
|
|
1526
|
-
if(err) return handleCallback(callback, err, false);
|
|
1527
|
-
_callback(null, true);
|
|
1528
|
-
});
|
|
1529
|
-
}
|
|
1530
|
-
} else if(authMechanism == 'DEFAULT') {
|
|
1531
|
-
self.s.topology.auth('default', authdb, username, password, function(err) {
|
|
1532
|
-
if(err) return handleCallback(callback, err, false);
|
|
1533
|
-
_callback(null, true);
|
|
1534
|
-
});
|
|
1535
|
-
} else {
|
|
1536
|
-
handleCallback(callback, MongoError.create({message: f("authentication mechanism %s not supported", options.authMechanism), driver:true}));
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
1473
|
/**
|
|
1541
1474
|
* Authenticate a user against the server.
|
|
1542
1475
|
* @method
|
|
@@ -1546,44 +1479,11 @@ var authenticate = function(self, username, password, options, callback) {
|
|
|
1546
1479
|
* @param {string} [options.authMechanism=MONGODB-CR] The authentication mechanism to use, GSSAPI, MONGODB-CR, MONGODB-X509, PLAIN
|
|
1547
1480
|
* @param {Db~resultCallback} [callback] The command result callback
|
|
1548
1481
|
* @return {Promise} returns Promise if no callback passed
|
|
1482
|
+
* @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.
|
|
1549
1483
|
*/
|
|
1550
1484
|
Db.prototype.authenticate = function(username, password, options, callback) {
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
// Shallow copy the options
|
|
1554
|
-
options = shallowClone(options);
|
|
1555
|
-
|
|
1556
|
-
// Set default mechanism
|
|
1557
|
-
if(!options.authMechanism) {
|
|
1558
|
-
options.authMechanism = 'DEFAULT';
|
|
1559
|
-
} else if(options.authMechanism != 'GSSAPI'
|
|
1560
|
-
&& options.authMechanism != 'DEFAULT'
|
|
1561
|
-
&& options.authMechanism != 'MONGODB-CR'
|
|
1562
|
-
&& options.authMechanism != 'MONGODB-X509'
|
|
1563
|
-
&& options.authMechanism != 'SCRAM-SHA-1'
|
|
1564
|
-
&& options.authMechanism != 'PLAIN') {
|
|
1565
|
-
return handleCallback(callback, MongoError.create({message: "only DEFAULT, GSSAPI, PLAIN, MONGODB-X509, SCRAM-SHA-1 or MONGODB-CR is supported by authMechanism", driver:true}));
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
// If we have a callback fallback
|
|
1569
|
-
if(typeof callback == 'function') return authenticate(self, username, password, options, function(err, r) {
|
|
1570
|
-
// Support failed auth method
|
|
1571
|
-
if(err && err.message && err.message.indexOf('saslStart') != -1) err.code = 59;
|
|
1572
|
-
// Reject error
|
|
1573
|
-
if(err) return callback(err, r);
|
|
1574
|
-
callback(null, r);
|
|
1575
|
-
});
|
|
1576
|
-
|
|
1577
|
-
// Return a promise
|
|
1578
|
-
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
1579
|
-
authenticate(self, username, password, options, function(err, r) {
|
|
1580
|
-
// Support failed auth method
|
|
1581
|
-
if(err && err.message && err.message.indexOf('saslStart') != -1) err.code = 59;
|
|
1582
|
-
// Reject error
|
|
1583
|
-
if(err) return reject(err);
|
|
1584
|
-
resolve(r);
|
|
1585
|
-
});
|
|
1586
|
-
});
|
|
1485
|
+
console.warn("Db.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.");
|
|
1486
|
+
return authenticate.apply(this, [this].concat(Array.prototype.slice.call(arguments)));
|
|
1587
1487
|
};
|
|
1588
1488
|
|
|
1589
1489
|
define.classMethod('authenticate', {callback: true, promise:true});
|
package/lib/mongo_client.js
CHANGED
|
@@ -4,13 +4,16 @@ var parse = require('./url_parser')
|
|
|
4
4
|
, Server = require('./server')
|
|
5
5
|
, Mongos = require('./mongos')
|
|
6
6
|
, ReplSet = require('./replset')
|
|
7
|
+
, EventEmitter = require('events').EventEmitter
|
|
8
|
+
, inherits = require('util').inherits
|
|
7
9
|
, Define = require('./metadata')
|
|
8
10
|
, ReadPreference = require('./read_preference')
|
|
9
11
|
, Logger = require('mongodb-core').Logger
|
|
10
12
|
, MongoError = require('mongodb-core').MongoError
|
|
11
13
|
, Db = require('./db')
|
|
12
14
|
, f = require('util').format
|
|
13
|
-
, shallowClone = require('./utils').shallowClone
|
|
15
|
+
, shallowClone = require('./utils').shallowClone
|
|
16
|
+
, authenticate = require('./authenticate');
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* @fileOverview The **MongoClient** class is a class that allows for making Connections to MongoDB.
|
|
@@ -65,6 +68,11 @@ function validOptions(options) {
|
|
|
65
68
|
* @return {MongoClient} a MongoClient instance.
|
|
66
69
|
*/
|
|
67
70
|
function MongoClient() {
|
|
71
|
+
if(!(this instanceof MongoClient)) return new MongoClient();
|
|
72
|
+
|
|
73
|
+
// Set up event emitter
|
|
74
|
+
EventEmitter.call(this);
|
|
75
|
+
|
|
68
76
|
/**
|
|
69
77
|
* The callback format for results
|
|
70
78
|
* @callback MongoClient~connectCallback
|
|
@@ -120,7 +128,7 @@ function MongoClient() {
|
|
|
120
128
|
* @param {object} [options.pkFactory=null] A primary key factory object for generation of custom _id keys.
|
|
121
129
|
* @param {object} [options.promiseLibrary=null] A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
|
|
122
130
|
* @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
|
|
123
|
-
* @param {
|
|
131
|
+
* @param {string} [options.readConcern.level='local'] Specify a read concern level for the collection operations, one of [local|majority]. (only MongoDB 3.2 or higher supported)
|
|
124
132
|
* @param {number} [options.maxStalenessSeconds=undefined] The max staleness to secondary reads (values under 10 seconds cannot be guaranteed);
|
|
125
133
|
* @param {string} [options.loggerLevel=undefined] The logging level (error/warn/info/debug)
|
|
126
134
|
* @param {object} [options.logger=undefined] Custom logger object
|
|
@@ -131,6 +139,11 @@ function MongoClient() {
|
|
|
131
139
|
this.connect = MongoClient.connect;
|
|
132
140
|
}
|
|
133
141
|
|
|
142
|
+
/**
|
|
143
|
+
* @ignore
|
|
144
|
+
*/
|
|
145
|
+
inherits(MongoClient, EventEmitter);
|
|
146
|
+
|
|
134
147
|
var define = MongoClient.define = new Define('MongoClient', MongoClient, false);
|
|
135
148
|
|
|
136
149
|
/**
|
|
@@ -182,7 +195,7 @@ var define = MongoClient.define = new Define('MongoClient', MongoClient, false);
|
|
|
182
195
|
* @param {object} [options.pkFactory=null] A primary key factory object for generation of custom _id keys.
|
|
183
196
|
* @param {object} [options.promiseLibrary=null] A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
|
|
184
197
|
* @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
|
|
185
|
-
* @param {
|
|
198
|
+
* @param {string} [options.readConcern.level='local'] Specify a read concern level for the collection operations, one of [local|majority]. (only MongoDB 3.2 or higher supported)
|
|
186
199
|
* @param {number} [options.maxStalenessSeconds=undefined] The max staleness to secondary reads (values under 10 seconds cannot be guaranteed);
|
|
187
200
|
* @param {string} [options.loggerLevel=undefined] The logging level (error/warn/info/debug)
|
|
188
201
|
* @param {object} [options.logger=undefined] Custom logger object
|
|
@@ -195,6 +208,7 @@ MongoClient.connect = function(url, options, callback) {
|
|
|
195
208
|
callback = typeof args[args.length - 1] == 'function' ? args.pop() : null;
|
|
196
209
|
options = args.length ? args.shift() : null;
|
|
197
210
|
options = options || {};
|
|
211
|
+
var self = this;
|
|
198
212
|
|
|
199
213
|
// Validate options object
|
|
200
214
|
var err = validOptions(options);
|
|
@@ -214,7 +228,7 @@ MongoClient.connect = function(url, options, callback) {
|
|
|
214
228
|
// Did we have a validation error
|
|
215
229
|
if(err) return reject(err);
|
|
216
230
|
// Attempt to connect
|
|
217
|
-
connect(url, options, function(err, db) {
|
|
231
|
+
connect(self, url, options, function(err, db) {
|
|
218
232
|
if(err) return reject(err);
|
|
219
233
|
resolve(db);
|
|
220
234
|
});
|
|
@@ -224,7 +238,7 @@ MongoClient.connect = function(url, options, callback) {
|
|
|
224
238
|
// Did we have a validation error
|
|
225
239
|
if(err) return callback(err);
|
|
226
240
|
// Fallback to callback based connect
|
|
227
|
-
connect(url, options, callback);
|
|
241
|
+
connect(self, url, options, callback);
|
|
228
242
|
}
|
|
229
243
|
|
|
230
244
|
define.staticMethod('connect', {callback: true, promise:true});
|
|
@@ -244,7 +258,7 @@ var mergeOptions = function(target, source, flatten) {
|
|
|
244
258
|
var createUnifiedOptions = function(finalOptions, options) {
|
|
245
259
|
var childOptions = ['mongos', 'server', 'db'
|
|
246
260
|
, 'replset', 'db_options', 'server_options', 'rs_options', 'mongos_options'];
|
|
247
|
-
var noMerge = [];
|
|
261
|
+
var noMerge = ['readconcern'];
|
|
248
262
|
|
|
249
263
|
for(var name in options) {
|
|
250
264
|
if(noMerge.indexOf(name.toLowerCase()) != -1) {
|
|
@@ -291,25 +305,50 @@ function translateOptions(options) {
|
|
|
291
305
|
});
|
|
292
306
|
}
|
|
293
307
|
|
|
294
|
-
function
|
|
308
|
+
function relayEvents(self, db) {
|
|
309
|
+
if(self instanceof MongoClient) {
|
|
310
|
+
var events = ["timeout", "close", 'serverOpening', 'serverDescriptionChanged', 'serverHeartbeatStarted',
|
|
311
|
+
'serverHeartbeatSucceeded', 'serverHeartbeatFailed', 'serverClosed', 'topologyOpening',
|
|
312
|
+
'topologyClosed', 'topologyDescriptionChanged', 'joined', 'left', 'ping', 'ha', 'all', 'fullsetup'];
|
|
313
|
+
events.forEach(function(event) {
|
|
314
|
+
db.serverConfig.on(event, function(object1, object2) {
|
|
315
|
+
self.emit(event, object1, object2);
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function createReplicaset(self, options, callback) {
|
|
295
322
|
// Set default options
|
|
296
323
|
var servers = translateOptions(options);
|
|
297
324
|
// Create Db instance
|
|
298
|
-
new Db(options.dbName, new ReplSet(servers, options), options)
|
|
325
|
+
var db = new Db(options.dbName, new ReplSet(servers, options), options);
|
|
326
|
+
// Propegate the events to the client
|
|
327
|
+
relayEvents(self, db);
|
|
328
|
+
// Open the connection
|
|
329
|
+
db.open(callback);
|
|
299
330
|
}
|
|
300
331
|
|
|
301
|
-
function createMongos(options, callback) {
|
|
332
|
+
function createMongos(self, options, callback) {
|
|
302
333
|
// Set default options
|
|
303
334
|
var servers = translateOptions(options);
|
|
304
335
|
// Create Db instance
|
|
305
|
-
new Db(options.dbName, new Mongos(servers, options), options)
|
|
336
|
+
var db = new Db(options.dbName, new Mongos(servers, options), options)
|
|
337
|
+
// Propegate the events to the client
|
|
338
|
+
relayEvents(self, db);
|
|
339
|
+
// Open the connection
|
|
340
|
+
db.open(callback);
|
|
306
341
|
}
|
|
307
342
|
|
|
308
|
-
function createServer(options, callback) {
|
|
343
|
+
function createServer(self, options, callback) {
|
|
309
344
|
// Set default options
|
|
310
345
|
var servers = translateOptions(options);
|
|
346
|
+
// Create db instance
|
|
347
|
+
var db = new Db(options.dbName, servers[0], options);
|
|
348
|
+
// Propegate the events to the client
|
|
349
|
+
relayEvents(self, db);
|
|
311
350
|
// Create Db instance
|
|
312
|
-
|
|
351
|
+
db.open(function(err, db) {
|
|
313
352
|
if(err) return callback(err);
|
|
314
353
|
// Check if we are really speaking to a mongos
|
|
315
354
|
var ismaster = db.serverConfig.lastIsMaster();
|
|
@@ -319,7 +358,7 @@ function createServer(options, callback) {
|
|
|
319
358
|
// Destroy the current connection
|
|
320
359
|
db.close();
|
|
321
360
|
// Create mongos connection instead
|
|
322
|
-
return createMongos(options, callback);
|
|
361
|
+
return createMongos(self, options, callback);
|
|
323
362
|
}
|
|
324
363
|
|
|
325
364
|
// Otherwise callback
|
|
@@ -359,7 +398,7 @@ function connectHandler(options, callback) {
|
|
|
359
398
|
}
|
|
360
399
|
|
|
361
400
|
// Authenticate
|
|
362
|
-
|
|
401
|
+
authenticate(authentication_db, options.user, options.password, options, function(err, success) {
|
|
363
402
|
if(success){
|
|
364
403
|
process.nextTick(function() {
|
|
365
404
|
try {
|
|
@@ -387,7 +426,7 @@ function connectHandler(options, callback) {
|
|
|
387
426
|
/*
|
|
388
427
|
* Connect using MongoClient
|
|
389
428
|
*/
|
|
390
|
-
var connect = function(url, options, callback) {
|
|
429
|
+
var connect = function(self, url, options, callback) {
|
|
391
430
|
options = options || {};
|
|
392
431
|
options = shallowClone(options);
|
|
393
432
|
|
|
@@ -430,11 +469,11 @@ var connect = function(url, options, callback) {
|
|
|
430
469
|
|
|
431
470
|
// Do we have a replicaset then skip discovery and go straight to connectivity
|
|
432
471
|
if(_finalOptions.replicaSet || _finalOptions.rs_name) {
|
|
433
|
-
return createReplicaset(_finalOptions, connectHandler(_finalOptions, connectCallback));
|
|
472
|
+
return createReplicaset(self, _finalOptions, connectHandler(_finalOptions, connectCallback));
|
|
434
473
|
} else if(object.servers.length > 1) {
|
|
435
|
-
return createMongos(_finalOptions, connectHandler(_finalOptions, connectCallback));
|
|
474
|
+
return createMongos(self, _finalOptions, connectHandler(_finalOptions, connectCallback));
|
|
436
475
|
} else {
|
|
437
|
-
return createServer(_finalOptions, connectHandler(_finalOptions, connectCallback));
|
|
476
|
+
return createServer(self, _finalOptions, connectHandler(_finalOptions, connectCallback));
|
|
438
477
|
}
|
|
439
478
|
}
|
|
440
479
|
|
package/lib/replset.js
CHANGED
|
@@ -270,69 +270,95 @@ ReplSet.prototype.connect = function(db, _options, callback) {
|
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
-
//
|
|
274
|
-
var
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
// Set up listeners
|
|
283
|
-
self.s.replset.once('timeout', errorHandler('timeout'));
|
|
284
|
-
self.s.replset.once('error', errorHandler('error'));
|
|
285
|
-
self.s.replset.once('close', errorHandler('close'));
|
|
273
|
+
// Clear out all the current handlers left over
|
|
274
|
+
var events = ["timeout", "error", "close", 'serverOpening', 'serverDescriptionChanged', 'serverHeartbeatStarted',
|
|
275
|
+
'serverHeartbeatSucceeded', 'serverHeartbeatFailed', 'serverClosed', 'topologyOpening',
|
|
276
|
+
'topologyClosed', 'topologyDescriptionChanged', 'joined', 'left', 'ping', 'ha'];
|
|
277
|
+
events.forEach(function(e) {
|
|
278
|
+
self.s.replset.removeAllListeners(e);
|
|
279
|
+
});
|
|
286
280
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
281
|
+
// relay the event
|
|
282
|
+
var relay = function(event) {
|
|
283
|
+
return function(t, server) {
|
|
284
|
+
self.emit(event, t, server);
|
|
292
285
|
}
|
|
286
|
+
}
|
|
293
287
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
288
|
+
// Replset events relay
|
|
289
|
+
var replsetRelay = function(event) {
|
|
290
|
+
return function(t, server) {
|
|
291
|
+
self.emit(event, t, server.lastIsMaster(), server);
|
|
299
292
|
}
|
|
293
|
+
}
|
|
300
294
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
295
|
+
// Relay ha
|
|
296
|
+
var relayHa = function(t, state) {
|
|
297
|
+
self.emit('ha', t, state);
|
|
304
298
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
299
|
+
if(t == 'start') {
|
|
300
|
+
self.emit('ha_connect', t, state);
|
|
301
|
+
} else if(t == 'end') {
|
|
302
|
+
self.emit('ha_ismaster', t, state);
|
|
310
303
|
}
|
|
304
|
+
}
|
|
311
305
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
306
|
+
// Set up serverConfig listeners
|
|
307
|
+
self.s.replset.on('joined', replsetRelay('joined'));
|
|
308
|
+
self.s.replset.on('left', relay('left'));
|
|
309
|
+
self.s.replset.on('ping', relay('ping'));
|
|
310
|
+
self.s.replset.on('ha', relayHa);
|
|
311
|
+
|
|
312
|
+
// Set up SDAM listeners
|
|
313
|
+
self.s.replset.on('serverDescriptionChanged', relay('serverDescriptionChanged'));
|
|
314
|
+
self.s.replset.on('serverHeartbeatStarted', relay('serverHeartbeatStarted'));
|
|
315
|
+
self.s.replset.on('serverHeartbeatSucceeded', relay('serverHeartbeatSucceeded'));
|
|
316
|
+
self.s.replset.on('serverHeartbeatFailed', relay('serverHeartbeatFailed'));
|
|
317
|
+
self.s.replset.on('serverOpening', relay('serverOpening'));
|
|
318
|
+
self.s.replset.on('serverClosed', relay('serverClosed'));
|
|
319
|
+
self.s.replset.on('topologyOpening', relay('topologyOpening'));
|
|
320
|
+
self.s.replset.on('topologyClosed', relay('topologyClosed'));
|
|
321
|
+
self.s.replset.on('topologyDescriptionChanged', relay('topologyDescriptionChanged'));
|
|
322
|
+
|
|
323
|
+
self.s.replset.on('fullsetup', function() {
|
|
324
|
+
self.emit('fullsetup', null, self);
|
|
325
|
+
});
|
|
332
326
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
327
|
+
self.s.replset.on('all', function() {
|
|
328
|
+
self.emit('all', null, self);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Connect handler
|
|
332
|
+
var connectHandler = function() {
|
|
333
|
+
// Set up listeners
|
|
334
|
+
self.s.replset.once('timeout', errorHandler('timeout'));
|
|
335
|
+
self.s.replset.once('error', errorHandler('error'));
|
|
336
|
+
self.s.replset.once('close', errorHandler('close'));
|
|
337
|
+
|
|
338
|
+
// // Set up serverConfig listeners
|
|
339
|
+
// self.s.replset.on('joined', replsetRelay('joined'));
|
|
340
|
+
// self.s.replset.on('left', relay('left'));
|
|
341
|
+
// self.s.replset.on('ping', relay('ping'));
|
|
342
|
+
// self.s.replset.on('ha', relayHa);
|
|
343
|
+
|
|
344
|
+
// // Set up SDAM listeners
|
|
345
|
+
// self.s.replset.on('serverDescriptionChanged', relay('serverDescriptionChanged'));
|
|
346
|
+
// self.s.replset.on('serverHeartbeatStarted', relay('serverHeartbeatStarted'));
|
|
347
|
+
// self.s.replset.on('serverHeartbeatSucceeded', relay('serverHeartbeatSucceeded'));
|
|
348
|
+
// self.s.replset.on('serverHeartbeatFailed', relay('serverHeartbeatFailed'));
|
|
349
|
+
// self.s.replset.on('serverOpening', relay('serverOpening'));
|
|
350
|
+
// self.s.replset.on('serverClosed', relay('serverClosed'));
|
|
351
|
+
// self.s.replset.on('topologyOpening', relay('topologyOpening'));
|
|
352
|
+
// self.s.replset.on('topologyClosed', relay('topologyClosed'));
|
|
353
|
+
// self.s.replset.on('topologyDescriptionChanged', relay('topologyDescriptionChanged'));
|
|
354
|
+
|
|
355
|
+
// self.s.replset.on('fullsetup', function() {
|
|
356
|
+
// self.emit('fullsetup', null, self);
|
|
357
|
+
// });
|
|
358
|
+
|
|
359
|
+
// self.s.replset.on('all', function() {
|
|
360
|
+
// self.emit('all', null, self);
|
|
361
|
+
// });
|
|
336
362
|
|
|
337
363
|
// Emit open event
|
|
338
364
|
self.emit('open', null, self);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongodb",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.27",
|
|
4
4
|
"description": "The official MongoDB driver for Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"es6-promise": "3.2.1",
|
|
17
|
-
"mongodb-core": "2.1.
|
|
17
|
+
"mongodb-core": "2.1.11",
|
|
18
18
|
"readable-stream": "2.2.7"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|