mongodb 3.0.0 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc CHANGED
@@ -7,7 +7,8 @@
7
7
  "mocha": true
8
8
  },
9
9
  "globals": {
10
- "Promise": true
10
+ "Promise": true,
11
+ "Set": true
11
12
  },
12
13
  "parserOptions": {
13
14
  "ecmaVersion": 2017
package/CHANGES_3.0.0.md CHANGED
@@ -101,10 +101,6 @@ MongoClient.connect('mongodb://localhost:27017/test', (err, client) => {
101
101
  });
102
102
  ```
103
103
 
104
- `Collection.prototype.aggregate` now returns a cursor if a callback is provided. It used to return
105
- the resulting documents which is the same as calling `cursor.toArray()` on the cursor we now pass to
106
- the callback.
107
-
108
104
  ## Other Changes
109
105
 
110
106
  Below are more updates to the driver in the 3.0.0 release.
@@ -177,7 +173,72 @@ in on the options object . Additionally, `find` does not support individual opti
177
173
  `limit` as positional parameters. You must either pass in these parameters in the `options` object,
178
174
  or add them via `Cursor` methods like `Cursor.prototype.skip`.
179
175
 
180
- ### Aggregation
176
+ ### `Collection.prototype.aggregate`
177
+
178
+ `Collection.prototype.aggregate` no longer accepts variadic arguments. While this
179
+ was originally added to improve compatibility with the mongo shell, it has never
180
+ been a documented feature, and has led to more bugs and maintenance burden.
181
+ Pipeline stages are now only accepted as an `Array` of stages as the first argument.
182
+
183
+ 2.x syntax:
184
+
185
+ ```js
186
+ collection.prototype.aggregate(
187
+ {$match: {a: 1}},
188
+ {$project: {b: 1, _id: 0}},
189
+ function (err, result) {
190
+ ...
191
+ }
192
+ );
193
+ ```
194
+
195
+ 3.x syntax
196
+
197
+ ```js
198
+ collection.prototype.aggregate(
199
+ [
200
+ {$match: {a: 1}},
201
+ {$project: {b: 1, _id: 0}}
202
+ ],
203
+ function (err, cursor) {
204
+ ...
205
+ }
206
+ );
207
+ ```
208
+
209
+ `Collection.prototype.aggregate` now returns a cursor if a callback is provided. It used to return
210
+ the resulting documents which is the same as calling `cursor.toArray()` on the cursor we now pass to
211
+ the callback.
212
+
213
+ 2.x syntax
214
+
215
+ ```js
216
+ collection.prototype.aggregate(
217
+ [
218
+ {$match: {a: 1}},
219
+ {$project: {b: 1, _id: 0}}
220
+ ],
221
+ function (err, result) {
222
+ console.log(result);
223
+ }
224
+ );
225
+ ```
226
+
227
+ 3.x syntax
228
+
229
+ ```js
230
+ collection.prototype.aggregate(
231
+ [
232
+ {$match: {a: 1}},
233
+ {$project: {b: 1, _id: 0}}
234
+ ],
235
+ function (err, cursor) {
236
+ cursor.toArray(function(err, result) {
237
+ console.log(result);
238
+ });
239
+ }
240
+ );
241
+ ```
181
242
 
182
243
  Support added for `comment` in the aggregation command. Support also added for a `hint` field in the
183
244
  aggregation `options`.
package/HISTORY.md CHANGED
@@ -1,3 +1,60 @@
1
+ <a name="3.0.4"></a>
2
+ ## [3.0.4](https://github.com/mongodb/node-mongodb-native/compare/v3.0.2...v3.0.4) (2018-03-05)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * **collection:** fix error when calling remove with no args ([#1657](https://github.com/mongodb/node-mongodb-native/issues/1657)) ([4c9b0f8](https://github.com/mongodb/node-mongodb-native/commit/4c9b0f8))
8
+ * **executeOperation:** don't mutate options passed to commands ([934a43a](https://github.com/mongodb/node-mongodb-native/commit/934a43a))
9
+ * **jsdoc:** mark db.collection callback as optional + typo fix ([#1658](https://github.com/mongodb/node-mongodb-native/issues/1658)) ([c519b9b](https://github.com/mongodb/node-mongodb-native/commit/c519b9b))
10
+ * **sessions:** move active session tracking to topology base ([#1665](https://github.com/mongodb/node-mongodb-native/issues/1665)) ([b1f296f](https://github.com/mongodb/node-mongodb-native/commit/b1f296f))
11
+ * **utils:** fixes executeOperation to clean up sessions ([04e6ef6](https://github.com/mongodb/node-mongodb-native/commit/04e6ef6))
12
+
13
+
14
+ ### Features
15
+
16
+ * **default-db:** use dbName from uri if none provided ([23b1938](https://github.com/mongodb/node-mongodb-native/commit/23b1938))
17
+ * **mongodb-core:** update to mongodb-core 3.0.4 ([1fdbaa5](https://github.com/mongodb/node-mongodb-native/commit/1fdbaa5))
18
+
19
+
20
+
21
+ <a name="3.0.3"></a>
22
+ ## [3.0.3](https://github.com/mongodb/node-mongodb-native/compare/v3.0.2...v3.0.3) (2018-02-23)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * **collection:** fix error when calling remove with no args ([#1657](https://github.com/mongodb/node-mongodb-native/issues/1657)) ([4c9b0f8](https://github.com/mongodb/node-mongodb-native/commit/4c9b0f8))
28
+ * **executeOperation:** don't mutate options passed to commands ([934a43a](https://github.com/mongodb/node-mongodb-native/commit/934a43a))
29
+ * **jsdoc:** mark db.collection callback as optional + typo fix ([#1658](https://github.com/mongodb/node-mongodb-native/issues/1658)) ([c519b9b](https://github.com/mongodb/node-mongodb-native/commit/c519b9b))
30
+ * **sessions:** move active session tracking to topology base ([#1665](https://github.com/mongodb/node-mongodb-native/issues/1665)) ([b1f296f](https://github.com/mongodb/node-mongodb-native/commit/b1f296f))
31
+
32
+
33
+
34
+ <a name="3.0.2"></a>
35
+ ## [3.0.2](https://github.com/mongodb/node-mongodb-native/compare/v3.0.1...v3.0.2) (2018-01-29)
36
+
37
+
38
+ ### Bug Fixes
39
+
40
+ * **collection:** ensure dynamic require of `db` is wrapped in parentheses ([efa78f0](https://github.com/mongodb/node-mongodb-native/commit/efa78f0))
41
+ * **db:** only callback with MongoError NODE-1293 ([#1652](https://github.com/mongodb/node-mongodb-native/issues/1652)) ([45bc722](https://github.com/mongodb/node-mongodb-native/commit/45bc722))
42
+ * **topology base:** allow more than 10 event listeners ([#1630](https://github.com/mongodb/node-mongodb-native/issues/1630)) ([d9fb750](https://github.com/mongodb/node-mongodb-native/commit/d9fb750))
43
+ * **url parser:** preserve auth creds when composing conn string ([#1640](https://github.com/mongodb/node-mongodb-native/issues/1640)) ([eddca5e](https://github.com/mongodb/node-mongodb-native/commit/eddca5e))
44
+
45
+
46
+ ### Features
47
+
48
+ * **bulk:** forward 'checkKeys' option for ordered and unordered bulk operations ([421a6b2](https://github.com/mongodb/node-mongodb-native/commit/421a6b2))
49
+ * **collection:** expose `dbName` property of collection ([6fd05c1](https://github.com/mongodb/node-mongodb-native/commit/6fd05c1))
50
+
51
+
52
+
53
+ <a name="3.0.1"></a>
54
+ ## [3.0.1](https://github.com/mongodb/node-mongodb-native/compare/v3.0.0...v3.0.1) (2017-12-24)
55
+
56
+ * update mongodb-core to 3.0.1
57
+
1
58
  <a name="3.0.0"></a>
2
59
  # [3.0.0](https://github.com/mongodb/node-mongodb-native/compare/v3.0.0-rc0...v3.0.0) (2017-12-24)
3
60
 
package/README.md CHANGED
@@ -15,7 +15,7 @@ The official [MongoDB](https://www.mongodb.com/) driver for Node.js. Provides a
15
15
  | what | where |
16
16
  |---------------|------------------------------------------------|
17
17
  | documentation | http://mongodb.github.io/node-mongodb-native |
18
- | api-doc | http://mongodb.github.io/node-mongodb-native/2.2/api |
18
+ | api-doc | http://mongodb.github.io/node-mongodb-native/3.0/api |
19
19
  | source | https://github.com/mongodb/node-mongodb-native |
20
20
  | mongodb | http://www.mongodb.org |
21
21
 
@@ -67,11 +67,11 @@ The MongoDB driver depends on several other packages. These are:
67
67
 
68
68
  The `kerberos` package is a C++ extension that requires a build environment to be installed on your system. You must be able to build Node.js itself in order to compile and install the `kerberos` module. Furthermore, the `kerberos` module requires the MIT Kerberos package to correctly compile on UNIX operating systems. Consult your UNIX operation system package manager for what libraries to install.
69
69
 
70
- **Windows already contains the SSPI API used for Kerberos authentication. However you will need to install a full compiler tool chain using Visual Studio C++ to correctly install the Kerberos extension.**
70
+ **Windows already contains the SSPI API used for Kerberos authentication. However, you will need to install a full compiler tool chain using Visual Studio C++ to correctly install the Kerberos extension.**
71
71
 
72
72
  ### Diagnosing on UNIX
73
73
 
74
- If you don’t have the build essentials, this module won’t build. In the case of Linux, you will need gcc, g++, Node.js with all the headers and Python. The easiest way to figure out what’s missing is by trying to build the Kerberos project. You can do this by performing the following steps.
74
+ If you don’t have the build-essentials, this module won’t build. In the case of Linux, you will need gcc, g++, Node.js with all the headers and Python. The easiest way to figure out what’s missing is by trying to build the Kerberos project. You can do this by performing the following steps.
75
75
 
76
76
  ```bash
77
77
  git clone https://github.com/mongodb-js/kerberos
@@ -303,7 +303,9 @@ function OrderedBulkOperation(topology, collection, options) {
303
303
  bypassDocumentValidation:
304
304
  typeof options.bypassDocumentValidation === 'boolean'
305
305
  ? options.bypassDocumentValidation
306
- : false
306
+ : false,
307
+ // check keys
308
+ checkKeys: typeof options.checkKeys === 'boolean' ? options.checkKeys : true
307
309
  };
308
310
  }
