mongodb 3.6.8 → 3.6.12

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.
Files changed (43) hide show
  1. package/README.md +4 -4
  2. package/lib/bulk/common.js +34 -12
  3. package/lib/cmap/connection.js +1 -0
  4. package/lib/collection.js +9 -0
  5. package/lib/command_utils.js +124 -0
  6. package/lib/core/auth/mongo_credentials.js +4 -1
  7. package/lib/core/auth/mongodb_aws.js +17 -15
  8. package/lib/core/auth/scram.js +1 -0
  9. package/lib/core/connection/apm.js +10 -123
  10. package/lib/core/connection/commands.js +11 -2
  11. package/lib/core/connection/connect.js +3 -0
  12. package/lib/core/connection/connection.js +7 -3
  13. package/lib/core/connection/msg.js +11 -2
  14. package/lib/core/connection/pool.js +7 -2
  15. package/lib/core/connection/utils.js +35 -2
  16. package/lib/core/cursor.js +7 -0
  17. package/lib/core/index.js +1 -0
  18. package/lib/core/sdam/monitor.js +2 -1
  19. package/lib/core/sdam/server.js +8 -1
  20. package/lib/core/sdam/topology.js +28 -15
  21. package/lib/core/topologies/mongos.js +1 -0
  22. package/lib/core/topologies/replset.js +1 -0
  23. package/lib/core/topologies/server.js +7 -2
  24. package/lib/core/uri_parser.js +3 -1
  25. package/lib/core/utils.js +1 -0
  26. package/lib/core/wireprotocol/constants.js +2 -2
  27. package/lib/core/wireprotocol/shared.js +1 -0
  28. package/lib/cursor.js +12 -2
  29. package/lib/db.js +83 -72
  30. package/lib/encrypter.js +8 -3
  31. package/lib/mongo_client.js +1 -0
  32. package/lib/operations/bulk_write.js +0 -17
  33. package/lib/operations/command.js +4 -1
  34. package/lib/operations/command_v2.js +7 -1
  35. package/lib/operations/connect.js +1 -0
  36. package/lib/operations/db_ops.js +6 -2
  37. package/lib/topologies/mongos.js +1 -0
  38. package/lib/topologies/replset.js +1 -0
  39. package/lib/topologies/server.js +1 -0
  40. package/lib/url_parser.js +2 -1
  41. package/lib/utils.js +87 -1
  42. package/package.json +6 -2
  43. package/HISTORY.md +0 -2881
