mongodb 2.2.27 → 2.2.31
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 +40 -0
- package/lib/bulk/ordered.js +17 -10
- package/lib/bulk/unordered.js +17 -10
- package/lib/collection.js +1 -1
- package/lib/cursor.js +6 -1
- package/lib/db.js +2 -1
- package/lib/gridfs/grid_store.js +6 -3
- package/lib/gridfs-stream/download.js +17 -7
- package/lib/gridfs-stream/upload.js +7 -0
- package/lib/mongo_client.js +60 -12
- package/lib/mongos.js +22 -15
- package/lib/replset.js +3 -28
- package/lib/server.js +29 -24
- package/lib/url_parser.js +9 -2
- package/lib/utils.js +8 -8
- package/package.json +3 -3
- package/yarn.lock +617 -670
- package/.vscode/last.sql +0 -0
package/HISTORY.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
2.2.31 2017-08-08
|
|
2
|
+
-----------------
|
|
3
|
+
* update mongodb-core to 2.2.15
|
|
4
|
+
* allow auth option in MongoClient.connect
|
|
5
|
+
* remove duplicate option `promoteLongs` from MongoClient's `connect`
|
|
6
|
+
* bulk operations should not throw an error on empty batch
|
|
7
|
+
|
|
8
|
+
2.2.30 2017-07-07
|
|
9
|
+
-----------------
|
|
10
|
+
* Update mongodb-core to 2.2.14
|
|
11
|
+
* MongoClient
|
|
12
|
+
* add `appname` to list of valid option names
|
|
13
|
+
* added test for passing appname as option
|
|
14
|
+
* NODE-1052 ensure user options are applied while parsing connection string uris
|
|
15
|
+
|
|
16
|
+
2.2.29 2017-06-19
|
|
17
|
+
-----------------
|
|
18
|
+
* Update mongodb-core to 2.1.13
|
|
19
|
+
* NODE-1039 ensure we force destroy server instances, forcing queue to be flushed.
|
|
20
|
+
* Use actual server type in standalone SDAM events.
|
|
21
|
+
* Allow multiple map calls (Issue #1521, https://github.com/Robbilie).
|
|
22
|
+
* Clone insertMany options before mutating (Issue #1522, https://github.com/vkarpov15).
|
|
23
|
+
* NODE-1034 Fix GridStore issue caused by Node 8.0.0 breaking backward compatible fs.read API.
|
|
24
|
+
* NODE-1026, use operator instead of skip function in order to avoid useless fetch stage.
|
|
25
|
+
|
|
26
|
+
2.2.28 2017-06-02
|
|
27
|
+
-----------------
|
|
28
|
+
* Update mongodb-core to 2.1.12
|
|
29
|
+
* NODE-1019 Set keepAlive to 300 seconds or 1/2 of socketTimeout if socketTimeout < keepAlive.
|
|
30
|
+
* Minor fix to report the correct state on error.
|
|
31
|
+
* NODE-1020 'family' was added to options to provide high priority for ipv6 addresses (Issue #1518, https://github.com/firej).
|
|
32
|
+
* Fix require_optional loading of bson-ext.
|
|
33
|
+
* Ensure no errors are thrown by replset if topology is destroyed before it finished connecting.
|
|
34
|
+
* NODE-999 SDAM fixes for Mongos and single Server event emitting.
|
|
35
|
+
* NODE-1014 Set socketTimeout to default to 360 seconds.
|
|
36
|
+
* NODE-1019 Set keepAlive to 300 seconds or 1/2 of socketTimeout if socketTimeout < keepAlive.
|
|
37
|
+
* Just handle Collection name errors distinctly from general callback errors avoiding double callbacks in Db.collection.
|
|
38
|
+
* NODE-999 SDAM fixes for Mongos and single Server event emitting.
|
|
39
|
+
* NODE-1000 Added guard condition for upload.js checkDone function in case of race condition caused by late arriving chunk write.
|
|
40
|
+
|
|
1
41
|
2.2.27 2017-05-22
|
|
2
42
|
-----------------
|
|
3
43
|
* Updated mongodb-core to 2.1.11
|
package/lib/bulk/ordered.js
CHANGED
|
@@ -488,30 +488,37 @@ var executeCommands = function(self, callback) {
|
|
|
488
488
|
*/
|
|
489
489
|
OrderedBulkOperation.prototype.execute = function(_writeConcern, callback) {
|
|
490
490
|
var self = this;
|
|
491
|
-
if(this.s.executed)
|
|
492
|
-
|
|
491
|
+
if (this.s.executed) {
|
|
492
|
+
var executedError = toError('batch cannot be re-executed');
|
|
493
|
+
return (typeof callback === 'function') ?
|
|
494
|
+
callback(executedError, null) : this.s.promiseLibrary.reject(executedError);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (typeof _writeConcern === 'function') {
|
|
493
498
|
callback = _writeConcern;
|
|
494
|
-
|
|
499
|
+
} else if (_writeConcern && typeof _writeConcern === 'object') {
|
|
495
500
|
this.s.writeConcern = _writeConcern;
|
|
496
501
|
}
|
|
497
502
|
|
|
498
503
|
// If we have current batch
|
|
499
|
-
if(this.s.currentBatch) this.s.batches.push(this.s.currentBatch)
|
|
504
|
+
if (this.s.currentBatch) this.s.batches.push(this.s.currentBatch)
|
|
500
505
|
|
|
501
506
|
// If we have no operations in the bulk raise an error
|
|
502
|
-
if(this.s.batches.length == 0) {
|
|
503
|
-
|
|
507
|
+
if (this.s.batches.length == 0) {
|
|
508
|
+
var emptyBatchError = toError('Invalid Operation, no operations specified');
|
|
509
|
+
return (typeof callback === 'function') ?
|
|
510
|
+
callback(emptyBatchError, null) : this.s.promiseLibrary.reject(emptyBatchError);
|
|
504
511
|
}
|
|
505
512
|
|
|
506
513
|
// Execute using callback
|
|
507
|
-
if(typeof callback
|
|
508
|
-
|
|
509
|
-
|
|
514
|
+
if (typeof callback === 'function') {
|
|
515
|
+
return executeCommands(this, callback);
|
|
516
|
+
}
|
|
510
517
|
|
|
511
518
|
// Return a Promise
|
|
512
519
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
513
520
|
executeCommands(self, function(err, r) {
|
|
514
|
-
if(err) return reject(err);
|
|
521
|
+
if (err) return reject(err);
|
|
515
522
|
resolve(r);
|
|
516
523
|
});
|
|
517
524
|
});
|
package/lib/bulk/unordered.js
CHANGED
|
@@ -490,30 +490,37 @@ var executeBatches = function(self, callback) {
|
|
|
490
490
|
*/
|
|
491
491
|
UnorderedBulkOperation.prototype.execute = function(_writeConcern, callback) {
|
|
492
492
|
var self = this;
|
|
493
|
-
if(this.s.executed)
|
|
494
|
-
|
|
493
|
+
if (this.s.executed) {
|
|
494
|
+
var executedError = toError('batch cannot be re-executed');
|
|
495
|
+
return (typeof callback === 'function') ?
|
|
496
|
+
callback(executedError, null) : this.s.promiseLibrary.reject(executedError);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
if (typeof _writeConcern === 'function') {
|
|
495
500
|
callback = _writeConcern;
|
|
496
|
-
} else if(_writeConcern && typeof _writeConcern
|
|
501
|
+
} else if (_writeConcern && typeof _writeConcern === 'object') {
|
|
497
502
|
this.s.writeConcern = _writeConcern;
|
|
498
503
|
}
|
|
499
504
|
|
|
500
505
|
// If we have current batch
|
|
501
|
-
if(this.s.currentInsertBatch) this.s.batches.push(this.s.currentInsertBatch);
|
|
502
|
-
if(this.s.currentUpdateBatch) this.s.batches.push(this.s.currentUpdateBatch);
|
|
503
|
-
if(this.s.currentRemoveBatch) this.s.batches.push(this.s.currentRemoveBatch);
|
|
506
|
+
if (this.s.currentInsertBatch) this.s.batches.push(this.s.currentInsertBatch);
|
|
507
|
+
if (this.s.currentUpdateBatch) this.s.batches.push(this.s.currentUpdateBatch);
|
|
508
|
+
if (this.s.currentRemoveBatch) this.s.batches.push(this.s.currentRemoveBatch);
|
|
504
509
|
|
|
505
510
|
// If we have no operations in the bulk raise an error
|
|
506
|
-
if(this.s.batches.length == 0) {
|
|
507
|
-
|
|
511
|
+
if (this.s.batches.length == 0) {
|
|
512
|
+
var emptyBatchError = toError('Invalid Operation, no operations specified');
|
|
513
|
+
return (typeof callback === 'function') ?
|
|
514
|
+
callback(emptyBatchError, null) : this.s.promiseLibrary.reject(emptyBatchError);
|
|
508
515
|
}
|
|
509
516
|
|
|
510
517
|
// Execute using callback
|
|
511
|
-
if(typeof callback
|
|
518
|
+
if (typeof callback === 'function') return executeBatches(this, callback);
|
|
512
519
|
|
|
513
520
|
// Return a Promise
|
|
514
521
|
return new this.s.promiseLibrary(function(resolve, reject) {
|
|
515
522
|
executeBatches(self, function(err, r) {
|
|
516
|
-
if(err) return reject(err);
|
|
523
|
+
if (err) return reject(err);
|
|
517
524
|
resolve(r);
|
|
518
525
|
});
|
|
519
526
|
});
|
package/lib/collection.js
CHANGED
|
@@ -496,7 +496,7 @@ define.classMethod('insertOne', {callback: true, promise:true});
|
|
|
496
496
|
Collection.prototype.insertMany = function(docs, options, callback) {
|
|
497
497
|
var self = this;
|
|
498
498
|
if(typeof options == 'function') callback = options, options = {};
|
|
499
|
-
options = options
|
|
499
|
+
options = options ? shallowClone(options) : {ordered:true};
|
|
500
500
|
if(!Array.isArray(docs) && typeof callback == 'function') {
|
|
501
501
|
return callback(MongoError.create({message: 'docs parameter must be an array of documents', driver:true }));
|
|
502
502
|
} else if(!Array.isArray(docs)) {
|
package/lib/cursor.js
CHANGED
|
@@ -1003,7 +1003,12 @@ define.classMethod('close', {callback: true, promise:true});
|
|
|
1003
1003
|
* @return {Cursor}
|
|
1004
1004
|
*/
|
|
1005
1005
|
Cursor.prototype.map = function(transform) {
|
|
1006
|
-
this.cursorState.transforms
|
|
1006
|
+
if(this.cursorState.transforms && this.cursorState.transforms.doc) {
|
|
1007
|
+
var oldTransform = this.cursorState.transforms.doc;
|
|
1008
|
+
this.cursorState.transforms.doc = function (doc) { return transform(oldTransform(doc)); };
|
|
1009
|
+
} else {
|
|
1010
|
+
this.cursorState.transforms = { doc: transform };
|
|
1011
|
+
}
|
|
1007
1012
|
return this;
|
|
1008
1013
|
}
|
|
1009
1014
|
|
package/lib/db.js
CHANGED
|
@@ -462,6 +462,7 @@ Db.prototype.collection = function(name, options, callback) {
|
|
|
462
462
|
if(callback) callback(null, collection);
|
|
463
463
|
return collection;
|
|
464
464
|
} catch(err) {
|
|
465
|
+
// if(err instanceof MongoError && callback) return callback(err);
|
|
465
466
|
if(callback) return callback(err);
|
|
466
467
|
throw err;
|
|
467
468
|
}
|
|
@@ -1482,7 +1483,7 @@ Db.prototype.removeUser = function(username, options, callback) {
|
|
|
1482
1483
|
* @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.
|
|
1483
1484
|
*/
|
|
1484
1485
|
Db.prototype.authenticate = function(username, password, options, callback) {
|
|
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
|
+
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
1487
|
return authenticate.apply(this, [this].concat(Array.prototype.slice.call(arguments)));
|
|
1487
1488
|
};
|
|
1488
1489
|
|
package/lib/gridfs/grid_store.js
CHANGED
|
@@ -427,20 +427,23 @@ var writeFile = function(self, file, callback) {
|
|
|
427
427
|
|
|
428
428
|
// Write a chunk
|
|
429
429
|
var writeChunk = function() {
|
|
430
|
-
|
|
430
|
+
// Allocate the buffer
|
|
431
|
+
var _buffer = new Buffer(self.chunkSize);
|
|
432
|
+
// Read the file
|
|
433
|
+
fs.read(file, _buffer, 0, _buffer.length, offset, function(err, bytesRead, data) {
|
|
431
434
|
if(err) return callback(err, self);
|
|
432
435
|
|
|
433
436
|
offset = offset + bytesRead;
|
|
434
437
|
|
|
435
438
|
// Create a new chunk for the data
|
|
436
439
|
var chunk = new Chunk(self, {n:index++}, self.writeConcern);
|
|
437
|
-
chunk.write(data, function(err, chunk) {
|
|
440
|
+
chunk.write(data.slice(0, bytesRead), function(err, chunk) {
|
|
438
441
|
if(err) return callback(err, self);
|
|
439
442
|
|
|
440
443
|
chunk.save({}, function(err) {
|
|
441
444
|
if(err) return callback(err, self);
|
|
442
445
|
|
|
443
|
-
self.position = self.position +
|
|
446
|
+
self.position = self.position + bytesRead;
|
|
444
447
|
|
|
445
448
|
// Point to current chunk
|
|
446
449
|
self.currentChunk = chunk;
|
|
@@ -298,15 +298,27 @@ function init(self) {
|
|
|
298
298
|
return;
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
self.s.
|
|
301
|
+
self.s.bytesToSkip = handleStartOption(self, doc, self.s.options);
|
|
302
|
+
|
|
303
|
+
var filter = { files_id: doc._id };
|
|
304
|
+
|
|
305
|
+
// Currently (MongoDB 3.4.4) skip function does not support the index,
|
|
306
|
+
// it needs to retrieve all the documents first and then skip them. (CS-25811)
|
|
307
|
+
// As work around we use $gte on the "n" field.
|
|
308
|
+
if (self.s.options && self.s.options.start != null){
|
|
309
|
+
var skip = Math.floor(self.s.options.start / doc.chunkSize);
|
|
310
|
+
if (skip > 0){
|
|
311
|
+
filter["n"] = {"$gte": skip};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
self.s.cursor = self.s.chunks.find(filter).sort({ n: 1 });
|
|
315
|
+
|
|
302
316
|
if (self.s.readPreference) {
|
|
303
317
|
self.s.cursor.setReadPreference(self.s.readPreference);
|
|
304
318
|
}
|
|
305
319
|
|
|
306
320
|
self.s.expectedEnd = Math.ceil(doc.length / doc.chunkSize);
|
|
307
321
|
self.s.file = doc;
|
|
308
|
-
self.s.bytesToSkip = handleStartOption(self, doc, self.s.cursor,
|
|
309
|
-
self.s.options);
|
|
310
322
|
self.s.bytesToTrim = handleEndOption(self, doc, self.s.cursor,
|
|
311
323
|
self.s.options);
|
|
312
324
|
self.emit('file', doc);
|
|
@@ -336,11 +348,11 @@ function waitForFile(_this, callback) {
|
|
|
336
348
|
* @ignore
|
|
337
349
|
*/
|
|
338
350
|
|
|
339
|
-
function handleStartOption(stream, doc,
|
|
351
|
+
function handleStartOption(stream, doc, options) {
|
|
340
352
|
if (options && options.start != null) {
|
|
341
353
|
if (options.start > doc.length) {
|
|
342
354
|
throw new Error('Stream start (' + options.start + ') must not be ' +
|
|
343
|
-
'more than the length of the file (' + doc.length +')')
|
|
355
|
+
'more than the length of the file (' + doc.length +')');
|
|
344
356
|
}
|
|
345
357
|
if (options.start < 0) {
|
|
346
358
|
throw new Error('Stream start (' + options.start + ') must not be ' +
|
|
@@ -351,8 +363,6 @@ function handleStartOption(stream, doc, cursor, options) {
|
|
|
351
363
|
'greater than stream end (' + options.end + ')');
|
|
352
364
|
}
|
|
353
365
|
|
|
354
|
-
cursor.skip(Math.floor(options.start / doc.chunkSize));
|
|
355
|
-
|
|
356
366
|
stream.s.bytesRead = Math.floor(options.start / doc.chunkSize) *
|
|
357
367
|
doc.chunkSize;
|
|
358
368
|
stream.s.expected = Math.floor(options.start / doc.chunkSize);
|
|
@@ -33,6 +33,8 @@ function GridFSBucketWriteStream(bucket, filename, options) {
|
|
|
33
33
|
this.filename = filename;
|
|
34
34
|
this.files = bucket.s._filesCollection;
|
|
35
35
|
this.options = options;
|
|
36
|
+
// Signals the write is all done
|
|
37
|
+
this.done = false;
|
|
36
38
|
|
|
37
39
|
this.id = options.id ? options.id : core.BSON.ObjectId();
|
|
38
40
|
this.chunkSizeBytes = this.options.chunkSizeBytes;
|
|
@@ -252,9 +254,13 @@ function checkChunksIndex(_this, callback) {
|
|
|
252
254
|
*/
|
|
253
255
|
|
|
254
256
|
function checkDone(_this, callback) {
|
|
257
|
+
if(_this.done) return true;
|
|
255
258
|
if (_this.state.streamEnd &&
|
|
256
259
|
_this.state.outstandingRequests === 0 &&
|
|
257
260
|
!_this.state.errored) {
|
|
261
|
+
// Set done so we dont' trigger duplicate createFilesDoc
|
|
262
|
+
_this.done = true;
|
|
263
|
+
// Create a new files doc
|
|
258
264
|
var filesDoc = createFilesDoc(_this.id, _this.length, _this.chunkSizeBytes,
|
|
259
265
|
_this.md5.digest('hex'), _this.filename, _this.options.contentType,
|
|
260
266
|
_this.options.aliases, _this.options.metadata);
|
|
@@ -421,6 +427,7 @@ function doWrite(_this, chunk, encoding, callback) {
|
|
|
421
427
|
}
|
|
422
428
|
--_this.state.outstandingRequests;
|
|
423
429
|
--outstandingRequests;
|
|
430
|
+
|
|
424
431
|
if (!outstandingRequests) {
|
|
425
432
|
_this.emit('drain', doc);
|
|
426
433
|
callback && callback();
|
package/lib/mongo_client.js
CHANGED
|
@@ -12,6 +12,7 @@ var parse = require('./url_parser')
|
|
|
12
12
|
, MongoError = require('mongodb-core').MongoError
|
|
13
13
|
, Db = require('./db')
|
|
14
14
|
, f = require('util').format
|
|
15
|
+
, assign = require('./utils').assign
|
|
15
16
|
, shallowClone = require('./utils').shallowClone
|
|
16
17
|
, authenticate = require('./authenticate');
|
|
17
18
|
|
|
@@ -30,14 +31,14 @@ var parse = require('./url_parser')
|
|
|
30
31
|
* });
|
|
31
32
|
*/
|
|
32
33
|
var validOptionNames = ['poolSize', 'ssl', 'sslValidate', 'sslCA', 'sslCert',
|
|
33
|
-
'sslKey', 'sslPass', 'sslCRL', 'autoReconnect', 'noDelay', 'keepAlive', 'connectTimeoutMS',
|
|
34
|
+
'sslKey', 'sslPass', 'sslCRL', 'autoReconnect', 'noDelay', 'keepAlive', 'connectTimeoutMS', 'family',
|
|
34
35
|
'socketTimeoutMS', 'reconnectTries', 'reconnectInterval', 'ha', 'haInterval',
|
|
35
36
|
'replicaSet', 'secondaryAcceptableLatencyMS', 'acceptableLatencyMS',
|
|
36
37
|
'connectWithNoPrimary', 'authSource', 'w', 'wtimeout', 'j', 'forceServerObjectId',
|
|
37
|
-
'serializeFunctions', 'ignoreUndefined', 'raw', '
|
|
38
|
+
'serializeFunctions', 'ignoreUndefined', 'raw', 'bufferMaxEntries',
|
|
38
39
|
'readPreference', 'pkFactory', 'promiseLibrary', 'readConcern', 'maxStalenessSeconds',
|
|
39
40
|
'loggerLevel', 'logger', 'promoteValues', 'promoteBuffers', 'promoteLongs',
|
|
40
|
-
'domainsEnabled', 'keepAliveInitialDelay', 'checkServerIdentity', 'validateOptions'];
|
|
41
|
+
'domainsEnabled', 'keepAliveInitialDelay', 'checkServerIdentity', 'validateOptions', 'appname', 'auth'];
|
|
41
42
|
var ignoreOptionNames = ['native_parser'];
|
|
42
43
|
var legacyOptionNames = ['server', 'replset', 'replSet', 'mongos', 'db'];
|
|
43
44
|
|
|
@@ -100,9 +101,10 @@ function MongoClient() {
|
|
|
100
101
|
* @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function.
|
|
101
102
|
* @param {boolean} [options.autoReconnect=true] Enable autoReconnect for single server instances
|
|
102
103
|
* @param {boolean} [options.noDelay=true] TCP Connection no delay
|
|
103
|
-
* @param {
|
|
104
|
+
* @param {number} [options.family=4] Version of IP stack. Defaults to 4.
|
|
105
|
+
* @param {boolean} [options.keepAlive=30000] The number of milliseconds to wait before initiating keepAlive on the TCP socket.
|
|
104
106
|
* @param {number} [options.connectTimeoutMS=30000] TCP Connection timeout setting
|
|
105
|
-
* @param {number} [options.socketTimeoutMS=
|
|
107
|
+
* @param {number} [options.socketTimeoutMS=360000] TCP Socket timeout setting
|
|
106
108
|
* @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
|
|
107
109
|
* @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
|
|
108
110
|
* @param {boolean} [options.ha=true] Control if high availability monitoring runs for Replicaset or Mongos proxies.
|
|
@@ -112,6 +114,8 @@ function MongoClient() {
|
|
|
112
114
|
* @param {number} [options.acceptableLatencyMS=15] Cutoff latency point in MS for Mongos proxies selection.
|
|
113
115
|
* @param {boolean} [options.connectWithNoPrimary=false] Sets if the driver should connect even if no primary is available
|
|
114
116
|
* @param {string} [options.authSource=undefined] Define the database to authenticate against
|
|
117
|
+
* @param {string} [options.auth.user=undefined] The username for auth
|
|
118
|
+
* @param {string} [options.auth.password=undefined] The username for auth
|
|
115
119
|
* @param {(number|string)} [options.w=null] The write concern.
|
|
116
120
|
* @param {number} [options.wtimeout=null] The write concern timeout.
|
|
117
121
|
* @param {boolean} [options.j=false] Specify a journal write concern.
|
|
@@ -130,6 +134,7 @@ function MongoClient() {
|
|
|
130
134
|
* @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
|
|
131
135
|
* @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)
|
|
132
136
|
* @param {number} [options.maxStalenessSeconds=undefined] The max staleness to secondary reads (values under 10 seconds cannot be guaranteed);
|
|
137
|
+
* @param {string} [options.appname=undefined] The name of the application that created this MongoClient instance. MongoDB 3.4 and newer will print this value in the server log upon establishing each connection. It is also recorded in the slow query log and profile collections.
|
|
133
138
|
* @param {string} [options.loggerLevel=undefined] The logging level (error/warn/info/debug)
|
|
134
139
|
* @param {object} [options.logger=undefined] Custom logger object
|
|
135
140
|
* @param {object} [options.validateOptions=false] Validate MongoClient passed in options for correctness.
|
|
@@ -167,9 +172,10 @@ var define = MongoClient.define = new Define('MongoClient', MongoClient, false);
|
|
|
167
172
|
* @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function.
|
|
168
173
|
* @param {boolean} [options.autoReconnect=true] Enable autoReconnect for single server instances
|
|
169
174
|
* @param {boolean} [options.noDelay=true] TCP Connection no delay
|
|
170
|
-
* @param {
|
|
175
|
+
* @param {number} [options.family=4] Version of IP stack. Defaults to 4.
|
|
176
|
+
* @param {boolean} [options.keepAlive=30000] The number of milliseconds to wait before initiating keepAlive on the TCP socket.
|
|
171
177
|
* @param {number} [options.connectTimeoutMS=30000] TCP Connection timeout setting
|
|
172
|
-
* @param {number} [options.socketTimeoutMS=
|
|
178
|
+
* @param {number} [options.socketTimeoutMS=360000] TCP Socket timeout setting
|
|
173
179
|
* @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
|
|
174
180
|
* @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
|
|
175
181
|
* @param {boolean} [options.ha=true] Control if high availability monitoring runs for Replicaset or Mongos proxies.
|
|
@@ -179,6 +185,8 @@ var define = MongoClient.define = new Define('MongoClient', MongoClient, false);
|
|
|
179
185
|
* @param {number} [options.acceptableLatencyMS=15] Cutoff latency point in MS for Mongos proxies selection.
|
|
180
186
|
* @param {boolean} [options.connectWithNoPrimary=false] Sets if the driver should connect even if no primary is available
|
|
181
187
|
* @param {string} [options.authSource=undefined] Define the database to authenticate against
|
|
188
|
+
* @param {string} [options.auth.user=undefined] The username for auth
|
|
189
|
+
* @param {string} [options.auth.password=undefined] The username for auth
|
|
182
190
|
* @param {(number|string)} [options.w=null] The write concern.
|
|
183
191
|
* @param {number} [options.wtimeout=null] The write concern timeout.
|
|
184
192
|
* @param {boolean} [options.j=false] Specify a journal write concern.
|
|
@@ -197,6 +205,7 @@ var define = MongoClient.define = new Define('MongoClient', MongoClient, false);
|
|
|
197
205
|
* @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
|
|
198
206
|
* @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)
|
|
199
207
|
* @param {number} [options.maxStalenessSeconds=undefined] The max staleness to secondary reads (values under 10 seconds cannot be guaranteed);
|
|
208
|
+
* @param {string} [options.appname=undefined] The name of the application that created this MongoClient instance. MongoDB 3.4 and newer will print this value in the server log upon establishing each connection. It is also recorded in the slow query log and profile collections.
|
|
200
209
|
* @param {string} [options.loggerLevel=undefined] The logging level (error/warn/info/debug)
|
|
201
210
|
* @param {object} [options.logger=undefined] Custom logger object
|
|
202
211
|
* @param {object} [options.validateOptions=false] Validate MongoClient passed in options for correctness.
|
|
@@ -294,7 +303,7 @@ function translateOptions(options) {
|
|
|
294
303
|
}
|
|
295
304
|
|
|
296
305
|
// Set the socket and connection timeouts
|
|
297
|
-
if(options.socketTimeoutMS == null) options.socketTimeoutMS =
|
|
306
|
+
if(options.socketTimeoutMS == null) options.socketTimeoutMS = 360000;
|
|
298
307
|
if(options.connectTimeoutMS == null) options.connectTimeoutMS = 30000;
|
|
299
308
|
|
|
300
309
|
// Create server instances
|
|
@@ -305,6 +314,37 @@ function translateOptions(options) {
|
|
|
305
314
|
});
|
|
306
315
|
}
|
|
307
316
|
|
|
317
|
+
//
|
|
318
|
+
// Collect all events in order from SDAM
|
|
319
|
+
//
|
|
320
|
+
function collectEvents(self, db) {
|
|
321
|
+
var collectedEvents = [];
|
|
322
|
+
|
|
323
|
+
if(self instanceof MongoClient) {
|
|
324
|
+
var events = ["timeout", "close", 'serverOpening', 'serverDescriptionChanged', 'serverHeartbeatStarted',
|
|
325
|
+
'serverHeartbeatSucceeded', 'serverHeartbeatFailed', 'serverClosed', 'topologyOpening',
|
|
326
|
+
'topologyClosed', 'topologyDescriptionChanged', 'joined', 'left', 'ping', 'ha', 'all', 'fullsetup'];
|
|
327
|
+
events.forEach(function(event) {
|
|
328
|
+
db.serverConfig.on(event, function(object1, object2) {
|
|
329
|
+
collectedEvents.push({
|
|
330
|
+
event: event, object1: object1, object2: object2
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return collectedEvents;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
//
|
|
340
|
+
// Replay any events due to single server connection switching to Mongos
|
|
341
|
+
//
|
|
342
|
+
function replayEvents(self, events) {
|
|
343
|
+
for(var i = 0; i < events.length; i++) {
|
|
344
|
+
self.emit(events[i].event, events[i].object1, events[i].object2);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
308
348
|
function relayEvents(self, db) {
|
|
309
349
|
if(self instanceof MongoClient) {
|
|
310
350
|
var events = ["timeout", "close", 'serverOpening', 'serverDescriptionChanged', 'serverHeartbeatStarted',
|
|
@@ -325,7 +365,7 @@ function createReplicaset(self, options, callback) {
|
|
|
325
365
|
var db = new Db(options.dbName, new ReplSet(servers, options), options);
|
|
326
366
|
// Propegate the events to the client
|
|
327
367
|
relayEvents(self, db);
|
|
328
|
-
// Open the connection
|
|
368
|
+
// Open the connection
|
|
329
369
|
db.open(callback);
|
|
330
370
|
}
|
|
331
371
|
|
|
@@ -336,7 +376,7 @@ function createMongos(self, options, callback) {
|
|
|
336
376
|
var db = new Db(options.dbName, new Mongos(servers, options), options)
|
|
337
377
|
// Propegate the events to the client
|
|
338
378
|
relayEvents(self, db);
|
|
339
|
-
// Open the connection
|
|
379
|
+
// Open the connection
|
|
340
380
|
db.open(callback);
|
|
341
381
|
}
|
|
342
382
|
|
|
@@ -346,7 +386,7 @@ function createServer(self, options, callback) {
|
|
|
346
386
|
// Create db instance
|
|
347
387
|
var db = new Db(options.dbName, servers[0], options);
|
|
348
388
|
// Propegate the events to the client
|
|
349
|
-
|
|
389
|
+
var collectedEvents = collectEvents(self, db);
|
|
350
390
|
// Create Db instance
|
|
351
391
|
db.open(function(err, db) {
|
|
352
392
|
if(err) return callback(err);
|
|
@@ -361,6 +401,10 @@ function createServer(self, options, callback) {
|
|
|
361
401
|
return createMongos(self, options, callback);
|
|
362
402
|
}
|
|
363
403
|
|
|
404
|
+
// Fire all the events
|
|
405
|
+
replayEvents(self, collectedEvents);
|
|
406
|
+
// Propegate the events to the client
|
|
407
|
+
relayEvents(self, db);
|
|
364
408
|
// Otherwise callback
|
|
365
409
|
callback(err, db);
|
|
366
410
|
});
|
|
@@ -445,9 +489,13 @@ var connect = function(self, url, options, callback) {
|
|
|
445
489
|
_finalOptions = createUnifiedOptions(_finalOptions, options);
|
|
446
490
|
|
|
447
491
|
// Check if we have connection and socket timeout set
|
|
448
|
-
if(_finalOptions.socketTimeoutMS == null) _finalOptions.socketTimeoutMS =
|
|
492
|
+
if(_finalOptions.socketTimeoutMS == null) _finalOptions.socketTimeoutMS = 360000;
|
|
449
493
|
if(_finalOptions.connectTimeoutMS == null) _finalOptions.connectTimeoutMS = 30000;
|
|
450
494
|
|
|
495
|
+
if (_finalOptions.db_options && _finalOptions.db_options.auth) {
|
|
496
|
+
delete _finalOptions.db_options.auth;
|
|
497
|
+
}
|
|
498
|
+
|
|
451
499
|
// Failure modes
|
|
452
500
|
if(object.servers.length == 0) {
|
|
453
501
|
throw new Error("connection string must contain at least one seed host");
|
package/lib/mongos.js
CHANGED
|
@@ -283,9 +283,8 @@ Mongos.prototype.connect = function(db, _options, callback) {
|
|
|
283
283
|
// Connect handler
|
|
284
284
|
var connectHandler = function() {
|
|
285
285
|
// Clear out all the current handlers left over
|
|
286
|
-
["timeout", "error", "close", '
|
|
287
|
-
|
|
288
|
-
'topologyClosed', 'topologyDescriptionChanged'].forEach(function(e) {
|
|
286
|
+
var events = ["timeout", "error", "close", 'fullsetup'];
|
|
287
|
+
events.forEach(function(e) {
|
|
289
288
|
self.s.mongos.removeAllListeners(e);
|
|
290
289
|
});
|
|
291
290
|
|
|
@@ -294,19 +293,8 @@ Mongos.prototype.connect = function(db, _options, callback) {
|
|
|
294
293
|
self.s.mongos.once('error', errorHandler('error'));
|
|
295
294
|
self.s.mongos.once('close', errorHandler('close'));
|
|
296
295
|
|
|
297
|
-
// Set up SDAM listeners
|
|
298
|
-
self.s.mongos.on('serverDescriptionChanged', relay('serverDescriptionChanged'));
|
|
299
|
-
self.s.mongos.on('serverHeartbeatStarted', relay('serverHeartbeatStarted'));
|
|
300
|
-
self.s.mongos.on('serverHeartbeatSucceeded', relay('serverHeartbeatSucceeded'));
|
|
301
|
-
self.s.mongos.on('serverHeartbeatFailed', relay('serverHeartbeatFailed'));
|
|
302
|
-
self.s.mongos.on('serverOpening', relay('serverOpening'));
|
|
303
|
-
self.s.mongos.on('serverClosed', relay('serverClosed'));
|
|
304
|
-
self.s.mongos.on('topologyOpening', relay('topologyOpening'));
|
|
305
|
-
self.s.mongos.on('topologyClosed', relay('topologyClosed'));
|
|
306
|
-
self.s.mongos.on('topologyDescriptionChanged', relay('topologyDescriptionChanged'));
|
|
307
|
-
|
|
308
296
|
// Set up serverConfig listeners
|
|
309
|
-
self.s.mongos.on('fullsetup',
|
|
297
|
+
self.s.mongos.on('fullsetup', function() { self.emit('fullsetup', self); });
|
|
310
298
|
|
|
311
299
|
// Emit open event
|
|
312
300
|
self.emit('open', null, self);
|
|
@@ -319,6 +307,25 @@ Mongos.prototype.connect = function(db, _options, callback) {
|
|
|
319
307
|
}
|
|
320
308
|
}
|
|
321
309
|
|
|
310
|
+
// Clear out all the current handlers left over
|
|
311
|
+
var events = ["timeout", "error", "close", 'serverOpening', 'serverDescriptionChanged', 'serverHeartbeatStarted',
|
|
312
|
+
'serverHeartbeatSucceeded', 'serverHeartbeatFailed', 'serverClosed', 'topologyOpening',
|
|
313
|
+
'topologyClosed', 'topologyDescriptionChanged'];
|
|
314
|
+
events.forEach(function(e) {
|
|
315
|
+
self.s.mongos.removeAllListeners(e);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// Set up SDAM listeners
|
|
319
|
+
self.s.mongos.on('serverDescriptionChanged', relay('serverDescriptionChanged'));
|
|
320
|
+
self.s.mongos.on('serverHeartbeatStarted', relay('serverHeartbeatStarted'));
|
|
321
|
+
self.s.mongos.on('serverHeartbeatSucceeded', relay('serverHeartbeatSucceeded'));
|
|
322
|
+
self.s.mongos.on('serverHeartbeatFailed', relay('serverHeartbeatFailed'));
|
|
323
|
+
self.s.mongos.on('serverOpening', relay('serverOpening'));
|
|
324
|
+
self.s.mongos.on('serverClosed', relay('serverClosed'));
|
|
325
|
+
self.s.mongos.on('topologyOpening', relay('topologyOpening'));
|
|
326
|
+
self.s.mongos.on('topologyClosed', relay('topologyClosed'));
|
|
327
|
+
self.s.mongos.on('topologyDescriptionChanged', relay('topologyDescriptionChanged'));
|
|
328
|
+
|
|
322
329
|
// Set up listeners
|
|
323
330
|
self.s.mongos.once('timeout', connectErrorHandler('timeout'));
|
|
324
331
|
self.s.mongos.once('error', connectErrorHandler('error'));
|
package/lib/replset.js
CHANGED
|
@@ -44,7 +44,7 @@ var legalOptionNames = ['ha', 'haInterval', 'replicaSet', 'rs_name', 'secondaryA
|
|
|
44
44
|
, 'connectWithNoPrimary', 'poolSize', 'ssl', 'checkServerIdentity', 'sslValidate'
|
|
45
45
|
, 'sslCA', 'sslCert', 'sslCRL', 'sslKey', 'sslPass', 'socketOptions', 'bufferMaxEntries'
|
|
46
46
|
, 'store', 'auto_reconnect', 'autoReconnect', 'emitError'
|
|
47
|
-
, 'keepAlive', 'noDelay', 'connectTimeoutMS', 'socketTimeoutMS', 'strategy', 'debug'
|
|
47
|
+
, 'keepAlive', 'noDelay', 'connectTimeoutMS', 'socketTimeoutMS', 'strategy', 'debug', 'family'
|
|
48
48
|
, 'loggerLevel', 'logger', 'reconnectTries', 'appname', 'domainsEnabled'
|
|
49
49
|
, 'servername', 'promoteLongs', 'promoteValues', 'promoteBuffers', 'maxStalenessSeconds'];
|
|
50
50
|
|
|
@@ -62,7 +62,7 @@ var release = os.release();
|
|
|
62
62
|
* @deprecated
|
|
63
63
|
* @param {Server[]} servers A seedlist of servers participating in the replicaset.
|
|
64
64
|
* @param {object} [options=null] Optional settings.
|
|
65
|
-
* @param {
|
|
65
|
+
* @param {boolean} [options.ha=true] Turn on high availability monitoring.
|
|
66
66
|
* @param {number} [options.haInterval=10000] Time between each replicaset status check.
|
|
67
67
|
* @param {string} [options.replicaSet] The name of the replicaset to connect to.
|
|
68
68
|
* @param {number} [options.secondaryAcceptableLatencyMS=15] Sets the range of servers to pick when using NEAREST (lowest ping ms + the latency fence, ex: range of 1 to (1 + 15) ms)
|
|
@@ -321,7 +321,7 @@ ReplSet.prototype.connect = function(db, _options, callback) {
|
|
|
321
321
|
self.s.replset.on('topologyDescriptionChanged', relay('topologyDescriptionChanged'));
|
|
322
322
|
|
|
323
323
|
self.s.replset.on('fullsetup', function() {
|
|
324
|
-
self.emit('fullsetup',
|
|
324
|
+
self.emit('fullsetup', self, self);
|
|
325
325
|
});
|
|
326
326
|
|
|
327
327
|
self.s.replset.on('all', function() {
|
|
@@ -335,31 +335,6 @@ ReplSet.prototype.connect = function(db, _options, callback) {
|
|
|
335
335
|
self.s.replset.once('error', errorHandler('error'));
|
|
336
336
|
self.s.replset.once('close', errorHandler('close'));
|
|
337
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
|
-
// });
|
|
362
|
-
|
|
363
338
|
// Emit open event
|
|
364
339
|
self.emit('open', null, self);
|
|
365
340
|
|