mongodb 3.6.4 → 3.6.8
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 +43 -0
- package/README.md +63 -67
- package/lib/bulk/common.js +76 -0
- package/lib/cmap/connection.js +36 -32
- package/lib/collection.js +50 -34
- package/lib/core/auth/mongo_credentials.js +5 -5
- package/lib/core/auth/scram.js +2 -1
- package/lib/core/connection/connect.js +1 -1
- package/lib/core/connection/logger.js +1 -0
- package/lib/core/connection/msg.js +3 -1
- package/lib/core/connection/utils.js +9 -14
- package/lib/core/error.js +2 -2
- package/lib/core/index.js +1 -1
- package/lib/core/sdam/monitor.js +8 -3
- package/lib/core/sdam/topology.js +2 -2
- package/lib/core/sdam/topology_description.js +24 -6
- package/lib/core/tools/smoke_plugin.js +1 -0
- package/lib/core/topologies/read_preference.js +2 -1
- package/lib/core/topologies/replset.js +1 -1
- package/lib/core/uri_parser.js +2 -1
- package/lib/core/utils.js +2 -5
- package/lib/core/wireprotocol/command.js +10 -5
- package/lib/core/wireprotocol/kill_cursors.js +2 -1
- package/lib/db.js +9 -3
- package/lib/encrypter.js +163 -0
- package/lib/gridfs-stream/upload.js +1 -0
- package/lib/mongo_client.js +123 -172
- package/lib/operations/add_user.js +2 -1
- package/lib/operations/bulk_write.js +0 -8
- package/lib/operations/connect.js +14 -61
- package/lib/operations/execute_operation.js +47 -69
- package/lib/operations/find.js +3 -0
- package/lib/operations/find_one_and_replace.js +8 -2
- package/lib/operations/find_one_and_update.js +8 -3
- package/lib/operations/insert_many.js +1 -5
- package/lib/operations/operation.js +1 -1
- package/lib/utils.js +88 -30
- package/lib/write_concern.js +5 -1
- package/package.json +22 -22
|
@@ -13,9 +13,9 @@ const ReplSet = require('../topologies/replset');
|
|
|
13
13
|
const Server = require('../topologies/server');
|
|
14
14
|
const ServerSessionPool = require('../core').Sessions.ServerSessionPool;
|
|
15
15
|
const emitDeprecationWarning = require('../utils').emitDeprecationWarning;
|
|
16
|
+
const emitWarningOnce = require('../utils').emitWarningOnce;
|
|
16
17
|
const fs = require('fs');
|
|
17
18
|
const WriteConcern = require('../write_concern');
|
|
18
|
-
const BSON = require('../core/connection/utils').retrieveBSON();
|
|
19
19
|
const CMAP_EVENT_NAMES = require('../cmap/events').CMAP_EVENT_NAMES;
|
|
20
20
|
|
|
21
21
|
let client;
|
|
@@ -182,12 +182,12 @@ function validOptions(options) {
|
|
|
182
182
|
if (options.validateOptions) {
|
|
183
183
|
return new MongoError(`option ${name} is not supported`);
|
|
184
184
|
} else {
|
|
185
|
-
|
|
185
|
+
emitWarningOnce(`the options [${name}] is not supported`);
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
if (legacyOptionNames.indexOf(name) !== -1) {
|
|
190
|
-
|
|
190
|
+
emitWarningOnce(
|
|
191
191
|
`the server/replset/mongos/db options are deprecated, ` +
|
|
192
192
|
`all their options are supported at the top level of the options object [${validOptionNames}]`
|
|
193
193
|
);
|
|
@@ -257,9 +257,6 @@ function resolveTLSOptions(options) {
|
|
|
257
257
|
});
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
const emitDeprecationForNonUnifiedTopology = deprecate(() => {},
|
|
261
|
-
'current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. ' + 'To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.');
|
|
262
|
-
|
|
263
260
|
function connect(mongoClient, url, options, callback) {
|
|
264
261
|
options = Object.assign({}, options);
|
|
265
262
|
|
|
@@ -335,7 +332,9 @@ function connect(mongoClient, url, options, callback) {
|
|
|
335
332
|
return createTopology(mongoClient, 'unified', _finalOptions, connectCallback);
|
|
336
333
|
}
|
|
337
334
|
|
|
338
|
-
|
|
335
|
+
emitWarningOnce(
|
|
336
|
+
'Current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.'
|
|
337
|
+
);
|
|
339
338
|
|
|
340
339
|
// Do we have a replicaset then skip discovery and go straight to connectivity
|
|
341
340
|
if (_finalOptions.replicaSet || _finalOptions.rs_name) {
|
|
@@ -496,58 +495,9 @@ function createTopology(mongoClient, topologyType, options, callback) {
|
|
|
496
495
|
|
|
497
496
|
// determine CSFLE support
|
|
498
497
|
if (options.autoEncryption != null) {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
} catch (err) {
|
|
503
|
-
callback(
|
|
504
|
-
new MongoError(
|
|
505
|
-
'Auto-encryption requested, but the module is not installed. Please add `mongodb-client-encryption` as a dependency of your project'
|
|
506
|
-
)
|
|
507
|
-
);
|
|
508
|
-
return;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
try {
|
|
512
|
-
let mongodbClientEncryption = require('mongodb-client-encryption');
|
|
513
|
-
if (typeof mongodbClientEncryption.extension !== 'function') {
|
|
514
|
-
callback(
|
|
515
|
-
new MongoError(
|
|
516
|
-
'loaded version of `mongodb-client-encryption` does not have property `extension`. Please make sure you are loading the correct version of `mongodb-client-encryption`'
|
|
517
|
-
)
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
AutoEncrypter = mongodbClientEncryption.extension(require('../../index')).AutoEncrypter;
|
|
521
|
-
} catch (err) {
|
|
522
|
-
callback(err);
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
const mongoCryptOptions = Object.assign(
|
|
527
|
-
{
|
|
528
|
-
bson:
|
|
529
|
-
options.bson ||
|
|
530
|
-
new BSON([
|
|
531
|
-
BSON.Binary,
|
|
532
|
-
BSON.Code,
|
|
533
|
-
BSON.DBRef,
|
|
534
|
-
BSON.Decimal128,
|
|
535
|
-
BSON.Double,
|
|
536
|
-
BSON.Int32,
|
|
537
|
-
BSON.Long,
|
|
538
|
-
BSON.Map,
|
|
539
|
-
BSON.MaxKey,
|
|
540
|
-
BSON.MinKey,
|
|
541
|
-
BSON.ObjectId,
|
|
542
|
-
BSON.BSONRegExp,
|
|
543
|
-
BSON.Symbol,
|
|
544
|
-
BSON.Timestamp
|
|
545
|
-
])
|
|
546
|
-
},
|
|
547
|
-
options.autoEncryption
|
|
548
|
-
);
|
|
549
|
-
|
|
550
|
-
options.autoEncrypter = new AutoEncrypter(mongoClient, mongoCryptOptions);
|
|
498
|
+
const Encrypter = require('../encrypter').Encrypter;
|
|
499
|
+
options.encrypter = new Encrypter(mongoClient, options);
|
|
500
|
+
options.autoEncrypter = options.encrypter.autoEncrypter;
|
|
551
501
|
}
|
|
552
502
|
|
|
553
503
|
// Create the topology
|
|
@@ -585,7 +535,10 @@ function createTopology(mongoClient, topologyType, options, callback) {
|
|
|
585
535
|
return;
|
|
586
536
|
}
|
|
587
537
|
|
|
588
|
-
|
|
538
|
+
options.encrypter.connectInternalClient(error => {
|
|
539
|
+
if (error) return callback(error);
|
|
540
|
+
callback(undefined, topology);
|
|
541
|
+
});
|
|
589
542
|
});
|
|
590
543
|
});
|
|
591
544
|
|
|
@@ -616,7 +569,7 @@ function createUnifiedOptions(finalOptions, options) {
|
|
|
616
569
|
'mongos_options'
|
|
617
570
|
];
|
|
618
571
|
const noMerge = ['readconcern', 'compression', 'autoencryption'];
|
|
619
|
-
const skip = ['w', 'wtimeout', 'j', 'journal', 'fsync', '
|
|
572
|
+
const skip = ['w', 'wtimeout', 'j', 'journal', 'fsync', 'writeconcern'];
|
|
620
573
|
|
|
621
574
|
for (const name in options) {
|
|
622
575
|
if (skip.indexOf(name.toLowerCase()) !== -1) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const maybePromise = require('../utils').maybePromise;
|
|
3
4
|
const MongoError = require('../core/error').MongoError;
|
|
4
5
|
const Aspect = require('./operation').Aspect;
|
|
5
6
|
const OperationBase = require('./operation').OperationBase;
|
|
@@ -21,7 +22,7 @@ const isUnifiedTopology = require('../core/utils').isUnifiedTopology;
|
|
|
21
22
|
* @param {Operation} operation The operation to execute
|
|
22
23
|
* @param {function} callback The command result callback
|
|
23
24
|
*/
|
|
24
|
-
function executeOperation(topology, operation,
|
|
25
|
+
function executeOperation(topology, operation, cb) {
|
|
25
26
|
if (topology == null) {
|
|
26
27
|
throw new TypeError('This method requires a valid topology instance');
|
|
27
28
|
}
|
|
@@ -30,64 +31,57 @@ function executeOperation(topology, operation, callback) {
|
|
|
30
31
|
throw new TypeError('This method requires a valid operation instance');
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const Promise = topology.s.promiseLibrary;
|
|
38
|
-
|
|
39
|
-
// The driver sessions spec mandates that we implicitly create sessions for operations
|
|
40
|
-
// that are not explicitly provided with a session.
|
|
41
|
-
let session, owner;
|
|
42
|
-
if (topology.hasSessionSupport()) {
|
|
43
|
-
if (operation.session == null) {
|
|
44
|
-
owner = Symbol();
|
|
45
|
-
session = topology.startSession({ owner });
|
|
46
|
-
operation.session = session;
|
|
47
|
-
} else if (operation.session.hasEnded) {
|
|
48
|
-
throw new MongoError('Use of expired sessions is not permitted');
|
|
34
|
+
return maybePromise(topology, cb, callback => {
|
|
35
|
+
if (isUnifiedTopology(topology) && topology.shouldCheckForSessionSupport()) {
|
|
36
|
+
// Recursive call to executeOperation after a server selection
|
|
37
|
+
return selectServerForSessionSupport(topology, operation, callback);
|
|
49
38
|
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let result;
|
|
53
|
-
if (typeof callback !== 'function') {
|
|
54
|
-
result = new Promise((resolve, reject) => {
|
|
55
|
-
callback = (err, res) => {
|
|
56
|
-
if (err) return reject(err);
|
|
57
|
-
resolve(res);
|
|
58
|
-
};
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
39
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
40
|
+
// The driver sessions spec mandates that we implicitly create sessions for operations
|
|
41
|
+
// that are not explicitly provided with a session.
|
|
42
|
+
let session, owner;
|
|
43
|
+
if (topology.hasSessionSupport()) {
|
|
44
|
+
if (operation.session == null) {
|
|
45
|
+
owner = Symbol();
|
|
46
|
+
session = topology.startSession({ owner });
|
|
47
|
+
operation.session = session;
|
|
48
|
+
} else if (operation.session.hasEnded) {
|
|
49
|
+
return callback(new MongoError('Use of expired sessions is not permitted'));
|
|
67
50
|
}
|
|
51
|
+
} else if (operation.session) {
|
|
52
|
+
// If the user passed an explicit session and we are still, after server selection,
|
|
53
|
+
// trying to run against a topology that doesn't support sessions we error out.
|
|
54
|
+
return callback(new MongoError('Current topology does not support sessions'));
|
|
68
55
|
}
|
|
69
56
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
} else {
|
|
77
|
-
operation.execute(executeCallback);
|
|
78
|
-
}
|
|
79
|
-
} catch (e) {
|
|
80
|
-
if (session && session.owner === owner) {
|
|
81
|
-
session.endSession();
|
|
82
|
-
if (operation.session === session) {
|
|
83
|
-
operation.clearSession();
|
|
57
|
+
function executeCallback(err, result) {
|
|
58
|
+
if (session && session.owner === owner) {
|
|
59
|
+
session.endSession();
|
|
60
|
+
if (operation.session === session) {
|
|
61
|
+
operation.clearSession();
|
|
62
|
+
}
|
|
84
63
|
}
|
|
64
|
+
|
|
65
|
+
callback(err, result);
|
|
85
66
|
}
|
|
86
67
|
|
|
87
|
-
|
|
88
|
-
|
|
68
|
+
try {
|
|
69
|
+
if (operation.hasAspect(Aspect.EXECUTE_WITH_SELECTION)) {
|
|
70
|
+
executeWithServerSelection(topology, operation, executeCallback);
|
|
71
|
+
} else {
|
|
72
|
+
operation.execute(executeCallback);
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (session && session.owner === owner) {
|
|
76
|
+
session.endSession();
|
|
77
|
+
if (operation.session === session) {
|
|
78
|
+
operation.clearSession();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
89
81
|
|
|
90
|
-
|
|
82
|
+
callback(error);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
91
85
|
}
|
|
92
86
|
|
|
93
87
|
function supportsRetryableReads(server) {
|
|
@@ -139,7 +133,6 @@ function executeWithServerSelection(topology, operation, callback) {
|
|
|
139
133
|
callback(err, null);
|
|
140
134
|
return;
|
|
141
135
|
}
|
|
142
|
-
|
|
143
136
|
const shouldRetryReads =
|
|
144
137
|
topology.s.options.retryReads !== false &&
|
|
145
138
|
operation.session &&
|
|
@@ -156,31 +149,16 @@ function executeWithServerSelection(topology, operation, callback) {
|
|
|
156
149
|
});
|
|
157
150
|
}
|
|
158
151
|
|
|
159
|
-
//
|
|
160
|
-
//
|
|
152
|
+
// The Unified Topology runs serverSelection before executing every operation
|
|
153
|
+
// Session support is determined by the result of a monitoring check triggered by this selection
|
|
161
154
|
function selectServerForSessionSupport(topology, operation, callback) {
|
|
162
|
-
const Promise = topology.s.promiseLibrary;
|
|
163
|
-
|
|
164
|
-
let result;
|
|
165
|
-
if (typeof callback !== 'function') {
|
|
166
|
-
result = new Promise((resolve, reject) => {
|
|
167
|
-
callback = (err, result) => {
|
|
168
|
-
if (err) return reject(err);
|
|
169
|
-
resolve(result);
|
|
170
|
-
};
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
155
|
topology.selectServer(ReadPreference.primaryPreferred, err => {
|
|
175
156
|
if (err) {
|
|
176
|
-
callback(err);
|
|
177
|
-
return;
|
|
157
|
+
return callback(err);
|
|
178
158
|
}
|
|
179
159
|
|
|
180
160
|
executeOperation(topology, operation, callback);
|
|
181
161
|
});
|
|
182
|
-
|
|
183
|
-
return result;
|
|
184
162
|
}
|
|
185
163
|
|
|
186
164
|
module.exports = executeOperation;
|
package/lib/operations/find.js
CHANGED
|
@@ -20,6 +20,9 @@ class FindOperation extends OperationBase {
|
|
|
20
20
|
// copied from `CommandOperationV2`, to be subclassed in the future
|
|
21
21
|
this.server = server;
|
|
22
22
|
|
|
23
|
+
// updates readPreference if setReadPreference was called on the cursor
|
|
24
|
+
this.readPreference = ReadPreference.resolve(this, this.options);
|
|
25
|
+
|
|
23
26
|
if (typeof this.cmd.allowDiskUse !== 'undefined' && maxWireVersion(server) < 4) {
|
|
24
27
|
callback(new MongoError('The `allowDiskUse` option is not supported on MongoDB < 3.2'));
|
|
25
28
|
return;
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const MongoError = require('../core').MongoError;
|
|
3
4
|
const FindAndModifyOperation = require('./find_and_modify');
|
|
4
5
|
const hasAtomicOperators = require('../utils').hasAtomicOperators;
|
|
5
6
|
|
|
6
7
|
class FindOneAndReplaceOperation extends FindAndModifyOperation {
|
|
7
8
|
constructor(collection, filter, replacement, options) {
|
|
9
|
+
if ('returnDocument' in options && 'returnOriginal' in options) {
|
|
10
|
+
throw new MongoError(
|
|
11
|
+
'findOneAndReplace option returnOriginal is deprecated in favor of returnDocument and cannot be combined'
|
|
12
|
+
);
|
|
13
|
+
}
|
|
8
14
|
// Final options
|
|
9
15
|
const finalOptions = Object.assign({}, options);
|
|
10
16
|
finalOptions.fields = options.projection;
|
|
11
17
|
finalOptions.update = true;
|
|
12
|
-
finalOptions.new = options.
|
|
13
|
-
finalOptions.upsert = options.upsert
|
|
18
|
+
finalOptions.new = options.returnDocument === 'after' || options.returnOriginal === false;
|
|
19
|
+
finalOptions.upsert = options.upsert === true;
|
|
14
20
|
|
|
15
21
|
if (filter == null || typeof filter !== 'object') {
|
|
16
22
|
throw new TypeError('Filter parameter must be an object');
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const MongoError = require('../core').MongoError;
|
|
3
4
|
const FindAndModifyOperation = require('./find_and_modify');
|
|
4
5
|
const hasAtomicOperators = require('../utils').hasAtomicOperators;
|
|
5
6
|
|
|
6
7
|
class FindOneAndUpdateOperation extends FindAndModifyOperation {
|
|
7
8
|
constructor(collection, filter, update, options) {
|
|
9
|
+
if ('returnDocument' in options && 'returnOriginal' in options) {
|
|
10
|
+
throw new MongoError(
|
|
11
|
+
'findOneAndUpdate option returnOriginal is deprecated in favor of returnDocument and cannot be combined'
|
|
12
|
+
);
|
|
13
|
+
}
|
|
8
14
|
// Final options
|
|
9
15
|
const finalOptions = Object.assign({}, options);
|
|
10
16
|
finalOptions.fields = options.projection;
|
|
11
17
|
finalOptions.update = true;
|
|
12
|
-
finalOptions.new =
|
|
13
|
-
|
|
14
|
-
finalOptions.upsert = typeof options.upsert === 'boolean' ? options.upsert : false;
|
|
18
|
+
finalOptions.new = options.returnDocument === 'after' || options.returnOriginal === false;
|
|
19
|
+
finalOptions.upsert = options.upsert === true;
|
|
15
20
|
|
|
16
21
|
if (filter == null || typeof filter !== 'object') {
|
|
17
22
|
throw new TypeError('Filter parameter must be an object');
|
|
@@ -30,11 +30,7 @@ class InsertManyOperation extends OperationBase {
|
|
|
30
30
|
docs = prepareDocs(coll, docs, options);
|
|
31
31
|
|
|
32
32
|
// Generate the bulk write operations
|
|
33
|
-
const operations =
|
|
34
|
-
{
|
|
35
|
-
insertMany: docs
|
|
36
|
-
}
|
|
37
|
-
];
|
|
33
|
+
const operations = docs.map(document => ({ insertOne: { document } }));
|
|
38
34
|
|
|
39
35
|
const bulkWriteOperation = new BulkWriteOperation(coll, operations, options);
|
|
40
36
|
|
package/lib/utils.js
CHANGED
|
@@ -40,7 +40,7 @@ var formatSortValue = (exports.formatSortValue = function(sortDirection) {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
var formattedOrderClause = (exports.formattedOrderClause = function(sortValue) {
|
|
43
|
-
var orderBy =
|
|
43
|
+
var orderBy = new Map();
|
|
44
44
|
if (sortValue == null) return null;
|
|
45
45
|
if (Array.isArray(sortValue)) {
|
|
46
46
|
if (sortValue.length === 0) {
|
|
@@ -49,15 +49,22 @@ var formattedOrderClause = (exports.formattedOrderClause = function(sortValue) {
|
|
|
49
49
|
|
|
50
50
|
for (var i = 0; i < sortValue.length; i++) {
|
|
51
51
|
if (sortValue[i].constructor === String) {
|
|
52
|
-
orderBy
|
|
52
|
+
orderBy.set(`${sortValue[i]}`, 1);
|
|
53
53
|
} else {
|
|
54
|
-
orderBy
|
|
54
|
+
orderBy.set(`${sortValue[i][0]}`, formatSortValue(sortValue[i][1]));
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
} else if (sortValue != null && typeof sortValue === 'object') {
|
|
58
|
-
|
|
58
|
+
if (sortValue instanceof Map) {
|
|
59
|
+
orderBy = sortValue;
|
|
60
|
+
} else {
|
|
61
|
+
var sortKeys = Object.keys(sortValue);
|
|
62
|
+
for (var k of sortKeys) {
|
|
63
|
+
orderBy.set(k, sortValue[k]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
59
66
|
} else if (typeof sortValue === 'string') {
|
|
60
|
-
orderBy
|
|
67
|
+
orderBy.set(`${sortValue}`, 1);
|
|
61
68
|
} else {
|
|
62
69
|
throw new Error(
|
|
63
70
|
'Illegal sort clause, must be of the form ' +
|
|
@@ -287,39 +294,38 @@ var filterOptions = function(options, names) {
|
|
|
287
294
|
};
|
|
288
295
|
|
|
289
296
|
// Write concern keys
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// Merge the write concern options
|
|
293
|
-
var mergeOptionsAndWriteConcern = function(targetOptions, sourceOptions, keys, mergeWriteConcern) {
|
|
294
|
-
// Mix in any allowed options
|
|
295
|
-
for (var i = 0; i < keys.length; i++) {
|
|
296
|
-
if (!targetOptions[keys[i]] && sourceOptions[keys[i]] !== undefined) {
|
|
297
|
-
targetOptions[keys[i]] = sourceOptions[keys[i]];
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// No merging of write concern
|
|
302
|
-
if (!mergeWriteConcern) return targetOptions;
|
|
297
|
+
const WRITE_CONCERN_KEYS = ['w', 'j', 'wtimeout', 'fsync', 'writeConcern'];
|
|
303
298
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
299
|
+
/**
|
|
300
|
+
* If there is no WriteConcern related options defined on target then inherit from source.
|
|
301
|
+
* Otherwise, do not inherit **any** options from source.
|
|
302
|
+
* @internal
|
|
303
|
+
* @param {object} target - options object conditionally receiving the writeConcern options
|
|
304
|
+
* @param {object} source - options object containing the potentially inherited writeConcern options
|
|
305
|
+
*/
|
|
306
|
+
function conditionallyMergeWriteConcern(target, source) {
|
|
307
|
+
let found = false;
|
|
308
|
+
for (const wcKey of WRITE_CONCERN_KEYS) {
|
|
309
|
+
if (wcKey in target) {
|
|
310
|
+
// Found a writeConcern option
|
|
308
311
|
found = true;
|
|
309
312
|
break;
|
|
310
313
|
}
|
|
311
314
|
}
|
|
312
315
|
|
|
313
316
|
if (!found) {
|
|
314
|
-
for (
|
|
315
|
-
if (
|
|
316
|
-
|
|
317
|
+
for (const wcKey of WRITE_CONCERN_KEYS) {
|
|
318
|
+
if (source[wcKey]) {
|
|
319
|
+
if (!('writeConcern' in target)) {
|
|
320
|
+
target.writeConcern = {};
|
|
321
|
+
}
|
|
322
|
+
target.writeConcern[wcKey] = source[wcKey];
|
|
317
323
|
}
|
|
318
324
|
}
|
|
319
325
|
}
|
|
320
326
|
|
|
321
|
-
return
|
|
322
|
-
}
|
|
327
|
+
return target;
|
|
328
|
+
}
|
|
323
329
|
|
|
324
330
|
/**
|
|
325
331
|
* Executes the given operation with provided arguments.
|
|
@@ -534,7 +540,12 @@ function decorateWithExplain(command, explain) {
|
|
|
534
540
|
return { explain: command, verbosity: explain.verbosity };
|
|
535
541
|
}
|
|
536
542
|
|
|
537
|
-
const
|
|
543
|
+
const nodejsMajorVersion = +process.version.split('.')[0].substring(1);
|
|
544
|
+
const emitProcessWarning = msg =>
|
|
545
|
+
nodejsMajorVersion <= 6
|
|
546
|
+
? process.emitWarning(msg, 'DeprecationWarning', MONGODB_WARNING_CODE)
|
|
547
|
+
: process.emitWarning(msg, { type: 'DeprecationWarning', code: MONGODB_WARNING_CODE });
|
|
548
|
+
// eslint-disable-next-line no-console
|
|
538
549
|
const emitConsoleWarning = msg => console.error(msg);
|
|
539
550
|
const emitDeprecationWarning = process.emitWarning ? emitProcessWarning : emitConsoleWarning;
|
|
540
551
|
|
|
@@ -816,6 +827,50 @@ function hasAtomicOperators(doc) {
|
|
|
816
827
|
);
|
|
817
828
|
}
|
|
818
829
|
|
|
830
|
+
/**
|
|
831
|
+
* When the driver used emitWarning the code will be equal to this.
|
|
832
|
+
* @public
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* ```js
|
|
836
|
+
* process.on('warning', (warning) => {
|
|
837
|
+
* if (warning.code === MONGODB_WARNING_CODE) console.error('Ah an important warning! :)')
|
|
838
|
+
* })
|
|
839
|
+
* ```
|
|
840
|
+
*/
|
|
841
|
+
const MONGODB_WARNING_CODE = 'MONGODB DRIVER';
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* @internal
|
|
845
|
+
* @param {string} message - message to warn about
|
|
846
|
+
*/
|
|
847
|
+
function emitWarning(message) {
|
|
848
|
+
if (process.emitWarning) {
|
|
849
|
+
return nodejsMajorVersion <= 6
|
|
850
|
+
? process.emitWarning(message, undefined, MONGODB_WARNING_CODE)
|
|
851
|
+
: process.emitWarning(message, { code: MONGODB_WARNING_CODE });
|
|
852
|
+
} else {
|
|
853
|
+
// Approximate the style of print out on node versions pre 8.x
|
|
854
|
+
// eslint-disable-next-line no-console
|
|
855
|
+
return console.error(`[${MONGODB_WARNING_CODE}] Warning:`, message);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
const emittedWarnings = new Set();
|
|
860
|
+
/**
|
|
861
|
+
* Will emit a warning once for the duration of the application.
|
|
862
|
+
* Uses the message to identify if it has already been emitted
|
|
863
|
+
* so using string interpolation can cause multiple emits
|
|
864
|
+
* @internal
|
|
865
|
+
* @param {string} message - message to warn about
|
|
866
|
+
*/
|
|
867
|
+
function emitWarningOnce(message) {
|
|
868
|
+
if (!emittedWarnings.has(message)) {
|
|
869
|
+
emittedWarnings.add(message);
|
|
870
|
+
return emitWarning(message);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
819
874
|
module.exports = {
|
|
820
875
|
filterOptions,
|
|
821
876
|
mergeOptions,
|
|
@@ -832,7 +887,7 @@ module.exports = {
|
|
|
832
887
|
isObject,
|
|
833
888
|
debugOptions,
|
|
834
889
|
MAX_JS_INT: Number.MAX_SAFE_INTEGER + 1,
|
|
835
|
-
|
|
890
|
+
conditionallyMergeWriteConcern,
|
|
836
891
|
executeLegacyOperation,
|
|
837
892
|
applyRetryableWrites,
|
|
838
893
|
applyWriteConcern,
|
|
@@ -849,5 +904,8 @@ module.exports = {
|
|
|
849
904
|
now,
|
|
850
905
|
calculateDurationInMs,
|
|
851
906
|
makeInterruptableAsyncInterval,
|
|
852
|
-
hasAtomicOperators
|
|
907
|
+
hasAtomicOperators,
|
|
908
|
+
MONGODB_WARNING_CODE,
|
|
909
|
+
emitWarning,
|
|
910
|
+
emitWarningOnce
|
|
853
911
|
};
|
package/lib/write_concern.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const kWriteConcernKeys = new Set(['w', 'wtimeout', 'j', 'journal', 'fsync']);
|
|
4
|
+
let utils;
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The **WriteConcern** class is a class that represents a MongoDB WriteConcern.
|
|
@@ -75,7 +76,10 @@ class WriteConcern {
|
|
|
75
76
|
);
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
+
// this is down here to prevent circular dependency
|
|
80
|
+
if (!utils) utils = require('./utils');
|
|
81
|
+
|
|
82
|
+
utils.emitWarningOnce(
|
|
79
83
|
`Top-level use of w, wtimeout, j, and fsync is deprecated. Use writeConcern instead.`
|
|
80
84
|
);
|
|
81
85
|
return new WriteConcern(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongodb",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.8",
|
|
4
4
|
"description": "The official MongoDB driver for Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -16,13 +16,6 @@
|
|
|
16
16
|
"driver",
|
|
17
17
|
"official"
|
|
18
18
|
],
|
|
19
|
-
"peerOptionalDependencies": {
|
|
20
|
-
"kerberos": "^1.1.0",
|
|
21
|
-
"mongodb-client-encryption": "^1.0.0",
|
|
22
|
-
"mongodb-extjson": "^2.1.2",
|
|
23
|
-
"snappy": "^6.3.4",
|
|
24
|
-
"bson-ext": "^2.0.0"
|
|
25
|
-
},
|
|
26
19
|
"peerDependenciesMeta": {
|
|
27
20
|
"kerberos": {
|
|
28
21
|
"optional": true
|
|
@@ -47,33 +40,39 @@
|
|
|
47
40
|
"bl": "^2.2.1",
|
|
48
41
|
"bson": "^1.1.4",
|
|
49
42
|
"denque": "^1.4.1",
|
|
50
|
-
"
|
|
43
|
+
"optional-require": "^1.0.3",
|
|
51
44
|
"safe-buffer": "^5.1.2"
|
|
52
45
|
},
|
|
53
46
|
"devDependencies": {
|
|
47
|
+
"@types/chai": "^4.2.16",
|
|
48
|
+
"@types/mocha": "^8.2.2",
|
|
49
|
+
"@types/node": "^14.14.37",
|
|
50
|
+
"array-includes": "^3.1.3",
|
|
54
51
|
"chai": "^4.1.1",
|
|
55
52
|
"chai-subset": "^1.6.0",
|
|
56
53
|
"chalk": "^2.4.2",
|
|
57
54
|
"co": "4.6.0",
|
|
58
|
-
"coveralls": "^2.11.6",
|
|
59
55
|
"eslint": "^7.10.0",
|
|
60
56
|
"eslint-config-prettier": "^6.11.0",
|
|
61
57
|
"eslint-plugin-es": "^3.0.1",
|
|
62
58
|
"eslint-plugin-prettier": "^3.1.3",
|
|
63
|
-
"
|
|
64
|
-
"jsdoc": "3.5.5",
|
|
59
|
+
"jsdoc": "^3.5.5",
|
|
65
60
|
"lodash.camelcase": "^4.3.0",
|
|
66
61
|
"mocha": "5.2.0",
|
|
67
62
|
"mocha-sinon": "^2.1.0",
|
|
68
63
|
"mongodb-extjson": "^2.1.1",
|
|
69
64
|
"mongodb-mock-server": "^1.0.1",
|
|
65
|
+
"nyc": "^15.1.0",
|
|
66
|
+
"object.entries": "^1.1.3",
|
|
70
67
|
"prettier": "^1.19.1",
|
|
71
68
|
"semver": "^5.5.0",
|
|
72
69
|
"sinon": "^4.3.0",
|
|
73
70
|
"sinon-chai": "^3.2.0",
|
|
74
71
|
"snappy": "^6.3.4",
|
|
75
72
|
"spec-xunit-file": "0.0.1-3",
|
|
76
|
-
"standard-version": "^
|
|
73
|
+
"standard-version": "^9.2.0",
|
|
74
|
+
"tslib": "^2.2.0",
|
|
75
|
+
"typescript": "^4.2.4",
|
|
77
76
|
"util.promisify": "^1.0.1",
|
|
78
77
|
"worker-farm": "^1.5.0",
|
|
79
78
|
"wtfnode": "^0.8.0",
|
|
@@ -87,18 +86,19 @@
|
|
|
87
86
|
"url": "https://github.com/mongodb/node-mongodb-native/issues"
|
|
88
87
|
},
|
|
89
88
|
"scripts": {
|
|
90
|
-
"
|
|
89
|
+
"build:evergreen": "node .evergreen/generate_evergreen_tasks.js",
|
|
90
|
+
"build:unified": "tsc -p test/functional/unified-spec-runner/tsconfig.unified.json",
|
|
91
|
+
"check:atlas": "mocha --opts '{}' ./test/manual/atlas_connectivity.test.js",
|
|
92
|
+
"check:bench": "node test/benchmarks/driverBench/",
|
|
93
|
+
"check:coverage": "nyc npm run check:test",
|
|
91
94
|
"check:kerberos": "mocha --opts '{}' -t 60000 test/manual/kerberos.test.js",
|
|
92
95
|
"check:ldap": "mocha --opts '{}' test/manual/ldap.test.js",
|
|
96
|
+
"check:lint": "eslint -v && eslint lib test",
|
|
97
|
+
"check:test": "mocha --recursive test/functional test/unit",
|
|
93
98
|
"check:tls": "mocha --opts '{}' test/manual/tls_support.test.js",
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"lint": "eslint -v && eslint lib test",
|
|
98
|
-
"format": "npm run lint -- --fix",
|
|
99
|
-
"bench": "node test/benchmarks/driverBench/",
|
|
100
|
-
"generate-evergreen": "node .evergreen/generate_evergreen_tasks.js",
|
|
101
|
-
"release": "standard-version -i HISTORY.md"
|
|
99
|
+
"format": "npm run check:lint -- --fix",
|
|
100
|
+
"release": "standard-version -i HISTORY.md",
|
|
101
|
+
"test": "npm run lint && mocha --recursive test/functional test/unit"
|
|
102
102
|
},
|
|
103
103
|
"homepage": "https://github.com/mongodb/node-mongodb-native",
|
|
104
104
|
"optionalDependencies": {
|