mongodb 3.6.5 → 3.6.9
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 +41 -0
- package/lib/bulk/common.js +96 -1
- package/lib/cmap/connection.js +36 -32
- package/lib/collection.js +47 -32
- package/lib/core/auth/mongo_credentials.js +5 -5
- package/lib/core/connection/connect.js +1 -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 +0 -1
- package/lib/core/topologies/replset.js +1 -1
- package/lib/core/uri_parser.js +3 -1
- package/lib/core/utils.js +2 -5
- package/lib/core/wireprotocol/command.js +10 -5
- package/lib/encrypter.js +163 -0
- package/lib/gridfs-stream/upload.js +1 -0
- package/lib/mongo_client.js +123 -168
- package/lib/operations/bulk_write.js +0 -25
- package/lib/operations/connect.js +8 -55
- 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/url_parser.js +2 -1
- package/lib/utils.js +12 -5
- package/package.json +22 -22
package/HISTORY.md
CHANGED
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [3.6.9](https://github.com/mongodb/node-mongodb-native/compare/v3.6.8...v3.6.9) (2021-05-26)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **NODE-3309:** remove redundant iteration of bulk write result ([#2815](https://github.com/mongodb/node-mongodb-native/issues/2815)) ([fac9610](https://github.com/mongodb/node-mongodb-native/commit/fac961086eafa0f7437576fd6af900e1f9fe22ed))
|
|
11
|
+
* fix url parsing for a mongodb+srv url that has commas in the database name ([#2789](https://github.com/mongodb/node-mongodb-native/issues/2789)) ([58c4e69](https://github.com/mongodb/node-mongodb-native/commit/58c4e693cc3a717254144d5f9bdddd8414217e97))
|
|
12
|
+
|
|
13
|
+
### [3.6.8](https://github.com/mongodb/node-mongodb-native/compare/v3.6.7...v3.6.8) (2021-05-21)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* **cmap:** undo flipping of `beforeHandshake` flag for timeout errors ([#2813](https://github.com/mongodb/node-mongodb-native/issues/2813)) ([6e3bab3](https://github.com/mongodb/node-mongodb-native/commit/6e3bab32204ea905ab9b949edccb68556b50d382))
|
|
19
|
+
|
|
20
|
+
### [3.6.7](https://github.com/mongodb/node-mongodb-native/compare/v3.6.6...v3.6.7) (2021-05-18)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **docs:** removing incorrect apm docs ([#2793](https://github.com/mongodb/node-mongodb-native/issues/2793)) ([971259a](https://github.com/mongodb/node-mongodb-native/commit/971259a868a8018e90ebc2f28d151eb7af3dd50a))
|
|
26
|
+
* **NODE-3173:** Preserve sort key order for numeric string keys ([#2790](https://github.com/mongodb/node-mongodb-native/issues/2790)) ([730f43a](https://github.com/mongodb/node-mongodb-native/commit/730f43af6d9e53603af998353b720d8161426d8c))
|
|
27
|
+
* **NODE-3176:** handle errors from MessageStream ([#2774](https://github.com/mongodb/node-mongodb-native/issues/2774)) ([f1afcc4](https://github.com/mongodb/node-mongodb-native/commit/f1afcc4efbc41ce436812a6bfa22843e939ab5cf))
|
|
28
|
+
* **NODE-3192:** check clusterTime is defined before access ([#2806](https://github.com/mongodb/node-mongodb-native/issues/2806)) ([6ceace6](https://github.com/mongodb/node-mongodb-native/commit/6ceace6b245c42b8498fb1b13e7c37a97a46946d))
|
|
29
|
+
* **NODE-3252:** state transistion from DISCONNECTED ([#2807](https://github.com/mongodb/node-mongodb-native/issues/2807)) ([5d8f649](https://github.com/mongodb/node-mongodb-native/commit/5d8f6493a0ba4b525434c0868e2ae12315b4c249))
|
|
30
|
+
* **sdam:** topology no longer causes close event ([#2791](https://github.com/mongodb/node-mongodb-native/issues/2791)) ([16e7064](https://github.com/mongodb/node-mongodb-native/commit/16e70642f25954a03b91a2c2991cea96b8356de7))
|
|
31
|
+
* invalid case on writeconcern makes skip check fail ([#2773](https://github.com/mongodb/node-mongodb-native/issues/2773)) ([b1363c2](https://github.com/mongodb/node-mongodb-native/commit/b1363c26db5da5003f9db43be7e8d6e9007d45bd))
|
|
32
|
+
|
|
33
|
+
### [3.6.6](https://github.com/mongodb/node-mongodb-native/compare/v3.6.5...v3.6.6) (2021-04-06)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Bug Fixes
|
|
37
|
+
|
|
38
|
+
* always close gridfs upload stream on finish ([#2758](https://github.com/mongodb/node-mongodb-native/issues/2758)) ([c976a01](https://github.com/mongodb/node-mongodb-native/commit/c976a01bf385941bee07fa7f021adf1d425109a8))
|
|
39
|
+
* **csfle:** ensure that monitoring connections are not encrypted ([#2749](https://github.com/mongodb/node-mongodb-native/issues/2749)) ([86bddf1](https://github.com/mongodb/node-mongodb-native/commit/86bddf1ef516d6b8c752082e33c15624753579ab))
|
|
40
|
+
* ensure cursor readPreference is applied to find operations ([#2751](https://github.com/mongodb/node-mongodb-native/issues/2751)) ([91ba19e](https://github.com/mongodb/node-mongodb-native/commit/91ba19efdc4713903584c6161cfdd7b91b0e61f9))
|
|
41
|
+
* ensure monitor has rtt pinger in when calculating rtt ([#2757](https://github.com/mongodb/node-mongodb-native/issues/2757)) ([b94519b](https://github.com/mongodb/node-mongodb-native/commit/b94519ba894b4442d3dabbac59bd12784d8b7178))
|
|
42
|
+
* no infinite loop on windows requiring optional deps ([f2a4ff8](https://github.com/mongodb/node-mongodb-native/commit/f2a4ff870178fbbe8de616c45891368665f29f4b))
|
|
43
|
+
* **NODE-2995:** Add shared metadata MongoClient ([#2760](https://github.com/mongodb/node-mongodb-native/issues/2760)) ([9256242](https://github.com/mongodb/node-mongodb-native/commit/9256242d51c037059c0af5ada9639fc0a74ad033))
|
|
44
|
+
* **NODE-3109:** prevent servername from being IP ([#2763](https://github.com/mongodb/node-mongodb-native/issues/2763)) ([312ffef](https://github.com/mongodb/node-mongodb-native/commit/312ffef18c66a0020f19bdc1d654987d9148d709))
|
|
45
|
+
|
|
5
46
|
### [3.6.5](https://github.com/mongodb/node-mongodb-native/compare/v3.6.4...v3.6.5) (2021-03-16)
|
|
6
47
|
|
|
7
48
|
|
package/lib/bulk/common.js
CHANGED
|
@@ -5,6 +5,7 @@ const MongoError = require('../core').MongoError;
|
|
|
5
5
|
const ObjectID = require('../core').BSON.ObjectID;
|
|
6
6
|
const BSON = require('../core').BSON;
|
|
7
7
|
const MongoWriteConcernError = require('../core').MongoWriteConcernError;
|
|
8
|
+
const emitWarningOnce = require('../utils').emitWarningOnce;
|
|
8
9
|
const toError = require('../utils').toError;
|
|
9
10
|
const handleCallback = require('../utils').handleCallback;
|
|
10
11
|
const applyRetryableWrites = require('../utils').applyRetryableWrites;
|
|
@@ -56,6 +57,9 @@ class Batch {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
const kUpsertedIds = Symbol('upsertedIds');
|
|
61
|
+
const kInsertedIds = Symbol('insertedIds');
|
|
62
|
+
|
|
59
63
|
/**
|
|
60
64
|
* @classdesc
|
|
61
65
|
* The result of a bulk write.
|
|
@@ -68,6 +72,60 @@ class BulkWriteResult {
|
|
|
68
72
|
*/
|
|
69
73
|
constructor(bulkResult) {
|
|
70
74
|
this.result = bulkResult;
|
|
75
|
+
this[kUpsertedIds] = undefined;
|
|
76
|
+
this[kInsertedIds] = undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Number of documents inserted. */
|
|
80
|
+
get insertedCount() {
|
|
81
|
+
return typeof this.result.nInserted !== 'number' ? 0 : this.result.nInserted;
|
|
82
|
+
}
|
|
83
|
+
/** Number of documents matched for update. */
|
|
84
|
+
get matchedCount() {
|
|
85
|
+
return typeof this.result.nMatched !== 'number' ? 0 : this.result.nMatched;
|
|
86
|
+
}
|
|
87
|
+
/** Number of documents modified. */
|
|
88
|
+
get modifiedCount() {
|
|
89
|
+
return typeof this.result.nModified !== 'number' ? 0 : this.result.nModified;
|
|
90
|
+
}
|
|
91
|
+
/** Number of documents deleted. */
|
|
92
|
+
get deletedCount() {
|
|
93
|
+
return typeof this.result.nRemoved !== 'number' ? 0 : this.result.nRemoved;
|
|
94
|
+
}
|
|
95
|
+
/** Number of documents upserted. */
|
|
96
|
+
get upsertedCount() {
|
|
97
|
+
return !this.result.upserted ? 0 : this.result.upserted.length;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Upserted document generated Id's, hash key is the index of the originating operation */
|
|
101
|
+
get upsertedIds() {
|
|
102
|
+
if (this[kUpsertedIds]) {
|
|
103
|
+
return this[kUpsertedIds];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this[kUpsertedIds] = {};
|
|
107
|
+
for (const doc of this.result.upserted || []) {
|
|
108
|
+
this[kUpsertedIds][doc.index] = doc._id;
|
|
109
|
+
}
|
|
110
|
+
return this[kUpsertedIds];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Inserted document generated Id's, hash key is the index of the originating operation */
|
|
114
|
+
get insertedIds() {
|
|
115
|
+
if (this[kInsertedIds]) {
|
|
116
|
+
return this[kInsertedIds];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this[kInsertedIds] = {};
|
|
120
|
+
for (const doc of this.result.insertedIds || []) {
|
|
121
|
+
this[kInsertedIds][doc.index] = doc._id;
|
|
122
|
+
}
|
|
123
|
+
return this[kInsertedIds];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** The number of inserted documents @type {number} */
|
|
127
|
+
get n() {
|
|
128
|
+
return this.result.insertedCount;
|
|
71
129
|
}
|
|
72
130
|
|
|
73
131
|
/**
|
|
@@ -571,6 +629,35 @@ class BulkWriteError extends MongoError {
|
|
|
571
629
|
this.name = 'BulkWriteError';
|
|
572
630
|
this.result = result;
|
|
573
631
|
}
|
|
632
|
+
|
|
633
|
+
/** Number of documents inserted. */
|
|
634
|
+
get insertedCount() {
|
|
635
|
+
return this.result.insertedCount;
|
|
636
|
+
}
|
|
637
|
+
/** Number of documents matched for update. */
|
|
638
|
+
get matchedCount() {
|
|
639
|
+
return this.result.matchedCount;
|
|
640
|
+
}
|
|
641
|
+
/** Number of documents modified. */
|
|
642
|
+
get modifiedCount() {
|
|
643
|
+
return this.result.modifiedCount;
|
|
644
|
+
}
|
|
645
|
+
/** Number of documents deleted. */
|
|
646
|
+
get deletedCount() {
|
|
647
|
+
return this.result.deletedCount;
|
|
648
|
+
}
|
|
649
|
+
/** Number of documents upserted. */
|
|
650
|
+
get upsertedCount() {
|
|
651
|
+
return this.result.upsertedCount;
|
|
652
|
+
}
|
|
653
|
+
/** Inserted document generated Id's, hash key is the index of the originating operation */
|
|
654
|
+
get insertedIds() {
|
|
655
|
+
return this.result.insertedIds;
|
|
656
|
+
}
|
|
657
|
+
/** Upserted document generated Id's, hash key is the index of the originating operation */
|
|
658
|
+
get upsertedIds() {
|
|
659
|
+
return this.result.upsertedIds;
|
|
660
|
+
}
|
|
574
661
|
}
|
|
575
662
|
|
|
576
663
|
/**
|
|
@@ -737,15 +824,19 @@ class FindOperators {
|
|
|
737
824
|
|
|
738
825
|
/**
|
|
739
826
|
* backwards compatability for deleteOne
|
|
827
|
+
* @deprecated
|
|
740
828
|
*/
|
|
741
829
|
removeOne() {
|
|
830
|
+
emitWarningOnce('bulk operation `removeOne` has been deprecated, please use `deleteOne`');
|
|
742
831
|
return this.deleteOne();
|
|
743
832
|
}
|
|
744
833
|
|
|
745
834
|
/**
|
|
746
835
|
* backwards compatability for delete
|
|
836
|
+
* @deprecated
|
|
747
837
|
*/
|
|
748
838
|
remove() {
|
|
839
|
+
emitWarningOnce('bulk operation `remove` has been deprecated, please use `delete`');
|
|
749
840
|
return this.delete();
|
|
750
841
|
}
|
|
751
842
|
}
|
|
@@ -1041,6 +1132,9 @@ class BulkOperationBase {
|
|
|
1041
1132
|
}
|
|
1042
1133
|
|
|
1043
1134
|
if (op.insertMany) {
|
|
1135
|
+
emitWarningOnce(
|
|
1136
|
+
'bulk operation `insertMany` has been deprecated; use multiple `insertOne` ops instead'
|
|
1137
|
+
);
|
|
1044
1138
|
for (let i = 0; i < op.insertMany.length; i++) {
|
|
1045
1139
|
if (forceServerObjectId !== true && op.insertMany[i]._id == null)
|
|
1046
1140
|
op.insertMany[i]._id = new ObjectID();
|
|
@@ -1294,5 +1388,6 @@ module.exports = {
|
|
|
1294
1388
|
INSERT: INSERT,
|
|
1295
1389
|
UPDATE: UPDATE,
|
|
1296
1390
|
REMOVE: REMOVE,
|
|
1297
|
-
BulkWriteError
|
|
1391
|
+
BulkWriteError,
|
|
1392
|
+
BulkWriteResult
|
|
1298
1393
|
};
|
package/lib/cmap/connection.js
CHANGED
|
@@ -58,38 +58,9 @@ class Connection extends EventEmitter {
|
|
|
58
58
|
/* ignore errors, listen to `close` instead */
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
this.closed = true;
|
|
67
|
-
this[kQueue].forEach(op =>
|
|
68
|
-
op.cb(new MongoNetworkError(`connection ${this.id} to ${this.address} closed`))
|
|
69
|
-
);
|
|
70
|
-
this[kQueue].clear();
|
|
71
|
-
|
|
72
|
-
this.emit('close');
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
stream.on('timeout', () => {
|
|
76
|
-
if (this.closed) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
stream.destroy();
|
|
81
|
-
this.closed = true;
|
|
82
|
-
this[kQueue].forEach(op =>
|
|
83
|
-
op.cb(
|
|
84
|
-
new MongoNetworkTimeoutError(`connection ${this.id} to ${this.address} timed out`, {
|
|
85
|
-
beforeHandshake: this[kIsMaster] == null
|
|
86
|
-
})
|
|
87
|
-
)
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
this[kQueue].clear();
|
|
91
|
-
this.emit('close');
|
|
92
|
-
});
|
|
61
|
+
this[kMessageStream].on('error', error => this.handleIssue({ destroy: error }));
|
|
62
|
+
stream.on('close', () => this.handleIssue({ isClose: true }));
|
|
63
|
+
stream.on('timeout', () => this.handleIssue({ isTimeout: true, destroy: true }));
|
|
93
64
|
|
|
94
65
|
// hook the message stream up to the passed in stream
|
|
95
66
|
stream.pipe(this[kMessageStream]);
|
|
@@ -132,6 +103,39 @@ class Connection extends EventEmitter {
|
|
|
132
103
|
this[kLastUseTime] = now();
|
|
133
104
|
}
|
|
134
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @param {{ isTimeout?: boolean; isClose?: boolean; destroy?: boolean | Error }} issue
|
|
108
|
+
*/
|
|
109
|
+
handleIssue(issue) {
|
|
110
|
+
if (this.closed) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (issue.destroy) {
|
|
115
|
+
this[kStream].destroy(typeof issue.destroy === 'boolean' ? undefined : issue.destroy);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.closed = true;
|
|
119
|
+
|
|
120
|
+
for (const idAndOp of this[kQueue]) {
|
|
121
|
+
const op = idAndOp[1];
|
|
122
|
+
if (issue.isTimeout) {
|
|
123
|
+
op.cb(
|
|
124
|
+
new MongoNetworkTimeoutError(`connection ${this.id} to ${this.address} timed out`, {
|
|
125
|
+
beforeHandshake: this.ismaster == null
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
} else if (issue.isClose) {
|
|
129
|
+
op.cb(new MongoNetworkError(`connection ${this.id} to ${this.address} closed`));
|
|
130
|
+
} else {
|
|
131
|
+
op.cb(typeof issue.destroy === 'boolean' ? undefined : issue.destroy);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
this[kQueue].clear();
|
|
136
|
+
this.emit('close');
|
|
137
|
+
}
|
|
138
|
+
|
|
135
139
|
destroy(options, callback) {
|
|
136
140
|
if (typeof options === 'function') {
|
|
137
141
|
callback = options;
|
package/lib/collection.js
CHANGED
|
@@ -1655,7 +1655,7 @@ Collection.prototype.stats = function(options, callback) {
|
|
|
1655
1655
|
|
|
1656
1656
|
/**
|
|
1657
1657
|
* @typedef {Object} Collection~findAndModifyWriteOpResult
|
|
1658
|
-
* @property {object} value Document returned from the `findAndModify` command. If no documents were found, `value` will be `null` by default
|
|
1658
|
+
* @property {object} value Document returned from the `findAndModify` command. If no documents were found, `value` will be `null` by default even if a document was upserted unless `returnDocument` is specified as `'after'`, in which case the upserted document will be returned.
|
|
1659
1659
|
* @property {object} lastErrorObject The raw lastErrorObject returned from the command. See {@link https://docs.mongodb.com/manual/reference/command/findAndModify/index.html#lasterrorobject|findAndModify command documentation}.
|
|
1660
1660
|
* @property {Number} ok Is 1 if the command executed correctly.
|
|
1661
1661
|
*/
|
|
@@ -1716,7 +1716,8 @@ Collection.prototype.findOneAndDelete = function(filter, options, callback) {
|
|
|
1716
1716
|
* @param {object} [options.projection] Limits the fields to return for all matching documents.
|
|
1717
1717
|
* @param {object} [options.sort] Determines which document the operation modifies if the query selects multiple documents.
|
|
1718
1718
|
* @param {boolean} [options.upsert=false] Upsert the document if it does not exist.
|
|
1719
|
-
* @param {
|
|
1719
|
+
* @param {'before'|'after'} [options.returnDocument='before'] When set to `'after'`, returns the updated document rather than the original. The default is `'before'`.
|
|
1720
|
+
* @param {boolean} [options.returnOriginal=true] **Deprecated** Use `options.returnDocument` instead.
|
|
1720
1721
|
* @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
|
|
1721
1722
|
* @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
|
|
1722
1723
|
* @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
|
|
@@ -1725,22 +1726,29 @@ Collection.prototype.findOneAndDelete = function(filter, options, callback) {
|
|
|
1725
1726
|
* @param {Collection~findAndModifyCallback} [callback] The collection result callback
|
|
1726
1727
|
* @return {Promise<Collection~findAndModifyWriteOpResultObject>} returns Promise if no callback passed
|
|
1727
1728
|
*/
|
|
1728
|
-
Collection.prototype.findOneAndReplace =
|
|
1729
|
-
|
|
1730
|
-
|
|
1729
|
+
Collection.prototype.findOneAndReplace = deprecateOptions(
|
|
1730
|
+
{
|
|
1731
|
+
name: 'collection.findOneAndReplace',
|
|
1732
|
+
deprecatedOptions: ['returnOriginal'],
|
|
1733
|
+
optionsIndex: 2
|
|
1734
|
+
},
|
|
1735
|
+
function(filter, replacement, options, callback) {
|
|
1736
|
+
if (typeof options === 'function') (callback = options), (options = {});
|
|
1737
|
+
options = options || {};
|
|
1731
1738
|
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1739
|
+
// Add ignoreUndefined
|
|
1740
|
+
if (this.s.options.ignoreUndefined) {
|
|
1741
|
+
options = Object.assign({}, options);
|
|
1742
|
+
options.ignoreUndefined = this.s.options.ignoreUndefined;
|
|
1743
|
+
}
|
|
1737
1744
|
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
}
|
|
1745
|
+
return executeOperation(
|
|
1746
|
+
this.s.topology,
|
|
1747
|
+
new FindOneAndReplaceOperation(this, filter, replacement, options),
|
|
1748
|
+
callback
|
|
1749
|
+
);
|
|
1750
|
+
}
|
|
1751
|
+
);
|
|
1744
1752
|
|
|
1745
1753
|
/**
|
|
1746
1754
|
* Find a document and update it in one atomic operation. Requires a write lock for the duration of the operation.
|
|
@@ -1757,7 +1765,8 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options,
|
|
|
1757
1765
|
* @param {object} [options.projection] Limits the fields to return for all matching documents.
|
|
1758
1766
|
* @param {object} [options.sort] Determines which document the operation modifies if the query selects multiple documents.
|
|
1759
1767
|
* @param {boolean} [options.upsert=false] Upsert the document if it does not exist.
|
|
1760
|
-
* @param {
|
|
1768
|
+
* @param {'before'|'after'} [options.returnDocument='before'] When set to `'after'`, returns the updated document rather than the original. The default is `'before'`.
|
|
1769
|
+
* @param {boolean} [options.returnOriginal=true] **Deprecated** Use `options.returnDocument` instead.
|
|
1761
1770
|
* @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
|
|
1762
1771
|
* @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
|
|
1763
1772
|
* @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
|
|
@@ -1766,22 +1775,29 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options,
|
|
|
1766
1775
|
* @param {Collection~findAndModifyCallback} [callback] The collection result callback
|
|
1767
1776
|
* @return {Promise<Collection~findAndModifyWriteOpResultObject>} returns Promise if no callback passed
|
|
1768
1777
|
*/
|
|
1769
|
-
Collection.prototype.findOneAndUpdate =
|
|
1770
|
-
|
|
1771
|
-
|
|
1778
|
+
Collection.prototype.findOneAndUpdate = deprecateOptions(
|
|
1779
|
+
{
|
|
1780
|
+
name: 'collection.findOneAndUpdate',
|
|
1781
|
+
deprecatedOptions: ['returnOriginal'],
|
|
1782
|
+
optionsIndex: 2
|
|
1783
|
+
},
|
|
1784
|
+
function(filter, update, options, callback) {
|
|
1785
|
+
if (typeof options === 'function') (callback = options), (options = {});
|
|
1786
|
+
options = options || {};
|
|
1772
1787
|
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1788
|
+
// Add ignoreUndefined
|
|
1789
|
+
if (this.s.options.ignoreUndefined) {
|
|
1790
|
+
options = Object.assign({}, options);
|
|
1791
|
+
options.ignoreUndefined = this.s.options.ignoreUndefined;
|
|
1792
|
+
}
|
|
1778
1793
|
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
}
|
|
1794
|
+
return executeOperation(
|
|
1795
|
+
this.s.topology,
|
|
1796
|
+
new FindOneAndUpdateOperation(this, filter, update, options),
|
|
1797
|
+
callback
|
|
1798
|
+
);
|
|
1799
|
+
}
|
|
1800
|
+
);
|
|
1785
1801
|
|
|
1786
1802
|
/**
|
|
1787
1803
|
* Find and update a document.
|
|
@@ -2199,7 +2215,6 @@ Collection.prototype.initializeUnorderedBulkOp = function(options) {
|
|
|
2199
2215
|
* @param {object|WriteConcern} [options.writeConcern] Specify write concern settings.
|
|
2200
2216
|
* @param {ClientSession} [options.session] optional session to use for this operation
|
|
2201
2217
|
* @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
|
|
2202
|
-
* @param {OrderedBulkOperation} callback The command result callback
|
|
2203
2218
|
* @return {null}
|
|
2204
2219
|
*/
|
|
2205
2220
|
Collection.prototype.initializeOrderedBulkOp = function(options) {
|
|
@@ -49,16 +49,16 @@ class MongoCredentials {
|
|
|
49
49
|
this.mechanism = options.mechanism || 'default';
|
|
50
50
|
this.mechanismProperties = options.mechanismProperties || {};
|
|
51
51
|
|
|
52
|
-
if (
|
|
53
|
-
if (this.username
|
|
52
|
+
if (/MONGODB-AWS/i.test(this.mechanism)) {
|
|
53
|
+
if (!this.username && process.env.AWS_ACCESS_KEY_ID) {
|
|
54
54
|
this.username = process.env.AWS_ACCESS_KEY_ID;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
if (this.password
|
|
57
|
+
if (!this.password && process.env.AWS_SECRET_ACCESS_KEY) {
|
|
58
58
|
this.password = process.env.AWS_SECRET_ACCESS_KEY;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
if (this.mechanismProperties.AWS_SESSION_TOKEN
|
|
61
|
+
if (!this.mechanismProperties.AWS_SESSION_TOKEN && process.env.AWS_SESSION_TOKEN) {
|
|
62
62
|
this.mechanismProperties.AWS_SESSION_TOKEN = process.env.AWS_SESSION_TOKEN;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -90,7 +90,7 @@ class MongoCredentials {
|
|
|
90
90
|
*/
|
|
91
91
|
resolveAuthMechanism(ismaster) {
|
|
92
92
|
// If the mechanism is not "default", then it does not need to be resolved
|
|
93
|
-
if (
|
|
93
|
+
if (/DEFAULT/i.test(this.mechanism)) {
|
|
94
94
|
return new MongoCredentials({
|
|
95
95
|
username: this.username,
|
|
96
96
|
password: this.password,
|
|
@@ -243,7 +243,7 @@ function parseSslOptions(family, options) {
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
// Set default sni servername to be the same as host
|
|
246
|
-
if (result.servername == null) {
|
|
246
|
+
if (result.servername == null && !net.isIP(result.host)) {
|
|
247
247
|
result.servername = result.host;
|
|
248
248
|
}
|
|
249
249
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const require_optional = require('
|
|
3
|
+
const require_optional = require('optional-require')(require);
|
|
4
4
|
|
|
5
5
|
function debugOptions(debugFields, options) {
|
|
6
|
-
|
|
6
|
+
const finaloptions = {};
|
|
7
7
|
debugFields.forEach(function(n) {
|
|
8
8
|
finaloptions[n] = options[n];
|
|
9
9
|
});
|
|
@@ -12,16 +12,14 @@ function debugOptions(debugFields, options) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
function retrieveBSON() {
|
|
15
|
-
|
|
15
|
+
const BSON = require('bson');
|
|
16
16
|
BSON.native = false;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
} catch (err) {} // eslint-disable-line
|
|
18
|
+
const optionalBSON = require_optional('bson-ext');
|
|
19
|
+
if (optionalBSON) {
|
|
20
|
+
optionalBSON.native = true;
|
|
21
|
+
return optionalBSON;
|
|
22
|
+
}
|
|
25
23
|
|
|
26
24
|
return BSON;
|
|
27
25
|
}
|
|
@@ -35,10 +33,7 @@ function noSnappyWarning() {
|
|
|
35
33
|
|
|
36
34
|
// Facilitate loading Snappy optionally
|
|
37
35
|
function retrieveSnappy() {
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
snappy = require_optional('snappy');
|
|
41
|
-
} catch (error) {} // eslint-disable-line
|
|
36
|
+
let snappy = require_optional('snappy');
|
|
42
37
|
if (!snappy) {
|
|
43
38
|
snappy = {
|
|
44
39
|
compress: noSnappyWarning,
|
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
package/lib/core/sdam/monitor.js
CHANGED
|
@@ -91,6 +91,10 @@ class Monitor extends EventEmitter {
|
|
|
91
91
|
|
|
92
92
|
// ensure no authentication is used for monitoring
|
|
93
93
|
delete connectOptions.credentials;
|
|
94
|
+
|
|
95
|
+
// ensure encryption is not requested for monitoring
|
|
96
|
+
delete connectOptions.autoEncrypter;
|
|
97
|
+
|
|
94
98
|
this.connectOptions = Object.freeze(connectOptions);
|
|
95
99
|
}
|
|
96
100
|
|
|
@@ -222,9 +226,10 @@ function checkServer(monitor, callback) {
|
|
|
222
226
|
}
|
|
223
227
|
|
|
224
228
|
const isMaster = result.result;
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
229
|
+
const rttPinger = monitor[kRTTPinger];
|
|
230
|
+
|
|
231
|
+
const duration =
|
|
232
|
+
isAwaitable && rttPinger ? rttPinger.roundTripTime : calculateDurationInMs(start);
|
|
228
233
|
|
|
229
234
|
monitor.emit(
|
|
230
235
|
'serverHeartbeatSucceeded',
|
|
@@ -558,7 +558,7 @@ var monitorServer = function(host, self, options) {
|
|
|
558
558
|
self.s.options.secondaryOnlyConnectionAllowed) ||
|
|
559
559
|
self.s.replicaSetState.hasPrimary())
|
|
560
560
|
) {
|
|
561
|
-
stateTransition(self,
|
|
561
|
+
stateTransition(self, CONNECTING);
|
|
562
562
|
|
|
563
563
|
// Rexecute any stalled operation
|
|
564
564
|
rexecuteOperations(self);
|
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,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const os = require('os');
|
|
3
3
|
const crypto = require('crypto');
|
|
4
|
-
const requireOptional = require('
|
|
4
|
+
const requireOptional = require('optional-require')(require);
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Generate a UUIDv4
|
|
@@ -46,10 +46,7 @@ const noEJSONError = function() {
|
|
|
46
46
|
|
|
47
47
|
// Facilitate loading EJSON optionally
|
|
48
48
|
function retrieveEJSON() {
|
|
49
|
-
let EJSON =
|
|
50
|
-
try {
|
|
51
|
-
EJSON = requireOptional('mongodb-extjson');
|
|
52
|
-
} catch (error) {} // eslint-disable-line
|
|
49
|
+
let EJSON = requireOptional('mongodb-extjson');
|
|
53
50
|
if (!EJSON) {
|
|
54
51
|
EJSON = {
|
|
55
52
|
parse: noEJSONError,
|
|
@@ -45,14 +45,19 @@ function _command(server, ns, cmd, options, callback) {
|
|
|
45
45
|
const shouldUseOpMsg = supportsOpMsg(server);
|
|
46
46
|
const session = options.session;
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
const serverClusterTime = server.clusterTime;
|
|
49
|
+
let clusterTime = serverClusterTime;
|
|
49
50
|
let finalCmd = Object.assign({}, cmd);
|
|
50
51
|
if (hasSessionSupport(server) && session) {
|
|
52
|
+
const sessionClusterTime = session.clusterTime;
|
|
51
53
|
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
serverClusterTime &&
|
|
55
|
+
serverClusterTime.clusterTime &&
|
|
56
|
+
sessionClusterTime &&
|
|
57
|
+
sessionClusterTime.clusterTime &&
|
|
58
|
+
sessionClusterTime.clusterTime.greaterThan(serverClusterTime.clusterTime)
|
|
54
59
|
) {
|
|
55
|
-
clusterTime =
|
|
60
|
+
clusterTime = sessionClusterTime;
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
const err = applySession(session, finalCmd, options);
|
|
@@ -61,8 +66,8 @@ function _command(server, ns, cmd, options, callback) {
|
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
// if we have a known cluster time, gossip it
|
|
65
69
|
if (clusterTime) {
|
|
70
|
+
// if we have a known cluster time, gossip it
|
|
66
71
|
finalCmd.$clusterTime = clusterTime;
|
|
67
72
|
}
|
|
68
73
|
|