@@ -139,7 +139,12 @@ Msg.getRequestId = function() {
139
139
 
140
140
  class BinMsg {
141
141
  constructor(bson, message, msgHeader, msgBody, opts) {
142
- opts = opts || { promoteLongs: true, promoteValues: true, promoteBuffers: false };
142
+ opts = opts || {
143
+ promoteLongs: true,
144
+ promoteValues: true,
145
+ promoteBuffers: false,
146
+ bsonRegExp: false
147
+ };
143
148
  this.parsed = false;
144
149
  this.raw = message;
145
150
  this.data = msgBody;
@@ -161,6 +166,7 @@ class BinMsg {
161
166
  this.promoteLongs = typeof opts.promoteLongs === 'boolean' ? opts.promoteLongs : true;
162
167
  this.promoteValues = typeof opts.promoteValues === 'boolean' ? opts.promoteValues : true;
163
168
  this.promoteBuffers = typeof opts.promoteBuffers === 'boolean' ? opts.promoteBuffers : false;
169
+ this.bsonRegExp = typeof opts.bsonRegExp === 'boolean' ? opts.bsonRegExp : false;
164
170
 
165
171
  this.documents = [];
166
172
  }
@@ -186,12 +192,15 @@ class BinMsg {
186
192
  typeof options.promoteBuffers === 'boolean'
187
193
  ? options.promoteBuffers
188
194
  : this.opts.promoteBuffers;
195
+ const bsonRegExp =
196
+ typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : this.opts.bsonRegExp;
189
197
 
190
198
  // Set up the options
191
199
  const _options = {
192
200
  promoteLongs: promoteLongs,
193
201
  promoteValues: promoteValues,
194
- promoteBuffers: promoteBuffers
202
+ promoteBuffers: promoteBuffers,
203
+ bsonRegExp: bsonRegExp
195
204
  };
196
205
 
197
206
  while (this.index < this.data.length) {
@@ -76,6 +76,7 @@ var _id = 0;
76
76
  * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
77
77
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
78
78
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
79
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
79
80
  * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit.
80
81
  * @fires Pool#connect
81
82
  * @fires Pool#close
@@ -127,6 +128,7 @@ var Pool = function(topology, options) {
127
128
  promoteLongs: true,
128
129
  promoteValues: true,
129
130
  promoteBuffers: false,
131
+ bsonRegExp: false,
130
132
  // Reconnection options
131
133
  reconnect: true,
132
134
  reconnectInterval: 1000,
@@ -390,8 +392,8 @@ function messageHandler(self) {
390
392
  if (self.logger.isDebug()) {
391
393
  self.logger.debug(
392
394
  f(
393
- 'message [%s] received from %s:%s',
394
- message.raw.toString('hex'),
395
+ 'message [ %s ] received from %s:%s',
396
+ message.raw.length,
395
397
  self.options.host,
396
398
  self.options.port
397
399
  )
@@ -602,6 +604,7 @@ Pool.prototype.logout = function(dbName, callback) {
602
604
  /**
603
605
  * Unref the pool
604
606
  * @method
607
+ * @deprecated This function is deprecated and will be removed in the next major version.
605
608
  */
606
609
  Pool.prototype.unref = function() {
607
610
  // Get all the known connections
@@ -870,6 +873,7 @@ Pool.prototype.write = function(command, options, cb) {
870
873
  promoteLongs: true,
871
874
  promoteValues: true,
872
875
  promoteBuffers: false,
876
+ bsonRegExp: false,
873
877
  fullResult: false
874
878
  };
875
879
 
@@ -879,6 +883,7 @@ Pool.prototype.write = function(command, options, cb) {
879
883
  typeof options.promoteValues === 'boolean' ? options.promoteValues : true;
880
884
  operation.promoteBuffers =
881
885
  typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false;
886
+ operation.bsonRegExp = typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false;
882
887
  operation.raw = typeof options.raw === 'boolean' ? options.raw : false;
883
888
  operation.immediateRelease =
884
889
  typeof options.immediateRelease === 'boolean' ? options.immediateRelease : false;
@@ -1,5 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ const parsePackageVersion = require('../../utils').parsePackageVersion;
4
+ const MongoError = require('../error').MongoError;
5
+
3
6
  const require_optional = require('optional-require')(require);
4
7
 
5
8
  function debugOptions(debugFields, options) {
@@ -16,7 +19,15 @@ function retrieveBSON() {
16
19
  BSON.native = false;
17
20
 
18
21
  const optionalBSON = require_optional('bson-ext');
22
+ const bsonExtVersion = parsePackageVersion(
23
+ require_optional('bson-ext/package.json') || { version: '0.0.0' }
24
+ );
19
25
  if (optionalBSON) {
26
+ if (bsonExtVersion.major >= 4) {
27
+ throw new MongoError(
28
+ 'bson-ext version 4 and above does not work with the 3.x version of the mongodb driver'
29
+ );
30
+ }
20
31
  optionalBSON.native = true;
21
32
  return optionalBSON;
22
33
  }
@@ -31,21 +42,43 @@ function noSnappyWarning() {
31
42
  );
32
43
  }
33
44
 
45
+ const PKG_VERSION = Symbol('kPkgVersion');
46
+
34
47
  // Facilitate loading Snappy optionally
35
48
  function retrieveSnappy() {
36
- let snappy = require_optional('snappy');
49
+ const snappy = require_optional('snappy');
37
50
  if (!snappy) {
38
- snappy = {
51
+ return {
39
52
  compress: noSnappyWarning,
40
53
  uncompress: noSnappyWarning,
41
54
  compressSync: noSnappyWarning,
42
55
  uncompressSync: noSnappyWarning
43
56
  };
44
57
  }
58
+
59
+ const snappyPkg = require_optional('snappy/package.json') || { version: '0.0.0' };
60
+ const version = parsePackageVersion(snappyPkg);
61
+ snappy[PKG_VERSION] = version;
62
+ if (version.major >= 7) {
63
+ const compressOriginal = snappy.compress;
64
+ const uncompressOriginal = snappy.uncompress;
65
+ snappy.compress = (data, callback) => {
66
+ compressOriginal(data)
67
+ .then(res => callback(undefined, res))
68
+ .catch(error => callback(error));
69
+ };
70
+ snappy.uncompress = (data, callback) => {
71
+ uncompressOriginal(data)
72
+ .then(res => callback(undefined, res))
73
+ .catch(error => callback(error));
74
+ };
75
+ }
76
+
45
77
  return snappy;
46
78
  }
47
79
 
48
80
  module.exports = {
81
+ PKG_VERSION,
49
82
  debugOptions,
50
83
  retrieveBSON,
51
84
  retrieveSnappy
@@ -146,6 +146,13 @@ class CoreCursor extends Readable {
146
146
  this.cursorState.promoteBuffers = options.promoteBuffers;
147
147
  }
148
148
 
149
+ // Add bsonRegExp to cursor state
150
+ if (typeof topologyOptions.bsonRegExp === 'boolean') {
151
+ this.cursorState.bsonRegExp = topologyOptions.bsonRegExp;
152
+ } else if (typeof options.bsonRegExp === 'boolean') {
153
+ this.cursorState.bsonRegExp = options.bsonRegExp;
154
+ }
155
+
149
156
  if (topologyOptions.reconnect) {
150
157
  this.cursorState.reconnect = topologyOptions.reconnect;
151
158
  }
package/lib/core/index.js CHANGED
@@ -5,6 +5,7 @@ const require_optional = require('optional-require')(require);
5
5
  const EJSON = require('./utils').retrieveEJSON();
6
6
 
7
7
  try {
8
+ // Ensure you always wrap an optional require in the try block NODE-3199
8
9
  // Attempt to grab the native BSON parser
9
10
  const BSONNative = require_optional('bson-ext');
10
11
  // If we got the native parser, use it instead of the
@@ -85,7 +85,8 @@ class Monitor extends EventEmitter {
85
85
  raw: false,
86
86
  promoteLongs: true,
87
87
  promoteValues: true,
88
- promoteBuffers: true
88
+ promoteBuffers: true,
89
+ bsonRegExp: true
89
90
  }
90
91
  );
91
92
 
@@ -20,6 +20,7 @@ const isNodeShuttingDownError = require('../error').isNodeShuttingDownError;
20
20
  const isNetworkErrorBeforeHandshake = require('../error').isNetworkErrorBeforeHandshake;
21
21
  const maxWireVersion = require('../utils').maxWireVersion;
22
22
  const makeStateMachine = require('../utils').makeStateMachine;
23
+ const extractCommand = require('../../command_utils').extractCommand;
23
24
  const common = require('./common');
24
25
  const ServerType = common.ServerType;
25
26
  const isTransactionCommand = require('../transactions').isTransactionCommand;
@@ -49,6 +50,7 @@ const DEBUG_FIELDS = [
49
50
  'promoteLongs',
50
51
  'promoteValues',
51
52
  'promoteBuffers',
53
+ 'bsonRegExp',
52
54
  'servername'
53
55
  ];
54
56
 
@@ -166,6 +168,10 @@ class Server extends EventEmitter {
166
168
  return this.s.description;
167
169
  }
168
170
 
171
+ get supportsRetryableWrites() {
172
+ return supportsRetryableWrites(this);
173
+ }
174
+
169
175
  get name() {
170
176
  return this.s.description.address;
171
177
  }
@@ -261,10 +267,11 @@ class Server extends EventEmitter {
261
267
 
262
268
  // Debug log
263
269
  if (this.s.logger.isDebug()) {
270
+ const extractedCommand = extractCommand(cmd);
264
271
  this.s.logger.debug(
265
272
  `executing command [${JSON.stringify({
266
273
  ns,
267
- cmd,
274
+ cmd: extractedCommand.shouldRedact ? `${extractedCommand.name} details REDACTED` : cmd,
268
275
  options: debugOptions(DEBUG_FIELDS, options)
269
276
  })}] against ${this.name}`
270
277
  );
@@ -9,7 +9,6 @@ const events = require('./events');
9
9
  const Server = require('./server').Server;
10
10
  const relayEvents = require('../utils').relayEvents;
11
11
  const ReadPreference = require('../topologies/read_preference');
12
- const isRetryableWritesSupported = require('../topologies/shared').isRetryableWritesSupported;
13
12
  const CoreCursor = require('../cursor').CoreCursor;
14
13
  const deprecate = require('util').deprecate;
15
14
  const BSON = require('../connection/utils').retrieveBSON();
@@ -669,12 +668,17 @@ class Topology extends EventEmitter {
669
668
  return;
670
669
  }
671
670
 
671
+ const notAlreadyRetrying = !options.retrying;
672
+ const retryWrites = !!options.retryWrites;
673
+ const hasSession = !!options.session;
674
+ const supportsRetryableWrites = server.supportsRetryableWrites;
675
+ const notInTransaction = !hasSession || !options.session.inTransaction();
672
676
  const willRetryWrite =
673
- !options.retrying &&
674
- !!options.retryWrites &&
675
- options.session &&
676
- isRetryableWritesSupported(this) &&
677
- !options.session.inTransaction() &&
677
+ notAlreadyRetrying &&
678
+ retryWrites &&
679
+ hasSession &&
680
+ supportsRetryableWrites &&
681
+ notInTransaction &&
678
682
  isWriteCommand(cmd);
679
683
 
680
684
  const cb = (err, result) => {
@@ -738,8 +742,11 @@ class Topology extends EventEmitter {
738
742
  return this.s.state === STATE_CLOSED;
739
743
  }
740
744
 
745
+ /**
746
+ * @deprecated This function is deprecated and will be removed in the next major version.
747
+ */
741
748
  unref() {
742
- emitWarning('not implemented: `unref`');
749
+ emitWarning('`unref` is a noop and will be removed in the next major version');
743
750
  }
744
751
 
745
752
  // NOTE: There are many places in code where we explicitly check the last isMaster
@@ -925,20 +932,26 @@ function executeWriteOperation(args, options, callback) {
925
932
  const ns = args.ns;
926
933
  const ops = args.ops;
927
934
 
928
- const willRetryWrite =
929
- !args.retrying &&
930
- !!options.retryWrites &&
931
- options.session &&
932
- isRetryableWritesSupported(topology) &&
933
- !options.session.inTransaction() &&
934
- options.explain === undefined;
935
-
936
935
  topology.selectServer(writableServerSelector(), options, (err, server) => {
937
936
  if (err) {
938
937
  callback(err, null);
939
938
  return;
940
939
  }
941
940
 
941
+ const notAlreadyRetrying = !args.retrying;
942
+ const retryWrites = !!options.retryWrites;
943
+ const hasSession = !!options.session;
944
+ const supportsRetryableWrites = server.supportsRetryableWrites;
945
+ const notInTransaction = !hasSession || !options.session.inTransaction();
946
+ const notExplaining = options.explain === undefined;
947
+ const willRetryWrite =
948
+ notAlreadyRetrying &&
949
+ retryWrites &&
950
+ hasSession &&
951
+ supportsRetryableWrites &&
952
+ notInTransaction &&
953
+ notExplaining;
954
+
942
955
  const handler = (err, result) => {
943
956
  if (!err) return callback(null, result);
944
957
  if (!shouldRetryOperation(err)) {
@@ -88,6 +88,7 @@ var handlers = ['connect', 'close', 'error', 'timeout', 'parseError'];
88
88
  * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
89
89
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
90
90
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
91
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
91
92
  * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit.
92
93
  * @param {boolean} [options.monitorCommands=false] Enable command monitoring for this topology
93
94
  * @return {Mongos} A cursor instance
@@ -88,6 +88,7 @@ var handlers = ['connect', 'close', 'error', 'timeout', 'parseError'];
88
88
  * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
89
89
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
90
90
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
91
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
91
92
  * @param {number} [options.pingInterval=5000] Ping interval to check the response time to the different servers
92
93
  * @param {number} [options.localThresholdMS=15] Cutoff latency point in MS for Replicaset member selection
93
94
  * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit.
@@ -16,6 +16,7 @@ var inherits = require('util').inherits,
16
16
  createCompressionInfo = require('./shared').createCompressionInfo,
17
17
  resolveClusterTime = require('./shared').resolveClusterTime,
18
18
  SessionMixins = require('./shared').SessionMixins,
19
+ extractCommand = require('../../command_utils').extractCommand,
19
20
  relayEvents = require('../utils').relayEvents;
20
21
 
21
22
  const collationNotSupported = require('../utils').collationNotSupported;
@@ -46,6 +47,7 @@ var debugFields = [
46
47
  'promoteLongs',
47
48
  'promoteValues',
48
49
  'promoteBuffers',
50
+ 'bsonRegExp',
49
51
  'servername'
50
52
  ];
51
53
 
@@ -88,6 +90,7 @@ function topologyId(server) {
88
90
  * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
89
91
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
90
92
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
93
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
91
94
  * @param {string} [options.appname=null] Application name, passed in on ismaster call and logged in mongod server logs. Maximum size 128 bytes.
92
95
  * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit.
93
96
  * @param {boolean} [options.monitorCommands=false] Enable command monitoring for this topology
@@ -608,18 +611,20 @@ Server.prototype.command = function(ns, cmd, options, callback) {
608
611
  options = Object.assign({}, options, { wireProtocolCommand: false });
609
612
 
610
613
  // Debug log
611
- if (self.s.logger.isDebug())
614
+ if (self.s.logger.isDebug()) {
615
+ const extractedCommand = extractCommand(cmd);
612
616
  self.s.logger.debug(
613
617
  f(
614
618
  'executing command [%s] against %s',
615
619
  JSON.stringify({
616
620
  ns: ns,
617
- cmd: cmd,
621
+ cmd: extractedCommand.shouldRedact ? `${extractedCommand.name} details REDACTED` : cmd,
618
622
  options: debugOptions(debugFields, options)
619
623
  }),
620
624
  self.name
621
625
  )
622
626
  );
627
+ }
623
628
 
624
629
  // If we are not connected or have a disconnectHandler specified
625
630
  if (disconnectHandler(self, 'command', ns, cmd, options, callback)) return;
@@ -52,7 +52,9 @@ function parseSrvConnectionString(uri, options, callback) {
52
52
  }
53
53
 
54
54
  result.domainLength = result.hostname.split('.').length;
55
- if (result.pathname && result.pathname.match(',')) {
55
+
56
+ const hostname = uri.substring('mongodb+srv://'.length).split('/')[0];
57
+ if (hostname.match(',')) {
56
58
  return callback(new MongoParseError('Invalid URI, cannot contain multiple hostnames'));
57
59
  }
58
60
 
package/lib/core/utils.js CHANGED
@@ -27,6 +27,7 @@ function retrieveKerberos() {
27
27
  let kerberos;
28
28
 
29
29
  try {
30
+ // Ensure you always wrap an optional require in the try block NODE-3199
30
31
  kerberos = requireOptional('kerberos');
31
32
  } catch (err) {
32
33
  if (err.code === 'MODULE_NOT_FOUND') {
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  const MIN_SUPPORTED_SERVER_VERSION = '2.6';
4
- const MAX_SUPPORTED_SERVER_VERSION = '4.4';
4
+ const MAX_SUPPORTED_SERVER_VERSION = '5.0';
5
5
  const MIN_SUPPORTED_WIRE_VERSION = 2;
6
- const MAX_SUPPORTED_WIRE_VERSION = 9;
6
+ const MAX_SUPPORTED_WIRE_VERSION = 13;
7
7
 
8
8
  module.exports = {
9
9
  MIN_SUPPORTED_SERVER_VERSION,
@@ -57,6 +57,7 @@ function applyCommonQueryOptions(queryOptions, options) {
57
57
  promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true,
58
58
  promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true,
59
59
  promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false,
60
+ bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false,
60
61
  monitoring: typeof options.monitoring === 'boolean' ? options.monitoring : false,
61
62
  fullResult: typeof options.fullResult === 'boolean' ? options.fullResult : false
62
63
  });
package/lib/cursor.js CHANGED
@@ -742,7 +742,12 @@ class Cursor extends CoreCursor {
742
742
  return false;
743
743
  }
744
744
  if (doc != null) {
745
- iterator(doc);
745
+ try {
746
+ iterator(doc);
747
+ } catch (error) {
748
+ callback(error);
749
+ return false;
750
+ }
746
751
  return true;
747
752
  }
748
753
  if (doc == null && callback) {
@@ -762,7 +767,12 @@ class Cursor extends CoreCursor {
762
767
  fulfill(null);
763
768
  return false;
764
769
  } else {
765
- iterator(doc);
770
+ try {
771
+ iterator(doc);
772
+ } catch (error) {
773
+ reject(error);
774
+ return false;
775
+ }
766
776
  return true;
767
777
  }
768
778
  });
package/lib/db.js CHANGED
@@ -83,7 +83,6 @@ const legalOptionNames = [
83
83
  'bufferMaxEntries',
84
84
  'authSource',
85
85
  'ignoreUndefined',
86
- 'promoteLongs',
87
86
  'promiseLibrary',
88
87
  'readConcern',
89
88
  'retryMiliSeconds',
@@ -95,6 +94,7 @@ const legalOptionNames = [
95
94
  'promoteBuffers',
96
95
  'promoteLongs',
97
96
  'promoteValues',
97
+ 'bsonRegExp',
98
98
  'compression',
99
99
  'retryWrites'
100
100
  ];
@@ -117,6 +117,7 @@ const legalOptionNames = [
117
117
  * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
118
118
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
119
119
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
120
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
120
121
  * @param {number} [options.bufferMaxEntries=-1] Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited.
121
122
  * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
122
123
  * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys.
@@ -323,6 +324,7 @@ Db.prototype.command = function(command, options, callback) {
323
324
  * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
324
325
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
325
326
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
327
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
326
328
  * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
327
329
  * @param {string} [options.comment] Add a comment to an aggregation command
328
330
  * @param {string|object} [options.hint] Add an index selection hint to an aggregation command
@@ -391,7 +393,8 @@ const COLLECTION_OPTION_KEYS = [
391
393
  'ignoreUndefined',
392
394
  'promoteValues',
393
395
  'promoteBuffers',
394
- 'promoteLongs'
396
+ 'promoteLongs',
397
+ 'bsonRegExp'
395
398
  ];
396
399
 
397
400
  /**
@@ -409,91 +412,98 @@ const COLLECTION_OPTION_KEYS = [
409
412
  * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys.
410
413
  * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
411
414
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
412
- * @param {boolean} [options.strict=false] Returns an error if the collection does not exist
415
+ * @param {boolean} [options.strict=false] **Deprecated** Returns an error if the collection does not exist
413
416
  * @param {object} [options.readConcern] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
414
417
  * @param {ReadConcernLevel} [options.readConcern.level='local'] Specify a read concern level for the collection operations (only MongoDB 3.2 or higher supported)
415
418
  * @param {Db~collectionResultCallback} [callback] The collection result callback
416
419
  * @return {Collection} return the new Collection instance if not in strict mode
417
420
  */
418
- Db.prototype.collection = function(name, options, callback) {
419
- if (typeof options === 'function') (callback = options), (options = {});
420
- options = options || {};
421
- options = Object.assign({}, options);
422
-
423
- // Set the promise library
424
- options.promiseLibrary = this.s.promiseLibrary;
421
+ Db.prototype.collection = deprecateOptions(
422
+ {
423
+ name: 'Db.collection',
424
+ deprecatedOptions: ['strict'],
425
+ optionsIndex: 1
426
+ },
427
+ function(name, options, callback) {
428
+ if (typeof options === 'function') (callback = options), (options = {});
429
+ options = options || {};
430
+ options = Object.assign({}, options);
425
431
 
426
- // If we have not set a collection level readConcern set the db level one
427
- options.readConcern = options.readConcern
428
- ? new ReadConcern(options.readConcern.level)
429
- : this.readConcern;
432
+ // Set the promise library
433
+ options.promiseLibrary = this.s.promiseLibrary;
430
434
 
431
- // Do we have ignoreUndefined set
432
- if (this.s.options.ignoreUndefined) {
433
- options.ignoreUndefined = this.s.options.ignoreUndefined;
434
- }
435
+ // If we have not set a collection level readConcern set the db level one
436
+ options.readConcern = options.readConcern
437
+ ? new ReadConcern(options.readConcern.level)
438
+ : this.readConcern;
435
439
 
436
- for (const collectionOptionKey of COLLECTION_OPTION_KEYS) {
437
- if (!(collectionOptionKey in options) && this.s.options[collectionOptionKey] !== undefined) {
438
- options[collectionOptionKey] = this.s.options[collectionOptionKey];
440
+ // Do we have ignoreUndefined set
441
+ if (this.s.options.ignoreUndefined) {
442
+ options.ignoreUndefined = this.s.options.ignoreUndefined;
439
443
  }
440
- }
441
444
 
442
- // Merge in all needed options and ensure correct writeConcern merging from db level
443
- options = conditionallyMergeWriteConcern(options, this.s.options);
444
-
445
- // Execute
446
- if (options == null || !options.strict) {
447
- try {
448
- const collection = new Collection(
449
- this,
450
- this.s.topology,
451
- this.databaseName,
452
- name,
453
- this.s.pkFactory,
454
- options
455
- );
456
- if (callback) callback(null, collection);
457
- return collection;
458
- } catch (err) {
459
- if (err instanceof MongoError && callback) return callback(err);
460
- throw err;
445
+ for (const collectionOptionKey of COLLECTION_OPTION_KEYS) {
446
+ if (!(collectionOptionKey in options) && this.s.options[collectionOptionKey] !== undefined) {
447
+ options[collectionOptionKey] = this.s.options[collectionOptionKey];
448
+ }
461
449
  }
462
- }
463
450
 
464
- // Strict mode
465
- if (typeof callback !== 'function') {
466
- throw toError(`A callback is required in strict mode. While getting collection ${name}`);
467
- }
451
+ // Merge in all needed options and ensure correct writeConcern merging from db level
452
+ options = conditionallyMergeWriteConcern(options, this.s.options);
453
+
454
+ // Execute
455
+ if (options == null || !options.strict) {
456
+ try {
457
+ const collection = new Collection(
458
+ this,
459
+ this.s.topology,
460
+ this.databaseName,
461
+ name,
462
+ this.s.pkFactory,
463
+ options
464
+ );
465
+ if (callback) callback(null, collection);
466
+ return collection;
467
+ } catch (err) {
468
+ if (err instanceof MongoError && callback) return callback(err);
469
+ throw err;
470
+ }
471
+ }
468
472
 
469
- // Did the user destroy the topology
470
- if (this.serverConfig && this.serverConfig.isDestroyed()) {
471
- return callback(new MongoError('topology was destroyed'));
472
- }
473
+ // Strict mode
474
+ if (typeof callback !== 'function') {
475
+ throw toError(`A callback is required in strict mode. While getting collection ${name}`);
476
+ }
473
477
 
474
- const listCollectionOptions = Object.assign({}, options, { nameOnly: true });
475
-
476
- // Strict mode
477
- this.listCollections({ name: name }, listCollectionOptions).toArray((err, collections) => {
478
- if (err != null) return handleCallback(callback, err, null);
479
- if (collections.length === 0)
480
- return handleCallback(
481
- callback,
482
- toError(`Collection ${name} does not exist. Currently in strict mode.`),
483
- null
484
- );
485
-
486
- try {
487
- return handleCallback(
488
- callback,
489
- null,
490
- new Collection(this, this.s.topology, this.databaseName, name, this.s.pkFactory, options)
491
- );
492
- } catch (err) {
493
- return handleCallback(callback, err, null);
478
+ // Did the user destroy the topology
479
+ if (this.serverConfig && this.serverConfig.isDestroyed()) {
480
+ return callback(new MongoError('topology was destroyed'));
494
481
  }
495
- });
496
- };
482
+
483
+ const listCollectionOptions = Object.assign({}, options, { nameOnly: true });
484
+
485
+ // Strict mode
486
+ this.listCollections({ name: name }, listCollectionOptions).toArray((err, collections) => {
487
+ if (err != null) return handleCallback(callback, err, null);
488
+ if (collections.length === 0)
489
+ return handleCallback(
490
+ callback,
491
+ toError(`Collection ${name} does not exist. Currently in strict mode.`),
492
+ null
493
+ );
494
+
495
+ try {
496
+ return handleCallback(
497
+ callback,
498
+ null,
499
+ new Collection(this, this.s.topology, this.databaseName, name, this.s.pkFactory, options)
500
+ );
501
+ } catch (err) {
502
+ return handleCallback(callback, err, null);
503
+ }
504
+ });
505
+ }
506
+ );
497
507
 
498
508
  /**
499
509
  * Create a new collection on a server with the specified options. Use this to create capped collections.
@@ -941,6 +951,7 @@ Db.prototype.indexInformation = function(name, options, callback) {
941
951
  /**
942
952
  * Unref all sockets
943
953
  * @method
954
+ * @deprecated This function is deprecated and will be removed in the next major version.
944
955
  */
945
956
  Db.prototype.unref = function() {
946
957
  this.s.topology.unref();