mongodb 3.6.7 → 3.6.11
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 +34 -0
- package/README.md +4 -4
- package/lib/bulk/common.js +34 -12
- package/lib/cmap/connection.js +2 -1
- package/lib/collection.js +9 -0
- package/lib/command_utils.js +124 -0
- package/lib/core/auth/mongodb_aws.js +1 -0
- package/lib/core/auth/scram.js +1 -0
- package/lib/core/connection/apm.js +10 -123
- package/lib/core/connection/commands.js +11 -2
- package/lib/core/connection/connect.js +3 -0
- package/lib/core/connection/connection.js +6 -3
- package/lib/core/connection/msg.js +11 -2
- package/lib/core/connection/pool.js +6 -2
- package/lib/core/cursor.js +7 -0
- package/lib/core/error.js +2 -2
- package/lib/core/index.js +1 -0
- package/lib/core/sdam/monitor.js +2 -1
- package/lib/core/sdam/server.js +8 -1
- package/lib/core/sdam/topology.js +24 -14
- package/lib/core/topologies/mongos.js +1 -0
- package/lib/core/topologies/replset.js +1 -0
- package/lib/core/topologies/server.js +7 -2
- package/lib/core/uri_parser.js +3 -1
- package/lib/core/utils.js +1 -0
- package/lib/core/wireprotocol/constants.js +2 -2
- package/lib/core/wireprotocol/shared.js +1 -0
- package/lib/cursor.js +12 -2
- package/lib/db.js +82 -72
- package/lib/encrypter.js +8 -3
- package/lib/mongo_client.js +1 -0
- package/lib/operations/bulk_write.js +0 -17
- package/lib/operations/command.js +4 -1
- package/lib/operations/command_v2.js +7 -1
- package/lib/operations/connect.js +1 -0
- package/lib/operations/db_ops.js +6 -2
- package/lib/topologies/mongos.js +1 -0
- package/lib/topologies/replset.js +1 -0
- package/lib/topologies/server.js +1 -0
- package/lib/url_parser.js +2 -1
- package/lib/utils.js +78 -1
- package/package.json +6 -2
|
@@ -139,7 +139,12 @@ Msg.getRequestId = function() {
|
|
|
139
139
|
|
|
140
140
|
class BinMsg {
|
|
141
141
|
constructor(bson, message, msgHeader, msgBody, opts) {
|
|
142
|
-
opts = opts || {
|
|
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.
|
|
395
|
+
'message [ %s ] received from %s:%s',
|
|
396
|
+
message.raw.length,
|
|
395
397
|
self.options.host,
|
|
396
398
|
self.options.port
|
|
397
399
|
)
|
|
@@ -870,6 +872,7 @@ Pool.prototype.write = function(command, options, cb) {
|
|
|
870
872
|
promoteLongs: true,
|
|
871
873
|
promoteValues: true,
|
|
872
874
|
promoteBuffers: false,
|
|
875
|
+
bsonRegExp: false,
|
|
873
876
|
fullResult: false
|
|
874
877
|
};
|
|
875
878
|
|
|
@@ -879,6 +882,7 @@ Pool.prototype.write = function(command, options, cb) {
|
|
|
879
882
|
typeof options.promoteValues === 'boolean' ? options.promoteValues : true;
|
|
880
883
|
operation.promoteBuffers =
|
|
881
884
|
typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false;
|
|
885
|
+
operation.bsonRegExp = typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false;
|
|
882
886
|
operation.raw = typeof options.raw === 'boolean' ? options.raw : false;
|
|
883
887
|
operation.immediateRelease =
|
|
884
888
|
typeof options.immediateRelease === 'boolean' ? options.immediateRelease : false;
|
package/lib/core/cursor.js
CHANGED
|
@@ -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/error.js
CHANGED
|
@@ -102,8 +102,8 @@ class MongoNetworkError extends MongoError {
|
|
|
102
102
|
super(message);
|
|
103
103
|
this.name = 'MongoNetworkError';
|
|
104
104
|
|
|
105
|
-
if (options && options.beforeHandshake ===
|
|
106
|
-
this[kBeforeHandshake] =
|
|
105
|
+
if (options && typeof options.beforeHandshake === 'boolean') {
|
|
106
|
+
this[kBeforeHandshake] = options.beforeHandshake;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
}
|
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
|
package/lib/core/sdam/monitor.js
CHANGED
package/lib/core/sdam/server.js
CHANGED
|
@@ -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
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
677
|
+
notAlreadyRetrying &&
|
|
678
|
+
retryWrites &&
|
|
679
|
+
hasSession &&
|
|
680
|
+
supportsRetryableWrites &&
|
|
681
|
+
notInTransaction &&
|
|
678
682
|
isWriteCommand(cmd);
|
|
679
683
|
|
|
680
684
|
const cb = (err, result) => {
|
|
@@ -925,20 +929,26 @@ function executeWriteOperation(args, options, callback) {
|
|
|
925
929
|
const ns = args.ns;
|
|
926
930
|
const ops = args.ops;
|
|
927
931
|
|
|
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
932
|
topology.selectServer(writableServerSelector(), options, (err, server) => {
|
|
937
933
|
if (err) {
|
|
938
934
|
callback(err, null);
|
|
939
935
|
return;
|
|
940
936
|
}
|
|
941
937
|
|
|
938
|
+
const notAlreadyRetrying = !args.retrying;
|
|
939
|
+
const retryWrites = !!options.retryWrites;
|
|
940
|
+
const hasSession = !!options.session;
|
|
941
|
+
const supportsRetryableWrites = server.supportsRetryableWrites;
|
|
942
|
+
const notInTransaction = !hasSession || !options.session.inTransaction();
|
|
943
|
+
const notExplaining = options.explain === undefined;
|
|
944
|
+
const willRetryWrite =
|
|
945
|
+
notAlreadyRetrying &&
|
|
946
|
+
retryWrites &&
|
|
947
|
+
hasSession &&
|
|
948
|
+
supportsRetryableWrites &&
|
|
949
|
+
notInTransaction &&
|
|
950
|
+
notExplaining;
|
|
951
|
+
|
|
942
952
|
const handler = (err, result) => {
|
|
943
953
|
if (!err) return callback(null, result);
|
|
944
954
|
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;
|
package/lib/core/uri_parser.js
CHANGED
|
@@ -52,7 +52,9 @@ function parseSrvConnectionString(uri, options, callback) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
result.domainLength = result.hostname.split('.').length;
|
|
55
|
-
|
|
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
|
@@ -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
|
+
const MAX_SUPPORTED_SERVER_VERSION = '5.0';
|
|
5
5
|
const MIN_SUPPORTED_WIRE_VERSION = 2;
|
|
6
|
-
const MAX_SUPPORTED_WIRE_VERSION =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
options
|
|
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
|
-
|
|
427
|
-
|
|
428
|
-
? new ReadConcern(options.readConcern.level)
|
|
429
|
-
: this.readConcern;
|
|
432
|
+
// Set the promise library
|
|
433
|
+
options.promiseLibrary = this.s.promiseLibrary;
|
|
430
434
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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
|
-
|
|
437
|
-
if (
|
|
438
|
-
options
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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.
|
package/lib/encrypter.js
CHANGED
|
@@ -3,8 +3,10 @@ const MongoClient = require('./mongo_client');
|
|
|
3
3
|
const BSON = require('./core/connection/utils').retrieveBSON();
|
|
4
4
|
const MongoError = require('./core/error').MongoError;
|
|
5
5
|
|
|
6
|
+
let mongodbClientEncryption = undefined;
|
|
6
7
|
try {
|
|
7
|
-
require
|
|
8
|
+
// Ensure you always wrap an optional require in the try block NODE-3199
|
|
9
|
+
mongodbClientEncryption = require('mongodb-client-encryption');
|
|
8
10
|
} catch (err) {
|
|
9
11
|
throw new MongoError(
|
|
10
12
|
'Auto-encryption requested, but the module is not installed. ' +
|
|
@@ -12,13 +14,16 @@ try {
|
|
|
12
14
|
);
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
if (
|
|
18
|
+
mongodbClientEncryption === undefined ||
|
|
19
|
+
typeof mongodbClientEncryption.extension !== 'function'
|
|
20
|
+
) {
|
|
17
21
|
throw new MongoError(
|
|
18
22
|
'loaded version of `mongodb-client-encryption` does not have property `extension`. ' +
|
|
19
23
|
'Please make sure you are loading the correct version of `mongodb-client-encryption`'
|
|
20
24
|
);
|
|
21
25
|
}
|
|
26
|
+
|
|
22
27
|
const AutoEncrypter = mongodbClientEncryption.extension(require('../index')).AutoEncrypter;
|
|
23
28
|
|
|
24
29
|
const kInternalClient = Symbol('internalClient');
|
package/lib/mongo_client.js
CHANGED
|
@@ -144,6 +144,7 @@ const validOptions = require('./operations/connect').validOptions;
|
|
|
144
144
|
* @property {boolean} [promoteValues] (**default**: true) Promotes BSON values to native types where possible, set to false to only receive wrapper types
|
|
145
145
|
* @property {boolean} [promoteBuffers] (**default**: false) Promotes Binary BSON values to native Node Buffers
|
|
146
146
|
* @property {boolean} [promoteLongs] (**default**: true) Promotes long values to number if they fit inside the 53 bits resolution
|
|
147
|
+
* * @param {boolean} [bsonRegExp] (**default**: 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.
|
|
147
148
|
* @property {boolean} [domainsEnabled] (**default**: false) Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit
|
|
148
149
|
* @property {object} [validateOptions] (**default**: false) Validate MongoClient passed in options for correctness
|
|
149
150
|
* @property {string} [appname] (**default**: 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
|
|
@@ -70,23 +70,6 @@ class BulkWriteOperation extends OperationBase {
|
|
|
70
70
|
return callback(err, null);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
// Update the n
|
|
74
|
-
r.n = r.insertedCount;
|
|
75
|
-
|
|
76
|
-
// Inserted documents
|
|
77
|
-
const inserted = r.getInsertedIds();
|
|
78
|
-
// Map inserted ids
|
|
79
|
-
for (let i = 0; i < inserted.length; i++) {
|
|
80
|
-
r.insertedIds[inserted[i].index] = inserted[i]._id;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Upserted documents
|
|
84
|
-
const upserted = r.getUpsertedIds();
|
|
85
|
-
// Map upserted ids
|
|
86
|
-
for (let i = 0; i < upserted.length; i++) {
|
|
87
|
-
r.upsertedIds[upserted[i].index] = upserted[i]._id;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
73
|
// Return the results
|
|
91
74
|
callback(null, r);
|
|
92
75
|
});
|