309
311
 
@@ -513,6 +515,11 @@ var executeCommands = function(self, options, callback) {
513
515
  finalOptions.bypassDocumentValidation = true;
514
516
  }
515
517
 
518
+ // Is the checkKeys option disabled
519
+ if (self.s.checkKeys === false) {
520
+ finalOptions.checkKeys = false;
521
+ }
522
+
516
523
  try {
517
524
  if (batch.batchType === common.INSERT) {
518
525
  self.s.topology.insert(
@@ -312,7 +312,9 @@ var UnorderedBulkOperation = function(topology, collection, options) {
312
312
  bypassDocumentValidation:
313
313
  typeof options.bypassDocumentValidation === 'boolean'
314
314
  ? options.bypassDocumentValidation
315
- : false
315
+ : false,
316
+ // check keys
317
+ checkKeys: typeof options.checkKeys === 'boolean' ? options.checkKeys : true
316
318
  };
317
319
  };
318
320
 
@@ -474,6 +476,11 @@ var executeBatch = function(self, batch, options, callback) {
474
476
  finalOptions.bypassDocumentValidation = true;
475
477
  }
476
478
 
479
+ // Is the checkKeys option disabled
480
+ if (self.s.checkKeys === false) {
481
+ finalOptions.checkKeys = false;
482
+ }
483
+
477
484
  try {
478
485
  if (batch.batchType === common.INSERT) {
479
486
  self.s.topology.insert(
@@ -13,7 +13,7 @@ var cursorOptionNames = ['maxAwaitTimeMS', 'collation', 'readPreference'];
13
13
  * @param {(Db|Collection)} changeDomain The collection against which to create the change stream
14
14
  * @param {Array} pipeline An array of {@link https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/|aggregation pipeline stages} through which to pass change stream documents
15
15
  * @param {object} [options=null] Optional settings
16
- * @param {string} [options.fullDocument=none] Allowed values: ‘none’, ‘lookup’. When set to ‘lookup’, the change stream will include both a delta describing the changes to the document, as well as a copy of the entire document that was changed from some time after the change occurred.
16
+ * @param {string} [options.fullDocument='default'] Allowed values: ‘default’, ‘updateLookup’. When set to ‘updateLookup’, the change stream will include both a delta describing the changes to the document, as well as a copy of the entire document that was changed from some time after the change occurred.
17
17
  * @param {number} [options.maxAwaitTimeMS] The maximum amount of time for the server to wait on new documents to satisfy a change stream query
18
18
  * @param {object} [options.resumeAfter=null] Specifies the logical starting point for the new change stream. This should be the _id field from a previously returned change stream document.
19
19
  * @param {number} [options.batchSize=null] The number of documents to return per batch. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
@@ -335,7 +335,7 @@ var processNewChange = function(self, err, change, callback) {
335
335
  // Cache the resume token if it is present. If it is not present return an error.
336
336
  if (!change || !change._id) {
337
337
  var noResumeTokenError = new Error(
338
- 'A change stream document has been recieved that lacks a resume token (_id).'
338
+ 'A change stream document has been received that lacks a resume token (_id).'
339
339
  );
340
340
  if (typeof callback === 'function') return callback(noResumeTokenError, null);
341
341
  if (self.listenerCount('error')) return self.emit('error', noResumeTokenError);
package/lib/collection.js CHANGED
@@ -143,6 +143,13 @@ var Collection = function(db, topology, dbName, name, pkFactory, options) {
143
143
 
144
144
  var define = (Collection.define = new Define('Collection', Collection, false));
145
145
 
146
+ Object.defineProperty(Collection.prototype, 'dbName', {
147
+ enumerable: true,
148
+ get: function() {
149
+ return this.s.dbName;
150
+ }
151
+ });
152
+
146
153
  Object.defineProperty(Collection.prototype, 'collectionName', {
147
154
  enumerable: true,
148
155
  get: function() {
@@ -811,6 +818,7 @@ define.classMethod('insert', { callback: true, promise: true });
811
818
  * @param {number} [options.wtimeout=null] The write concern timeout.
812
819
  * @param {boolean} [options.j=false] Specify a journal write concern.
813
820
  * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
821
+ * @param {Array} [options.arrayFilters=null] optional list of array filters referenced in filtered positional operators
814
822
  * @param {ClientSession} [options.session] optional session to use for this operation
815
823
  * @param {Collection~updateWriteOpCallback} [callback] The command result callback
816
824
  * @return {Promise} returns Promise if no callback passed
@@ -929,13 +937,14 @@ define.classMethod('replaceOne', { callback: true, promise: true });
929
937
  /**
930
938
  * Update multiple documents on MongoDB
931
939
  * @method
932
- * @param {object} filter The Filter used to select the document to update
940
+ * @param {object} filter The Filter used to select the documents to update
933
941
  * @param {object} update The update operations to be applied to the document
934
942
  * @param {object} [options=null] Optional settings.
935
943
  * @param {boolean} [options.upsert=false] Update operation is an upsert.
936
944
  * @param {(number|string)} [options.w=null] The write concern.
937
945
  * @param {number} [options.wtimeout=null] The write concern timeout.
938
946
  * @param {boolean} [options.j=false] Specify a journal write concern.
947
+ * @param {Array} [options.arrayFilters=null] optional list of array filters referenced in filtered positional operators
939
948
  * @param {ClientSession} [options.session] optional session to use for this operation
940
949
  * @param {Collection~updateWriteOpCallback} [callback] The command result callback
941
950
  * @return {Promise} returns Promise if no callback passed
@@ -1042,6 +1051,7 @@ var updateDocuments = function(self, selector, document, options, callback) {
1042
1051
  * @param {boolean} [options.multi=false] Update one/all documents with operation.
1043
1052
  * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
1044
1053
  * @param {object} [options.collation=null] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
1054
+ * @param {Array} [options.arrayFilters=null] optional list of array filters referenced in filtered positional operators
1045
1055
  * @param {ClientSession} [options.session] optional session to use for this operation
1046
1056
  * @param {Collection~writeOpCallback} [callback] The command result callback
1047
1057
  * @throws {MongoError}
@@ -1223,6 +1233,9 @@ define.classMethod('removeMany', { callback: true, promise: true });
1223
1233
  * @deprecated use deleteOne, deleteMany or bulkWrite
1224
1234
  */
1225
1235
  Collection.prototype.remove = function(selector, options, callback) {
1236
+ if (typeof options === 'function') (callback = options), (options = {});
1237
+ options = options || {};
1238
+
1226
1239
  // Add ignoreUndfined
1227
1240
  if (this.s.options.ignoreUndefined) {
1228
1241
  options = shallowClone(options);
@@ -1288,6 +1301,13 @@ define.classMethod('save', { callback: true, promise: true });
1288
1301
  * @param {object} result The result object if the command was executed successfully.
1289
1302
  */
1290
1303
 
1304
+ /**
1305
+ * The callback format for an aggregation call
1306
+ * @callback Collection~aggregationCallback
1307
+ * @param {MongoError} error An error instance representing the error during the execution.
1308
+ * @param {AggregationCursor} cursor The cursor if the aggregation command was executed successfully.
1309
+ */
1310
+
1291
1311
  /**
1292
1312
  * Fetches the first document that matches the query
1293
1313
  * @method
@@ -1512,12 +1532,8 @@ define.classMethod('isCapped', { callback: true, promise: true });
1512
1532
  * @return {Promise} returns Promise if no callback passed
1513
1533
  */
1514
1534
  Collection.prototype.createIndex = function(fieldOrSpec, options, callback) {
1515
- var args = Array.prototype.slice.call(arguments, 1);
1516
- callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
1517
-
1518
- options = args.length ? args.shift() || {} : {};
1519
- options = typeof callback === 'function' ? options : callback;
1520
- options = options == null ? {} : options;
1535
+ if (typeof options === 'function') (callback = options), (options = {});
1536
+ options = options || {};
1521
1537
 
1522
1538
  return executeOperation(this.s.topology, createIndex, [this, fieldOrSpec, options, callback]);
1523
1539
  };
@@ -2384,7 +2400,7 @@ function decorateWithReadConcern(command, self, options) {
2384
2400
  * @param {object} [options.collation=null] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
2385
2401
  * @param {string} [options.comment] Add a comment to an aggregation command
2386
2402
  * @param {ClientSession} [options.session] optional session to use for this operation
2387
- * @param {Collection~resultCallback} callback The command result callback
2403
+ * @param {Collection~aggregationCallback} callback The command result callback
2388
2404
  * @return {(null|AggregationCursor)}
2389
2405
  */
2390
2406
  Collection.prototype.aggregate = function(pipeline, options, callback) {
@@ -2516,7 +2532,7 @@ define.classMethod('aggregate', { callback: true, promise: false });
2516
2532
  * @since 3.0.0
2517
2533
  * @param {Array} [pipeline=null] An array of {@link https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/|aggregation pipeline stages} through which to pass change stream documents. This allows for filtering (using $match) and manipulating the change stream documents.
2518
2534
  * @param {object} [options=null] Optional settings
2519
- * @param {string} [options.fullDocument=none] Allowed values: ‘none’, ‘lookup’. When set to ‘lookup’, the change stream will include both a delta describing the changes to the document, as well as a copy of the entire document that was changed from some time after the change occurred.
2535
+ * @param {string} [options.fullDocument='default'] Allowed values: ‘default’, ‘updateLookup’. When set to ‘updateLookup’, the change stream will include both a delta describing the changes to the document, as well as a copy of the entire document that was changed from some time after the change occurred.
2520
2536
  * @param {object} [options.resumeAfter=null] Specifies the logical starting point for the new change stream. This should be the _id field from a previously returned change stream document.
2521
2537
  * @param {number} [options.maxAwaitTimeMS] The maximum amount of time for the server to wait on new documents to satisfy a change stream query
2522
2538
  * @param {number} [options.batchSize=null] The number of documents to return per batch. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
@@ -2998,11 +3014,10 @@ var mapReduce = function(self, map, reduce, options, callback) {
2998
3014
  if (result.result != null && typeof result.result === 'object') {
2999
3015
  var doc = result.result;
3000
3016
  // Return a collection from another db
3001
- collection = new require('./db')(
3002
- doc.db,
3003
- self.s.db.s.topology,
3004
- self.s.db.s.options
3005
- ).collection(doc.collection);
3017
+ var Db = require('./db');
3018
+ collection = new Db(doc.db, self.s.db.s.topology, self.s.db.s.options).collection(
3019
+ doc.collection
3020
+ );
3006
3021
  } else {
3007
3022
  // Create a collection object that wraps the result collection
3008
3023
  collection = self.s.db.collection(result.result);
package/lib/db.js CHANGED
@@ -393,7 +393,7 @@ var collectionKeys = [
393
393
  ];
394
394
 
395
395
  /**
396
- * Fetch a specific collection (containing the actual collection information). If the application does not use strict mode you can
396
+ * Fetch a specific collection (containing the actual collection information). If the application does not use strict mode you
397
397
  * can use it without a callback in the following way: `var collection = db.collection('mycollection');`
398
398
  *
399
399
  * @method
@@ -409,7 +409,7 @@ var collectionKeys = [
409
409
  * @param {boolean} [options.strict=false] Returns an error if the collection does not exist
410
410
  * @param {object} [options.readConcern=null] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
411
411
  * @param {object} [options.readConcern.level='local'] Specify a read concern level for the collection operations, one of [local|majority]. (only MongoDB 3.2 or higher supported)
412
- * @param {Db~collectionResultCallback} callback The collection result callback
412
+ * @param {Db~collectionResultCallback} [callback] The collection result callback
413
413
  * @return {Collection} return the new Collection instance if not in strict mode
414
414
  */
415
415
  Db.prototype.collection = function(name, options, callback) {
@@ -445,8 +445,7 @@ Db.prototype.collection = function(name, options, callback) {
445
445
  if (callback) callback(null, collection);
446
446
  return collection;
447
447
  } catch (err) {
448
- // if(err instanceof MongoError && callback) return callback(err);
449
- if (callback) return callback(err);
448
+ if (err instanceof MongoError && callback) return callback(err);
450
449
  throw err;
451
450
  }
452
451
  }
@@ -1043,13 +1042,8 @@ define.classMethod('executeDbAdminCommand', { callback: true, promise: true });
1043
1042
  * @return {Promise} returns Promise if no callback passed
1044
1043
  */
1045
1044
  Db.prototype.createIndex = function(name, fieldOrSpec, options, callback) {
1046
- var args = Array.prototype.slice.call(arguments, 2);
1047
- callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
1048
- options = args.length ? args.shift() || {} : {};
1049
- options = typeof callback === 'function' ? options : callback;
1050
- options = options == null ? {} : options;
1051
- // Shallow clone the options
1052
- options = shallowClone(options);
1045
+ if (typeof options === 'function') (callback = options), (options = {});
1046
+ options = options ? shallowClone(options) : {};
1053
1047
 
1054
1048
  return executeOperation(this.s.topology, createIndex, [
1055
1049
  this,
@@ -22,6 +22,22 @@ var parse = require('./url_parser'),
22
22
  * @fileOverview The **MongoClient** class is a class that allows for making Connections to MongoDB.
23
23
  *
24
24
  * @example
25
+ * // Connect using a MongoClient instance
26
+ * const MongoClient = require('mongodb').MongoClient;
27
+ * const test = require('assert');
28
+ * // Connection url
29
+ * const url = 'mongodb://localhost:27017';
30
+ * // Database Name
31
+ * const dbName = 'test';
32
+ * // Connect using MongoClient
33
+ * const mongoClient = new MongoClient(url);
34
+ * mongoClient.connect(function(err, client) {
35
+ * const db = client.db(dbName);
36
+ * client.close();
37
+ * });
38
+ *
39
+ * @example
40
+ * // Connect using the MongoClient.connect static method
25
41
  * const MongoClient = require('mongodb').MongoClient;
26
42
  * const test = require('assert');
27
43
  * // Connection url
@@ -140,7 +156,8 @@ function validOptions(options) {
140
156
  * @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
141
157
  * @param {number} [options.keepAliveInitialDelay=30000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
142
158
  * @param {number} [options.connectTimeoutMS=30000] TCP Connection timeout setting
143
- * @param {number} [options.family=4] Version of IP stack. Defaults to 4
159
+ * @param {number} [options.family=null] Version of IP stack. Can be 4, 6 or null (default).
160
+ * If null, will attempt to connect with IPv6, and will fall back to IPv4 on failure
144
161
  * @param {number} [options.socketTimeoutMS=360000] TCP Socket timeout setting
145
162
  * @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
146
163
  * @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
@@ -218,7 +235,7 @@ var define = (MongoClient.define = new Define('MongoClient', MongoClient, false)
218
235
  * The callback format for results
219
236
  * @callback MongoClient~connectCallback
220
237
  * @param {MongoError} error An error instance representing the error during the execution.
221
- * @param {Db} db The connected database.
238
+ * @param {MongoClient} client The connected client.
222
239
  */
223
240
 
224
241
  /**
@@ -230,8 +247,7 @@ var define = (MongoClient.define = new Define('MongoClient', MongoClient, false)
230
247
  *
231
248
  * @method
232
249
  * @param {MongoClient~connectCallback} [callback] The command result callback
233
- * @return {Promise} returns Promise if no callback passed
234
- * @deprecated MongoClient.connect is deprecated, please use new MongoClient().connect() to connect.
250
+ * @return {Promise<MongoClient>} returns Promise if no callback passed
235
251
  */
236
252
  MongoClient.prototype.connect = function(callback) {
237
253
  // Validate options object
@@ -311,14 +327,6 @@ MongoClient.prototype.close = function(force, callback) {
311
327
  // Remove listeners after emit
312
328
  self.removeAllListeners('close');
313
329
 
314
- // If we have sessions, we want to send a single `endSessions` command for them,
315
- // and then individually clean them up. They will be removed from the internal state
316
- // when they emit their `ended` events.
317
- if (this.s.sessions.length) {
318
- this.topology.endSessions(this.s.sessions);
319
- this.s.sessions.forEach(session => session.endSession({ skipCommand: true }));
320
- }
321
-
322
330
  // Callback after next event loop tick
323
331
  if (typeof callback === 'function')
324
332
  return process.nextTick(function() {
@@ -340,7 +348,7 @@ define.classMethod('close', { callback: true, promise: true });
340
348
  * You can control these behaviors with the options noListener and returnNonCachedInstance.
341
349
  *
342
350
  * @method
343
- * @param {string} name The name of the database we want to use.
351
+ * @param {string} dbName The name of the database we want to use.
344
352
  * @param {object} [options=null] Optional settings.
345
353
  * @param {boolean} [options.noListener=false] Do not make the db an event listener to the original connection.
346
354
  * @param {boolean} [options.returnNonCachedInstance=false] Control if you want to return a cached instance or have a new one created
@@ -349,6 +357,11 @@ define.classMethod('close', { callback: true, promise: true });
349
357
  MongoClient.prototype.db = function(dbName, options) {
350
358
  options = options || {};
351
359
 
360
+ // Default to db from connection string if not provided
361
+ if (!dbName) {
362
+ dbName = this.s.options.dbName;
363
+ }
364
+
352
365
  // Copy the options and add out internal override of the not shared flag
353
366
  var finalOptions = Object.assign({}, this.s.options, options);
354
367
 
@@ -382,7 +395,7 @@ MongoClient.prototype.db = function(dbName, options) {
382
395
  * @param {object} [options=null] Optional settings.
383
396
  * @param {boolean} [options.noListener=false] Do not make the db an event listener to the original connection.
384
397
  * @param {boolean} [options.returnNonCachedInstance=false] Control if you want to return a cached instance or have a new one created
385
- * @return {Db}
398
+ * @return {boolean}
386
399
  */
387
400
  MongoClient.prototype.isConnected = function(options) {
388
401
  options = options || {};
@@ -415,7 +428,8 @@ MongoClient.prototype.isConnected = function(options) {
415
428
  * @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
416
429
  * @param {boolean} [options.keepAliveInitialDelay=30000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
417
430
  * @param {number} [options.connectTimeoutMS=30000] TCP Connection timeout setting
418
- * @param {number} [options.family=4] Version of IP stack. Defaults to 4
431
+ * @param {number} [options.family=null] Version of IP stack. Can be 4, 6 or null (default).
432
+ * If null, will attempt to connect with IPv6, and will fall back to IPv4 on failure
419
433
  * @param {number} [options.socketTimeoutMS=360000] TCP Socket timeout setting
420
434
  * @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
421
435
  * @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
@@ -458,7 +472,7 @@ MongoClient.prototype.isConnected = function(options) {
458
472
  * @param {number} [options.numberOfRetries=5] The number of retries for a tailable cursor
459
473
  * @param {boolean} [options.auto_reconnect=true] Enable auto reconnecting for single server instances
460
474
  * @param {MongoClient~connectCallback} [callback] The command result callback
461
- * @return {Promise} returns Promise if no callback passed
475
+ * @return {Promise<MongoClient>} returns Promise if no callback passed
462
476
  */
463
477
  MongoClient.connect = function(url, options, callback) {
464
478
  var args = Array.prototype.slice.call(arguments, 1);
@@ -467,9 +481,9 @@ MongoClient.connect = function(url, options, callback) {
467
481
  options = options || {};
468
482
 
469
483
  // Create client
470
- var mongoclient = new MongoClient(url, options);
484
+ var mongoClient = new MongoClient(url, options);
471
485
  // Execute the connect method
472
- return mongoclient.connect(callback);
486
+ return mongoClient.connect(callback);
473
487
  };
474
488
 
475
489
  define.staticMethod('connect', { callback: true, promise: true });
@@ -478,8 +492,7 @@ define.staticMethod('connect', { callback: true, promise: true });
478
492
  * Starts a new session on the server
479
493
  *
480
494
  * @param {object} [options] optional settings for a driver session
481
- * @param {MongoClient~sessionCallback} [callback] The callback called with a newly establish session, or an error if one occurred
482
- * @return {Promise} if no callback is specified, a promise will be returned for the newly established session
495
+ * @return {ClientSession} the newly established session
483
496
  */
484
497
  MongoClient.prototype.startSession = function(options) {
485
498
  options = options || {};
@@ -491,13 +504,7 @@ MongoClient.prototype.startSession = function(options) {
491
504
  throw new MongoError('Current topology does not support sessions');
492
505
  }
493
506
 
494
- const session = this.topology.startSession(options);
495
- session.once('ended', () => {
496
- this.s.sessions = this.s.sessions.filter(s => s.equals(session));
497
- });
498
-
499
- this.s.sessions.push(session);
500
- return session;
507
+ return this.topology.startSession(options);
501
508
  };
502
509
 
503
510
  var mergeOptions = function(target, source, flatten) {
@@ -190,6 +190,8 @@ class Mongos extends TopologyBase {
190
190
  options: options,
191
191
  // Server Session Pool
192
192
  sessionPool: null,
193
+ // Active client sessions
194
+ sessions: [],
193
195
  // Promise library
194
196
  promiseLibrary: options.promiseLibrary || Promise
195
197
  };
@@ -206,6 +206,8 @@ class ReplSet extends TopologyBase {
206
206
  options: options,
207
207
  // Server Session Pool
208
208
  sessionPool: null,
209
+ // Active client sessions
210
+ sessions: [],
209
211
  // Promise library
210
212
  promiseLibrary: options.promiseLibrary || Promise
211
213
  };
@@ -371,22 +373,9 @@ class ReplSet extends TopologyBase {
371
373
  }
372
374
 
373
375
  close(forceClosed) {
374
- var self = this;
375
- // Call destroy on the topology
376
- this.s.coreTopology.destroy({
377
- force: typeof forceClosed === 'boolean' ? forceClosed : false
378
- });
379
-
380
- // We need to wash out all stored processes
381
- if (forceClosed === true) {
382
- this.s.storeOptions.force = forceClosed;
383
- this.s.store.flush();
384
- }
376
+ super.close(forceClosed);
385
377
 
386
- var events = ['timeout', 'error', 'close', 'joined', 'left'];
387
- events.forEach(function(e) {
388
- self.removeAllListeners(e);
389
- });
378
+ ['timeout', 'error', 'close', 'joined', 'left'].forEach(e => this.removeAllListeners(e));
390
379
  }
391
380
  }
392
381
 
@@ -198,6 +198,8 @@ class Server extends TopologyBase {
198
198
  options: options,
199
199
  // Server Session Pool
200
200
  sessionPool: null,
201
+ // Active client sessions
202
+ sessions: [],
201
203
  // Promise library
202
204
  promiseLibrary: promiseLibrary || Promise
203
205
  };
@@ -280,6 +280,8 @@ class TopologyBase extends EventEmitter {
280
280
  },
281
281
  platform: nodejsversion
282
282
  };
283
+
284
+ this.setMaxListeners(Infinity);
283
285
  }
284
286
 
285
287
  // Sessions related methods
@@ -288,7 +290,13 @@ class TopologyBase extends EventEmitter {
288
290
  }
289
291
 
290
292
  startSession(options) {
291
- return new ClientSession(this, this.s.sessionPool, options);
293
+ const session = new ClientSession(this, this.s.sessionPool, options);
294
+ session.once('ended', () => {
295
+ this.s.sessions = this.s.sessions.filter(s => !s.equals(session));
296
+ });
297
+
298
+ this.s.sessions.push(session);
299
+ return session;
292
300
  }
293
301
 
294
302
  endSessions(sessions, callback) {
@@ -386,6 +394,18 @@ class TopologyBase extends EventEmitter {
386
394
  }
387
395
 
388
396
  close(forceClosed) {
397
+ // If we have sessions, we want to send a single `endSessions` command for them,
398
+ // and then individually clean them up. They will be removed from the internal state
399
+ // when they emit their `ended` events.
400
+ if (this.s.sessions.length) {
401
+ this.endSessions(this.s.sessions.map(session => session.id));
402
+ this.s.sessions.forEach(session => session.endSession({ skipCommand: true }));
403
+ }
404
+
405
+ if (this.s.sessionPool) {
406
+ this.s.sessionPool.endAllPooledSessions();
407
+ }
408
+
389
409
  this.s.coreTopology.destroy({
390
410
  force: typeof forceClosed === 'boolean' ? forceClosed : false
391
411
  });