mongodb 3.5.11 → 3.6.2
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 +42 -21
- package/lib/admin.js +1 -0
- package/lib/bulk/common.js +48 -4
- package/lib/change_stream.js +0 -1
- package/lib/cmap/connection.js +9 -6
- package/lib/cmap/connection_pool.js +4 -10
- package/lib/collection.js +59 -81
- package/lib/core/auth/auth_provider.js +29 -132
- package/lib/core/auth/defaultAuthProviders.js +2 -2
- package/lib/core/auth/gssapi.js +124 -214
- package/lib/core/auth/mongo_credentials.js +29 -3
- package/lib/core/auth/mongocr.js +6 -12
- package/lib/core/auth/mongodb_aws.js +256 -0
- package/lib/core/auth/plain.js +5 -12
- package/lib/core/auth/scram.js +229 -212
- package/lib/core/auth/x509.js +25 -16
- package/lib/core/connection/connect.js +97 -161
- package/lib/core/connection/connection.js +71 -3
- package/lib/core/connection/pool.js +2 -2
- package/lib/core/cursor.js +18 -11
- package/lib/core/error.js +82 -8
- package/lib/core/sdam/common.js +8 -0
- package/lib/core/sdam/monitor.js +240 -78
- package/lib/core/sdam/server.js +81 -15
- package/lib/core/sdam/server_description.js +37 -2
- package/lib/core/sdam/topology.js +41 -8
- package/lib/core/sdam/topology_description.js +21 -3
- package/lib/core/sessions.js +38 -51
- package/lib/core/topologies/mongos.js +18 -6
- package/lib/core/topologies/read_preference.js +15 -3
- package/lib/core/topologies/replset.js +4 -4
- package/lib/core/topologies/server.js +1 -1
- package/lib/core/topologies/shared.js +39 -16
- package/lib/core/uri_parser.js +41 -6
- package/lib/core/utils.js +30 -0
- package/lib/core/wireprotocol/command.js +1 -4
- package/lib/core/wireprotocol/constants.js +2 -2
- package/lib/core/wireprotocol/query.js +4 -0
- package/lib/cursor.js +0 -1
- package/lib/db.js +6 -5
- package/lib/error.js +6 -1
- package/lib/gridfs-stream/download.js +13 -2
- package/lib/mongo_client.js +6 -4
- package/lib/operations/collection_ops.js +0 -20
- package/lib/operations/command_v2.js +1 -1
- package/lib/operations/common_functions.js +3 -0
- package/lib/operations/connect.js +11 -14
- package/lib/operations/create_collection.js +37 -52
- package/lib/operations/create_indexes.js +111 -35
- package/lib/operations/find.js +7 -1
- package/lib/operations/find_and_modify.js +17 -0
- package/lib/operations/find_one_and_delete.js +5 -0
- package/lib/operations/find_one_and_replace.js +13 -0
- package/lib/operations/find_one_and_update.js +13 -0
- package/lib/operations/map_reduce.js +1 -1
- package/lib/operations/re_index.js +22 -17
- package/lib/operations/replace_one.js +11 -4
- package/lib/operations/update_many.js +5 -0
- package/lib/operations/update_one.js +5 -0
- package/lib/operations/validate_collection.js +1 -2
- package/lib/topologies/mongos.js +1 -1
- package/lib/topologies/replset.js +1 -1
- package/lib/topologies/server.js +1 -1
- package/lib/utils.js +18 -1
- package/lib/write_concern.js +10 -0
- package/package.json +1 -1
- package/lib/core/auth/sspi.js +0 -131
- package/lib/operations/create_index.js +0 -92
|
@@ -2,60 +2,136 @@
|
|
|
2
2
|
|
|
3
3
|
const Aspect = require('./operation').Aspect;
|
|
4
4
|
const defineAspects = require('./operation').defineAspects;
|
|
5
|
-
const
|
|
6
|
-
const executeCommand = require('./db_ops').executeCommand;
|
|
5
|
+
const CommandOperationV2 = require('./command_v2');
|
|
7
6
|
const MongoError = require('../core').MongoError;
|
|
8
|
-
const
|
|
7
|
+
const parseIndexOptions = require('../utils').parseIndexOptions;
|
|
8
|
+
const maxWireVersion = require('../core/utils').maxWireVersion;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const VALID_INDEX_OPTIONS = new Set([
|
|
11
|
+
'background',
|
|
12
|
+
'unique',
|
|
13
|
+
'name',
|
|
14
|
+
'partialFilterExpression',
|
|
15
|
+
'sparse',
|
|
16
|
+
'expireAfterSeconds',
|
|
17
|
+
'storageEngine',
|
|
18
|
+
'collation',
|
|
13
19
|
|
|
20
|
+
// text indexes
|
|
21
|
+
'weights',
|
|
22
|
+
'default_language',
|
|
23
|
+
'language_override',
|
|
24
|
+
'textIndexVersion',
|
|
25
|
+
|
|
26
|
+
// 2d-sphere indexes
|
|
27
|
+
'2dsphereIndexVersion',
|
|
28
|
+
|
|
29
|
+
// 2d indexes
|
|
30
|
+
'bits',
|
|
31
|
+
'min',
|
|
32
|
+
'max',
|
|
33
|
+
|
|
34
|
+
// geoHaystack Indexes
|
|
35
|
+
'bucketSize',
|
|
36
|
+
|
|
37
|
+
// wildcard indexes
|
|
38
|
+
'wildcardProjection'
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
class CreateIndexesOperation extends CommandOperationV2 {
|
|
42
|
+
/**
|
|
43
|
+
* @ignore
|
|
44
|
+
*/
|
|
45
|
+
constructor(parent, collection, indexes, options) {
|
|
46
|
+
super(parent, options);
|
|
14
47
|
this.collection = collection;
|
|
15
|
-
|
|
48
|
+
|
|
49
|
+
// createIndex can be called with a variety of styles:
|
|
50
|
+
// coll.createIndex('a');
|
|
51
|
+
// coll.createIndex({ a: 1 });
|
|
52
|
+
// coll.createIndex([['a', 1]]);
|
|
53
|
+
// createIndexes is always called with an array of index spec objects
|
|
54
|
+
if (!Array.isArray(indexes) || Array.isArray(indexes[0])) {
|
|
55
|
+
this.onlyReturnNameOfCreatedIndex = true;
|
|
56
|
+
// TODO: remove in v4 (breaking change); make createIndex return full response as createIndexes does
|
|
57
|
+
|
|
58
|
+
const indexParameters = parseIndexOptions(indexes);
|
|
59
|
+
// Generate the index name
|
|
60
|
+
const name = typeof options.name === 'string' ? options.name : indexParameters.name;
|
|
61
|
+
// Set up the index
|
|
62
|
+
const indexSpec = { name, key: indexParameters.fieldHash };
|
|
63
|
+
// merge valid index options into the index spec
|
|
64
|
+
for (let optionName in options) {
|
|
65
|
+
if (VALID_INDEX_OPTIONS.has(optionName)) {
|
|
66
|
+
indexSpec[optionName] = options[optionName];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
this.indexes = [indexSpec];
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.indexes = indexes;
|
|
16
74
|
}
|
|
17
75
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
76
|
+
/**
|
|
77
|
+
* @ignore
|
|
78
|
+
*/
|
|
79
|
+
execute(server, callback) {
|
|
80
|
+
const options = this.options;
|
|
81
|
+
const indexes = this.indexes;
|
|
22
82
|
|
|
23
|
-
const
|
|
83
|
+
const serverWireVersion = maxWireVersion(server);
|
|
24
84
|
|
|
25
85
|
// Ensure we generate the correct name if the parameter is not set
|
|
26
|
-
for (let i = 0; i <
|
|
27
|
-
if
|
|
28
|
-
|
|
86
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
87
|
+
// Did the user pass in a collation, check if our write server supports it
|
|
88
|
+
if (indexes[i].collation && serverWireVersion < 5) {
|
|
89
|
+
callback(
|
|
90
|
+
new MongoError(
|
|
91
|
+
`Server ${server.name}, which reports wire version ${serverWireVersion}, does not support collation`
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
29
96
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return callback(new MongoError('server/primary/mongos does not support collation'));
|
|
33
|
-
}
|
|
97
|
+
if (indexes[i].name == null) {
|
|
98
|
+
const keys = [];
|
|
34
99
|
|
|
35
|
-
for (let name in
|
|
36
|
-
keys.push(`${name}_${
|
|
100
|
+
for (let name in indexes[i].key) {
|
|
101
|
+
keys.push(`${name}_${indexes[i].key[name]}`);
|
|
37
102
|
}
|
|
38
103
|
|
|
39
104
|
// Set the name
|
|
40
|
-
|
|
105
|
+
indexes[i].name = keys.join('_');
|
|
41
106
|
}
|
|
42
107
|
}
|
|
43
108
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
options
|
|
54
|
-
|
|
55
|
-
|
|
109
|
+
const cmd = { createIndexes: this.collection, indexes };
|
|
110
|
+
|
|
111
|
+
if (options.commitQuorum != null) {
|
|
112
|
+
if (serverWireVersion < 9) {
|
|
113
|
+
callback(
|
|
114
|
+
new MongoError('`commitQuorum` option for `createIndexes` not supported on servers < 4.4')
|
|
115
|
+
);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
cmd.commitQuorum = options.commitQuorum;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// collation is set on each index, it should not be defined at the root
|
|
122
|
+
this.options.collation = undefined;
|
|
123
|
+
|
|
124
|
+
super.executeCommand(server, cmd, (err, result) => {
|
|
125
|
+
if (err) {
|
|
126
|
+
callback(err);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
callback(null, this.onlyReturnNameOfCreatedIndex ? indexes[0].name : result);
|
|
131
|
+
});
|
|
56
132
|
}
|
|
57
133
|
}
|
|
58
134
|
|
|
59
|
-
defineAspects(CreateIndexesOperation, Aspect.WRITE_OPERATION);
|
|
135
|
+
defineAspects(CreateIndexesOperation, [Aspect.WRITE_OPERATION, Aspect.EXECUTE_WITH_SELECTION]);
|
|
60
136
|
|
|
61
137
|
module.exports = CreateIndexesOperation;
|
package/lib/operations/find.js
CHANGED
|
@@ -4,6 +4,8 @@ const OperationBase = require('./operation').OperationBase;
|
|
|
4
4
|
const Aspect = require('./operation').Aspect;
|
|
5
5
|
const defineAspects = require('./operation').defineAspects;
|
|
6
6
|
const ReadPreference = require('../core').ReadPreference;
|
|
7
|
+
const maxWireVersion = require('../core/utils').maxWireVersion;
|
|
8
|
+
const MongoError = require('../core/error').MongoError;
|
|
7
9
|
|
|
8
10
|
class FindOperation extends OperationBase {
|
|
9
11
|
constructor(collection, ns, command, options) {
|
|
@@ -18,9 +20,13 @@ class FindOperation extends OperationBase {
|
|
|
18
20
|
// copied from `CommandOperationV2`, to be subclassed in the future
|
|
19
21
|
this.server = server;
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
if (typeof this.cmd.allowDiskUse !== 'undefined' && maxWireVersion(server) < 4) {
|
|
24
|
+
callback(new MongoError('The `allowDiskUse` option is not supported on MongoDB < 3.2'));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
22
27
|
|
|
23
28
|
// TOOD: use `MongoDBNamespace` through and through
|
|
29
|
+
const cursorState = this.cursorState || {};
|
|
24
30
|
server.query(this.ns.toString(), this.cmd, cursorState, this.options, callback);
|
|
25
31
|
}
|
|
26
32
|
}
|
|
@@ -8,6 +8,8 @@ const executeCommand = require('./db_ops').executeCommand;
|
|
|
8
8
|
const formattedOrderClause = require('../utils').formattedOrderClause;
|
|
9
9
|
const handleCallback = require('../utils').handleCallback;
|
|
10
10
|
const ReadPreference = require('../core').ReadPreference;
|
|
11
|
+
const maxWireVersion = require('../core/utils').maxWireVersion;
|
|
12
|
+
const MongoError = require('../error').MongoError;
|
|
11
13
|
|
|
12
14
|
class FindAndModifyOperation extends OperationBase {
|
|
13
15
|
constructor(collection, query, sort, doc, options) {
|
|
@@ -86,6 +88,21 @@ class FindAndModifyOperation extends OperationBase {
|
|
|
86
88
|
return callback(err, null);
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
if (options.hint) {
|
|
92
|
+
// TODO: once this method becomes a CommandOperationV2 we will have the server
|
|
93
|
+
// in place to check.
|
|
94
|
+
const unacknowledgedWrite = options.writeConcern && options.writeConcern.w === 0;
|
|
95
|
+
if (unacknowledgedWrite || maxWireVersion(coll.s.topology) < 8) {
|
|
96
|
+
callback(
|
|
97
|
+
new MongoError('The current topology does not support a hint on findAndModify commands')
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
queryObject.hint = options.hint;
|
|
104
|
+
}
|
|
105
|
+
|
|
89
106
|
// Execute the command
|
|
90
107
|
executeCommand(coll.s.db, queryObject, options, (err, result) => {
|
|
91
108
|
if (err) return handleCallback(callback, err, null);
|
|
@@ -9,6 +9,11 @@ class FindOneAndDeleteOperation extends FindAndModifyOperation {
|
|
|
9
9
|
finalOptions.fields = options.projection;
|
|
10
10
|
finalOptions.remove = true;
|
|
11
11
|
|
|
12
|
+
// Basic validation
|
|
13
|
+
if (filter == null || typeof filter !== 'object') {
|
|
14
|
+
throw new TypeError('Filter parameter must be an object');
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
super(collection, filter, finalOptions.sort, null, finalOptions);
|
|
13
18
|
}
|
|
14
19
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const FindAndModifyOperation = require('./find_and_modify');
|
|
4
|
+
const hasAtomicOperators = require('../utils').hasAtomicOperators;
|
|
4
5
|
|
|
5
6
|
class FindOneAndReplaceOperation extends FindAndModifyOperation {
|
|
6
7
|
constructor(collection, filter, replacement, options) {
|
|
@@ -11,6 +12,18 @@ class FindOneAndReplaceOperation extends FindAndModifyOperation {
|
|
|
11
12
|
finalOptions.new = options.returnOriginal !== void 0 ? !options.returnOriginal : false;
|
|
12
13
|
finalOptions.upsert = options.upsert !== void 0 ? !!options.upsert : false;
|
|
13
14
|
|
|
15
|
+
if (filter == null || typeof filter !== 'object') {
|
|
16
|
+
throw new TypeError('Filter parameter must be an object');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (replacement == null || typeof replacement !== 'object') {
|
|
20
|
+
throw new TypeError('Replacement parameter must be an object');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (hasAtomicOperators(replacement)) {
|
|
24
|
+
throw new TypeError('Replacement document must not contain atomic operators');
|
|
25
|
+
}
|
|
26
|
+
|
|
14
27
|
super(collection, filter, finalOptions.sort, replacement, finalOptions);
|
|
15
28
|
}
|
|
16
29
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const FindAndModifyOperation = require('./find_and_modify');
|
|
4
|
+
const hasAtomicOperators = require('../utils').hasAtomicOperators;
|
|
4
5
|
|
|
5
6
|
class FindOneAndUpdateOperation extends FindAndModifyOperation {
|
|
6
7
|
constructor(collection, filter, update, options) {
|
|
@@ -12,6 +13,18 @@ class FindOneAndUpdateOperation extends FindAndModifyOperation {
|
|
|
12
13
|
typeof options.returnOriginal === 'boolean' ? !options.returnOriginal : false;
|
|
13
14
|
finalOptions.upsert = typeof options.upsert === 'boolean' ? options.upsert : false;
|
|
14
15
|
|
|
16
|
+
if (filter == null || typeof filter !== 'object') {
|
|
17
|
+
throw new TypeError('Filter parameter must be an object');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (update == null || typeof update !== 'object') {
|
|
21
|
+
throw new TypeError('Update parameter must be an object');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!hasAtomicOperators(update)) {
|
|
25
|
+
throw new TypeError('Update document requires atomic operators');
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
super(collection, filter, finalOptions.sort, update, finalOptions);
|
|
16
29
|
}
|
|
17
30
|
}
|
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const Aspect = require('./operation').Aspect;
|
|
4
|
+
const defineAspects = require('./operation').defineAspects;
|
|
5
|
+
const CommandOperationV2 = require('./command_v2');
|
|
6
|
+
const serverType = require('../core/sdam/common').serverType;
|
|
7
|
+
const ServerType = require('../core/sdam/common').ServerType;
|
|
8
|
+
const MongoError = require('../core').MongoError;
|
|
5
9
|
|
|
6
|
-
class ReIndexOperation extends
|
|
10
|
+
class ReIndexOperation extends CommandOperationV2 {
|
|
7
11
|
constructor(collection, options) {
|
|
8
|
-
super(collection
|
|
12
|
+
super(collection, options);
|
|
13
|
+
this.collectionName = collection.collectionName;
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (err) return handleCallback(callback, err, null);
|
|
23
|
-
handleCallback(callback, null, result.ok ? true : false);
|
|
16
|
+
execute(server, callback) {
|
|
17
|
+
if (serverType(server) !== ServerType.Standalone) {
|
|
18
|
+
callback(new MongoError(`reIndex can only be executed on standalone servers.`));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
super.executeCommand(server, { reIndex: this.collectionName }, (err, result) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
callback(err);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
callback(null, !!result.ok);
|
|
24
27
|
});
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
defineAspects(ReIndexOperation, [Aspect.EXECUTE_WITH_SELECTION]);
|
|
32
|
+
|
|
28
33
|
module.exports = ReIndexOperation;
|
|
@@ -2,27 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
const OperationBase = require('./operation').OperationBase;
|
|
4
4
|
const updateDocuments = require('./common_functions').updateDocuments;
|
|
5
|
+
const hasAtomicOperators = require('../utils').hasAtomicOperators;
|
|
5
6
|
|
|
6
7
|
class ReplaceOneOperation extends OperationBase {
|
|
7
|
-
constructor(collection, filter,
|
|
8
|
+
constructor(collection, filter, replacement, options) {
|
|
8
9
|
super(options);
|
|
9
10
|
|
|
11
|
+
if (hasAtomicOperators(replacement)) {
|
|
12
|
+
throw new TypeError('Replacement document must not contain atomic operators');
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
this.collection = collection;
|
|
11
16
|
this.filter = filter;
|
|
12
|
-
this.
|
|
17
|
+
this.replacement = replacement;
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
execute(callback) {
|
|
16
21
|
const coll = this.collection;
|
|
17
22
|
const filter = this.filter;
|
|
18
|
-
const
|
|
23
|
+
const replacement = this.replacement;
|
|
19
24
|
const options = this.options;
|
|
20
25
|
|
|
21
26
|
// Set single document update
|
|
22
27
|
options.multi = false;
|
|
23
28
|
|
|
24
29
|
// Execute update
|
|
25
|
-
updateDocuments(coll, filter,
|
|
30
|
+
updateDocuments(coll, filter, replacement, options, (err, r) =>
|
|
31
|
+
replaceCallback(err, r, replacement, callback)
|
|
32
|
+
);
|
|
26
33
|
}
|
|
27
34
|
}
|
|
28
35
|
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
const OperationBase = require('./operation').OperationBase;
|
|
4
4
|
const updateCallback = require('./common_functions').updateCallback;
|
|
5
5
|
const updateDocuments = require('./common_functions').updateDocuments;
|
|
6
|
+
const hasAtomicOperators = require('../utils').hasAtomicOperators;
|
|
6
7
|
|
|
7
8
|
class UpdateManyOperation extends OperationBase {
|
|
8
9
|
constructor(collection, filter, update, options) {
|
|
9
10
|
super(options);
|
|
10
11
|
|
|
12
|
+
if (!hasAtomicOperators(update)) {
|
|
13
|
+
throw new TypeError('Update document requires atomic operators');
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
this.collection = collection;
|
|
12
17
|
this.filter = filter;
|
|
13
18
|
this.update = update;
|
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
const OperationBase = require('./operation').OperationBase;
|
|
4
4
|
const updateDocuments = require('./common_functions').updateDocuments;
|
|
5
|
+
const hasAtomicOperators = require('../utils').hasAtomicOperators;
|
|
5
6
|
|
|
6
7
|
class UpdateOneOperation extends OperationBase {
|
|
7
8
|
constructor(collection, filter, update, options) {
|
|
8
9
|
super(options);
|
|
9
10
|
|
|
11
|
+
if (!hasAtomicOperators(update)) {
|
|
12
|
+
throw new TypeError('Update document requires atomic operators');
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
this.collection = collection;
|
|
11
16
|
this.filter = filter;
|
|
12
17
|
this.update = update;
|
package/lib/topologies/mongos.js
CHANGED
|
@@ -82,7 +82,7 @@ var legalOptionNames = [
|
|
|
82
82
|
* @param {object} [options.socketOptions] Socket options
|
|
83
83
|
* @param {boolean} [options.socketOptions.noDelay=true] TCP Socket NoDelay option.
|
|
84
84
|
* @param {boolean} [options.socketOptions.keepAlive=true] TCP Connection keep alive enabled
|
|
85
|
-
* @param {number} [options.socketOptions.keepAliveInitialDelay=
|
|
85
|
+
* @param {number} [options.socketOptions.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
86
86
|
* @param {number} [options.socketOptions.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
87
87
|
* @param {number} [options.socketOptions.socketTimeoutMS=360000] How long a send or receive on a socket can take before timing out
|
|
88
88
|
* @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit.
|
|
@@ -92,7 +92,7 @@ var legalOptionNames = [
|
|
|
92
92
|
* @param {object} [options.socketOptions] Socket options
|
|
93
93
|
* @param {boolean} [options.socketOptions.noDelay=true] TCP Socket NoDelay option.
|
|
94
94
|
* @param {boolean} [options.socketOptions.keepAlive=true] TCP Connection keep alive enabled
|
|
95
|
-
* @param {number} [options.socketOptions.keepAliveInitialDelay=
|
|
95
|
+
* @param {number} [options.socketOptions.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
96
96
|
* @param {number} [options.socketOptions.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
97
97
|
* @param {number} [options.socketOptions.socketTimeoutMS=360000] How long a send or receive on a socket can take before timing out
|
|
98
98
|
* @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit.
|
package/lib/topologies/server.js
CHANGED
|
@@ -84,7 +84,7 @@ var legalOptionNames = [
|
|
|
84
84
|
* @param {boolean} [options.socketOptions.autoReconnect=true] Reconnect on error.
|
|
85
85
|
* @param {boolean} [options.socketOptions.noDelay=true] TCP Socket NoDelay option.
|
|
86
86
|
* @param {boolean} [options.socketOptions.keepAlive=true] TCP Connection keep alive enabled
|
|
87
|
-
* @param {number} [options.socketOptions.keepAliveInitialDelay=
|
|
87
|
+
* @param {number} [options.socketOptions.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
|
|
88
88
|
* @param {number} [options.socketOptions.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
|
|
89
89
|
* @param {number} [options.socketOptions.socketTimeoutMS=360000] How long a send or receive on a socket can take before timing out
|
|
90
90
|
* @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
|
package/lib/utils.js
CHANGED
|
@@ -721,6 +721,12 @@ function makeInterruptableAsyncInterval(fn, options) {
|
|
|
721
721
|
const timeUntilNextCall = Math.max(interval - timeSinceLastCall, 0);
|
|
722
722
|
lastWakeTime = currentTime;
|
|
723
723
|
|
|
724
|
+
// For the streaming protocol: there is nothing obviously stopping this
|
|
725
|
+
// interval from being woken up again while we are waiting "infinitely"
|
|
726
|
+
// for `fn` to be called again`. Since the function effectively
|
|
727
|
+
// never completes, the `timeUntilNextCall` will continue to grow
|
|
728
|
+
// negatively unbounded, so it will never trigger a reschedule here.
|
|
729
|
+
|
|
724
730
|
// debounce multiple calls to wake within the `minInterval`
|
|
725
731
|
if (timeSinceLastWake < minInterval) {
|
|
726
732
|
return;
|
|
@@ -753,6 +759,7 @@ function makeInterruptableAsyncInterval(fn, options) {
|
|
|
753
759
|
function executeAndReschedule() {
|
|
754
760
|
lastWakeTime = 0;
|
|
755
761
|
lastCallTime = now();
|
|
762
|
+
|
|
756
763
|
fn(err => {
|
|
757
764
|
if (err) throw err;
|
|
758
765
|
reschedule(interval);
|
|
@@ -769,6 +776,15 @@ function makeInterruptableAsyncInterval(fn, options) {
|
|
|
769
776
|
return { wake, stop };
|
|
770
777
|
}
|
|
771
778
|
|
|
779
|
+
function hasAtomicOperators(doc) {
|
|
780
|
+
if (Array.isArray(doc)) {
|
|
781
|
+
return doc.reduce((err, u) => err || hasAtomicOperators(u), null);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
const keys = Object.keys(doc);
|
|
785
|
+
return keys.length > 0 && keys[0][0] === '$';
|
|
786
|
+
}
|
|
787
|
+
|
|
772
788
|
module.exports = {
|
|
773
789
|
filterOptions,
|
|
774
790
|
mergeOptions,
|
|
@@ -800,5 +816,6 @@ module.exports = {
|
|
|
800
816
|
maybePromise,
|
|
801
817
|
now,
|
|
802
818
|
calculateDurationInMs,
|
|
803
|
-
makeInterruptableAsyncInterval
|
|
819
|
+
makeInterruptableAsyncInterval,
|
|
820
|
+
hasAtomicOperators
|
|
804
821
|
};
|
package/lib/write_concern.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const kWriteConcernKeys = new Set(['w', 'wtimeout', 'j', 'fsync']);
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* The **WriteConcern** class is a class that represents a MongoDB WriteConcern.
|
|
5
7
|
* @class
|
|
@@ -51,6 +53,14 @@ class WriteConcern {
|
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
if (options.writeConcern) {
|
|
56
|
+
if (typeof options.writeConcern === 'string') {
|
|
57
|
+
return new WriteConcern(options.writeConcern);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!Object.keys(options.writeConcern).some(key => kWriteConcernKeys.has(key))) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
return new WriteConcern(
|
|
55
65
|
options.writeConcern.w,
|
|
56
66
|
options.writeConcern.wtimeout,
|