mongodb 3.2.5 → 3.3.0-beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/HISTORY.md +0 -10
  2. package/index.js +4 -4
  3. package/lib/admin.js +56 -56
  4. package/lib/aggregation_cursor.js +7 -3
  5. package/lib/bulk/common.js +18 -13
  6. package/lib/change_stream.js +196 -89
  7. package/lib/collection.js +217 -169
  8. package/lib/command_cursor.js +17 -7
  9. package/lib/core/auth/auth_provider.js +158 -0
  10. package/lib/core/auth/defaultAuthProviders.js +29 -0
  11. package/lib/core/auth/gssapi.js +241 -0
  12. package/lib/core/auth/mongo_credentials.js +81 -0
  13. package/lib/core/auth/mongocr.js +51 -0
  14. package/lib/core/auth/plain.js +35 -0
  15. package/lib/core/auth/scram.js +293 -0
  16. package/lib/core/auth/sspi.js +131 -0
  17. package/lib/core/auth/x509.js +26 -0
  18. package/lib/core/connection/apm.js +236 -0
  19. package/lib/core/connection/command_result.js +36 -0
  20. package/lib/core/connection/commands.js +507 -0
  21. package/lib/core/connection/connect.js +370 -0
  22. package/lib/core/connection/connection.js +624 -0
  23. package/lib/core/connection/logger.js +246 -0
  24. package/lib/core/connection/msg.js +219 -0
  25. package/lib/core/connection/pool.js +1285 -0
  26. package/lib/core/connection/utils.js +57 -0
  27. package/lib/core/cursor.js +752 -0
  28. package/lib/core/error.js +186 -0
  29. package/lib/core/index.js +50 -0
  30. package/lib/core/sdam/monitoring.js +228 -0
  31. package/lib/core/sdam/server.js +467 -0
  32. package/lib/core/sdam/server_description.js +163 -0
  33. package/lib/core/sdam/server_selectors.js +244 -0
  34. package/lib/core/sdam/srv_polling.js +135 -0
  35. package/lib/core/sdam/topology.js +1151 -0
  36. package/lib/core/sdam/topology_description.js +408 -0
  37. package/lib/core/sessions.js +711 -0
  38. package/lib/core/tools/smoke_plugin.js +61 -0
  39. package/lib/core/topologies/mongos.js +1337 -0
  40. package/lib/core/topologies/read_preference.js +202 -0
  41. package/lib/core/topologies/replset.js +1507 -0
  42. package/lib/core/topologies/replset_state.js +1121 -0
  43. package/lib/core/topologies/server.js +984 -0
  44. package/lib/core/topologies/shared.js +453 -0
  45. package/lib/core/transactions.js +167 -0
  46. package/lib/core/uri_parser.js +631 -0
  47. package/lib/core/utils.js +165 -0
  48. package/lib/core/wireprotocol/command.js +170 -0
  49. package/lib/core/wireprotocol/compression.js +73 -0
  50. package/lib/core/wireprotocol/constants.js +13 -0
  51. package/lib/core/wireprotocol/get_more.js +86 -0
  52. package/lib/core/wireprotocol/index.js +18 -0
  53. package/lib/core/wireprotocol/kill_cursors.js +70 -0
  54. package/lib/core/wireprotocol/query.js +224 -0
  55. package/lib/core/wireprotocol/shared.js +115 -0
  56. package/lib/core/wireprotocol/write_command.js +50 -0
  57. package/lib/cursor.js +40 -46
  58. package/lib/db.js +141 -95
  59. package/lib/dynamic_loaders.js +32 -0
  60. package/lib/error.js +12 -10
  61. package/lib/gridfs/chunk.js +2 -2
  62. package/lib/gridfs/grid_store.js +31 -25
  63. package/lib/gridfs-stream/index.js +4 -4
  64. package/lib/gridfs-stream/upload.js +1 -1
  65. package/lib/mongo_client.js +37 -15
  66. package/lib/operations/add_user.js +96 -0
  67. package/lib/operations/aggregate.js +24 -13
  68. package/lib/operations/aggregate_operation.js +127 -0
  69. package/lib/operations/bulk_write.js +104 -0
  70. package/lib/operations/close.js +47 -0
  71. package/lib/operations/collection_ops.js +28 -287
  72. package/lib/operations/collections.js +55 -0
  73. package/lib/operations/command.js +120 -0
  74. package/lib/operations/command_v2.js +43 -0
  75. package/lib/operations/common_functions.js +372 -0
  76. package/lib/operations/{mongo_client_ops.js → connect.js} +185 -157
  77. package/lib/operations/count.js +72 -0
  78. package/lib/operations/count_documents.js +46 -0
  79. package/lib/operations/create_collection.js +118 -0
  80. package/lib/operations/create_index.js +92 -0
  81. package/lib/operations/create_indexes.js +61 -0
  82. package/lib/operations/cursor_ops.js +3 -4
  83. package/lib/operations/db_ops.js +15 -12
  84. package/lib/operations/delete_many.js +25 -0
  85. package/lib/operations/delete_one.js +25 -0
  86. package/lib/operations/distinct.js +85 -0
  87. package/lib/operations/drop.js +53 -0
  88. package/lib/operations/drop_index.js +42 -0
  89. package/lib/operations/drop_indexes.js +23 -0
  90. package/lib/operations/estimated_document_count.js +33 -0
  91. package/lib/operations/execute_db_admin_command.js +34 -0
  92. package/lib/operations/execute_operation.js +165 -0
  93. package/lib/operations/explain.js +23 -0
  94. package/lib/operations/find_and_modify.js +98 -0
  95. package/lib/operations/find_one.js +33 -0
  96. package/lib/operations/find_one_and_delete.js +16 -0
  97. package/lib/operations/find_one_and_replace.js +18 -0
  98. package/lib/operations/find_one_and_update.js +19 -0
  99. package/lib/operations/geo_haystack_search.js +79 -0
  100. package/lib/operations/has_next.js +40 -0
  101. package/lib/operations/index_exists.js +39 -0
  102. package/lib/operations/index_information.js +23 -0
  103. package/lib/operations/indexes.js +22 -0
  104. package/lib/operations/insert_many.js +63 -0
  105. package/lib/operations/insert_one.js +75 -0
  106. package/lib/operations/is_capped.js +19 -0
  107. package/lib/operations/list_indexes.js +66 -0
  108. package/lib/operations/map_reduce.js +189 -0
  109. package/lib/operations/next.js +32 -0
  110. package/lib/operations/operation.js +63 -0
  111. package/lib/operations/options_operation.js +32 -0
  112. package/lib/operations/profiling_level.js +31 -0
  113. package/lib/operations/re_index.js +28 -0
  114. package/lib/operations/remove_user.js +52 -0
  115. package/lib/operations/rename.js +61 -0
  116. package/lib/operations/replace_one.js +47 -0
  117. package/lib/operations/set_profiling_level.js +48 -0
  118. package/lib/operations/stats.js +45 -0
  119. package/lib/operations/to_array.js +68 -0
  120. package/lib/operations/update_many.js +29 -0
  121. package/lib/operations/update_one.js +44 -0
  122. package/lib/operations/validate_collection.js +40 -0
  123. package/lib/read_concern.js +55 -0
  124. package/lib/topologies/mongos.js +3 -3
  125. package/lib/topologies/native_topology.js +22 -2
  126. package/lib/topologies/replset.js +3 -3
  127. package/lib/topologies/server.js +4 -4
  128. package/lib/topologies/topology_base.js +6 -6
  129. package/lib/url_parser.js +4 -3
  130. package/lib/utils.js +46 -59
  131. package/lib/write_concern.js +66 -0
  132. package/package.json +15 -6
  133. package/lib/.DS_Store +0 -0
@@ -0,0 +1,186 @@
1
+ 'use strict';
2
+
3
+ const mongoErrorContextSymbol = Symbol('mongoErrorContextSymbol');
4
+
5
+ /**
6
+ * Creates a new MongoError
7
+ *
8
+ * @augments Error
9
+ * @param {Error|string|object} message The error message
10
+ * @property {string} message The error message
11
+ * @property {string} stack The error call stack
12
+ */
13
+ class MongoError extends Error {
14
+ constructor(message) {
15
+ if (message instanceof Error) {
16
+ super(message.message);
17
+ this.stack = message.stack;
18
+ } else {
19
+ if (typeof message === 'string') {
20
+ super(message);
21
+ } else {
22
+ super(message.message || message.errmsg || message.$err || 'n/a');
23
+ for (var name in message) {
24
+ this[name] = message[name];
25
+ }
26
+ }
27
+
28
+ Error.captureStackTrace(this, this.constructor);
29
+ }
30
+
31
+ this.name = 'MongoError';
32
+ this[mongoErrorContextSymbol] = this[mongoErrorContextSymbol] || {};
33
+ }
34
+
35
+ /**
36
+ * Creates a new MongoError object
37
+ *
38
+ * @param {Error|string|object} options The options used to create the error.
39
+ * @return {MongoError} A MongoError instance
40
+ * @deprecated Use `new MongoError()` instead.
41
+ */
42
+ static create(options) {
43
+ return new MongoError(options);
44
+ }
45
+
46
+ hasErrorLabel(label) {
47
+ return this.errorLabels && this.errorLabels.indexOf(label) !== -1;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Creates a new MongoNetworkError
53
+ *
54
+ * @param {Error|string|object} message The error message
55
+ * @property {string} message The error message
56
+ * @property {string} stack The error call stack
57
+ */
58
+ class MongoNetworkError extends MongoError {
59
+ constructor(message) {
60
+ super(message);
61
+ this.name = 'MongoNetworkError';
62
+
63
+ // This is added as part of the transactions specification
64
+ this.errorLabels = ['TransientTransactionError'];
65
+ }
66
+ }
67
+
68
+ /**
69
+ * An error used when attempting to parse a value (like a connection string)
70
+ *
71
+ * @param {Error|string|object} message The error message
72
+ * @property {string} message The error message
73
+ */
74
+ class MongoParseError extends MongoError {
75
+ constructor(message) {
76
+ super(message);
77
+ this.name = 'MongoParseError';
78
+ }
79
+ }
80
+
81
+ /**
82
+ * An error signifying a timeout event
83
+ *
84
+ * @param {Error|string|object} message The error message
85
+ * @property {string} message The error message
86
+ */
87
+ class MongoTimeoutError extends MongoError {
88
+ constructor(message) {
89
+ super(message);
90
+ this.name = 'MongoTimeoutError';
91
+ }
92
+ }
93
+
94
+ function makeWriteConcernResultObject(input) {
95
+ const output = Object.assign({}, input);
96
+
97
+ if (output.ok === 0) {
98
+ output.ok = 1;
99
+ delete output.errmsg;
100
+ delete output.code;
101
+ delete output.codeName;
102
+ }
103
+
104
+ return output;
105
+ }
106
+
107
+ /**
108
+ * An error thrown when the server reports a writeConcernError
109
+ *
110
+ * @param {Error|string|object} message The error message
111
+ * @param {object} result The result document (provided if ok: 1)
112
+ * @property {string} message The error message
113
+ * @property {object} [result] The result document (provided if ok: 1)
114
+ */
115
+ class MongoWriteConcernError extends MongoError {
116
+ constructor(message, result) {
117
+ super(message);
118
+ this.name = 'MongoWriteConcernError';
119
+
120
+ if (result != null) {
121
+ this.result = makeWriteConcernResultObject(result);
122
+ }
123
+ }
124
+ }
125
+
126
+ // see: https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.rst#terms
127
+ const RETRYABLE_ERROR_CODES = new Set([
128
+ 6, // HostUnreachable
129
+ 7, // HostNotFound
130
+ 89, // NetworkTimeout
131
+ 91, // ShutdownInProgress
132
+ 189, // PrimarySteppedDown
133
+ 9001, // SocketException
134
+ 10107, // NotMaster
135
+ 11600, // InterruptedAtShutdown
136
+ 11602, // InterruptedDueToReplStateChange
137
+ 13435, // NotMasterNoSlaveOk
138
+ 13436 // NotMasterOrSecondary
139
+ ]);
140
+
141
+ /**
142
+ * Determines whether an error is something the driver should attempt to retry
143
+ *
144
+ * @param {MongoError|Error} error
145
+ */
146
+ function isRetryableError(error) {
147
+ return (
148
+ RETRYABLE_ERROR_CODES.has(error.code) ||
149
+ error instanceof MongoNetworkError ||
150
+ error.message.match(/not master/) ||
151
+ error.message.match(/node is recovering/)
152
+ );
153
+ }
154
+
155
+ const SDAM_UNRECOVERABLE_ERROR_CODES = new Set([
156
+ 91, // ShutdownInProgress
157
+ 189, // PrimarySteppedDown
158
+ 10107, // NotMaster
159
+ 11600, // InterruptedAtShutdown
160
+ 11602, // InterruptedDueToReplStateChange
161
+ 13435, // NotMasterNoSlaveOk
162
+ 13436 // NotMasterOrSecondary
163
+ ]);
164
+ /**
165
+ * Determines whether an error is a "node is recovering" error or a "not master" error for SDAM retryability.
166
+ * See https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering
167
+ * @param {MongoError|Error} error
168
+ */
169
+ function isSDAMUnrecoverableError(error) {
170
+ return (
171
+ SDAM_UNRECOVERABLE_ERROR_CODES.has(error.code) ||
172
+ (error.message &&
173
+ (error.message.match(/not master/) || error.message.match(/node is recovering/)))
174
+ );
175
+ }
176
+
177
+ module.exports = {
178
+ MongoError,
179
+ MongoNetworkError,
180
+ MongoParseError,
181
+ MongoTimeoutError,
182
+ MongoWriteConcernError,
183
+ mongoErrorContextSymbol,
184
+ isRetryableError,
185
+ isSDAMUnrecoverableError
186
+ };
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ let BSON = require('bson');
4
+ const require_optional = require('require_optional');
5
+ const EJSON = require('./utils').retrieveEJSON();
6
+
7
+ try {
8
+ // Attempt to grab the native BSON parser
9
+ const BSONNative = require_optional('bson-ext');
10
+ // If we got the native parser, use it instead of the
11
+ // Javascript one
12
+ if (BSONNative) {
13
+ BSON = BSONNative;
14
+ }
15
+ } catch (err) {} // eslint-disable-line
16
+
17
+ module.exports = {
18
+ // Errors
19
+ MongoError: require('./error').MongoError,
20
+ MongoNetworkError: require('./error').MongoNetworkError,
21
+ MongoParseError: require('./error').MongoParseError,
22
+ MongoTimeoutError: require('./error').MongoTimeoutError,
23
+ MongoWriteConcernError: require('./error').MongoWriteConcernError,
24
+ mongoErrorContextSymbol: require('./error').mongoErrorContextSymbol,
25
+ // Core
26
+ Connection: require('./connection/connection'),
27
+ Server: require('./topologies/server'),
28
+ ReplSet: require('./topologies/replset'),
29
+ Mongos: require('./topologies/mongos'),
30
+ Logger: require('./connection/logger'),
31
+ Cursor: require('./cursor'),
32
+ ReadPreference: require('./topologies/read_preference'),
33
+ Sessions: require('./sessions'),
34
+ BSON: BSON,
35
+ EJSON: EJSON,
36
+ Topology: require('./sdam/topology'),
37
+ // Raw operations
38
+ Query: require('./connection/commands').Query,
39
+ // Auth mechanisms
40
+ MongoCredentials: require('./auth/mongo_credentials').MongoCredentials,
41
+ defaultAuthProviders: require('./auth/defaultAuthProviders').defaultAuthProviders,
42
+ MongoCR: require('./auth/mongocr'),
43
+ X509: require('./auth/x509'),
44
+ Plain: require('./auth/plain'),
45
+ GSSAPI: require('./auth/gssapi'),
46
+ ScramSHA1: require('./auth/scram').ScramSHA1,
47
+ ScramSHA256: require('./auth/scram').ScramSHA256,
48
+ // Utilities
49
+ parseConnectionString: require('./uri_parser')
50
+ };
@@ -0,0 +1,228 @@
1
+ 'use strict';
2
+
3
+ const ServerDescription = require('./server_description').ServerDescription;
4
+ const calculateDurationInMs = require('../utils').calculateDurationInMs;
5
+
6
+ /**
7
+ * Published when server description changes, but does NOT include changes to the RTT.
8
+ *
9
+ * @property {Object} topologyId A unique identifier for the topology
10
+ * @property {ServerAddress} address The address (host/port pair) of the server
11
+ * @property {ServerDescription} previousDescription The previous server description
12
+ * @property {ServerDescription} newDescription The new server description
13
+ */
14
+ class ServerDescriptionChangedEvent {
15
+ constructor(topologyId, address, previousDescription, newDescription) {
16
+ Object.assign(this, { topologyId, address, previousDescription, newDescription });
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Published when server is initialized.
22
+ *
23
+ * @property {Object} topologyId A unique identifier for the topology
24
+ * @property {ServerAddress} address The address (host/port pair) of the server
25
+ */
26
+ class ServerOpeningEvent {
27
+ constructor(topologyId, address) {
28
+ Object.assign(this, { topologyId, address });
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Published when server is closed.
34
+ *
35
+ * @property {ServerAddress} address The address (host/port pair) of the server
36
+ * @property {Object} topologyId A unique identifier for the topology
37
+ */
38
+ class ServerClosedEvent {
39
+ constructor(topologyId, address) {
40
+ Object.assign(this, { topologyId, address });
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Published when topology description changes.
46
+ *
47
+ * @property {Object} topologyId
48
+ * @property {TopologyDescription} previousDescription The old topology description
49
+ * @property {TopologyDescription} newDescription The new topology description
50
+ */
51
+ class TopologyDescriptionChangedEvent {
52
+ constructor(topologyId, previousDescription, newDescription) {
53
+ Object.assign(this, { topologyId, previousDescription, newDescription });
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Published when topology is initialized.
59
+ *
60
+ * @param {Object} topologyId A unique identifier for the topology
61
+ */
62
+ class TopologyOpeningEvent {
63
+ constructor(topologyId) {
64
+ Object.assign(this, { topologyId });
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Published when topology is closed.
70
+ *
71
+ * @param {Object} topologyId A unique identifier for the topology
72
+ */
73
+ class TopologyClosedEvent {
74
+ constructor(topologyId) {
75
+ Object.assign(this, { topologyId });
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Fired when the server monitor’s ismaster command is started - immediately before
81
+ * the ismaster command is serialized into raw BSON and written to the socket.
82
+ *
83
+ * @property {Object} connectionId The connection id for the command
84
+ */
85
+ class ServerHeartbeatStartedEvent {
86
+ constructor(connectionId) {
87
+ Object.assign(this, { connectionId });
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Fired when the server monitor’s ismaster succeeds.
93
+ *
94
+ * @param {Number} duration The execution time of the event in ms
95
+ * @param {Object} reply The command reply
96
+ * @param {Object} connectionId The connection id for the command
97
+ */
98
+ class ServerHeartbeatSucceededEvent {
99
+ constructor(duration, reply, connectionId) {
100
+ Object.assign(this, { duration, reply, connectionId });
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Fired when the server monitor’s ismaster fails, either with an “ok: 0” or a socket exception.
106
+ *
107
+ * @param {Number} duration The execution time of the event in ms
108
+ * @param {MongoError|Object} failure The command failure
109
+ * @param {Object} connectionId The connection id for the command
110
+ */
111
+ class ServerHeartbeatFailedEvent {
112
+ constructor(duration, failure, connectionId) {
113
+ Object.assign(this, { duration, failure, connectionId });
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Performs a server check as described by the SDAM spec.
119
+ *
120
+ * NOTE: This method automatically reschedules itself, so that there is always an active
121
+ * monitoring process
122
+ *
123
+ * @param {Server} server The server to monitor
124
+ */
125
+ function monitorServer(server, options) {
126
+ options = options || {};
127
+ const heartbeatFrequencyMS = options.heartbeatFrequencyMS || 10000;
128
+
129
+ if (options.initial === true) {
130
+ server.s.monitorId = setTimeout(() => monitorServer(server), heartbeatFrequencyMS);
131
+ return;
132
+ }
133
+
134
+ // executes a single check of a server
135
+ const checkServer = callback => {
136
+ let start = process.hrtime();
137
+
138
+ // emit a signal indicating we have started the heartbeat
139
+ server.emit('serverHeartbeatStarted', new ServerHeartbeatStartedEvent(server.name));
140
+
141
+ // NOTE: legacy monitoring event
142
+ process.nextTick(() => server.emit('monitoring', server));
143
+
144
+ server.command(
145
+ 'admin.$cmd',
146
+ { ismaster: true },
147
+ {
148
+ monitoring: true,
149
+ socketTimeout: server.s.options.connectionTimeout || 2000
150
+ },
151
+ (err, result) => {
152
+ let duration = calculateDurationInMs(start);
153
+
154
+ if (err) {
155
+ server.emit(
156
+ 'serverHeartbeatFailed',
157
+ new ServerHeartbeatFailedEvent(duration, err, server.name)
158
+ );
159
+
160
+ return callback(err, null);
161
+ }
162
+
163
+ const isMaster = result.result;
164
+ server.emit(
165
+ 'serverHeartbeatSucceded',
166
+ new ServerHeartbeatSucceededEvent(duration, isMaster, server.name)
167
+ );
168
+
169
+ return callback(null, isMaster);
170
+ }
171
+ );
172
+ };
173
+
174
+ const successHandler = isMaster => {
175
+ server.s.monitoring = false;
176
+
177
+ // emit an event indicating that our description has changed
178
+ server.emit('descriptionReceived', new ServerDescription(server.description.address, isMaster));
179
+
180
+ // schedule the next monitoring process
181
+ server.s.monitorId = setTimeout(() => monitorServer(server), heartbeatFrequencyMS);
182
+ };
183
+
184
+ // run the actual monitoring loop
185
+ server.s.monitoring = true;
186
+ checkServer((err, isMaster) => {
187
+ if (!err) {
188
+ successHandler(isMaster);
189
+ return;
190
+ }
191
+
192
+ // According to the SDAM specification's "Network error during server check" section, if
193
+ // an ismaster call fails we reset the server's pool. If a server was once connected,
194
+ // change its type to `Unknown` only after retrying once.
195
+ server.s.pool.reset(() => {
196
+ // otherwise re-attempt monitoring once
197
+ checkServer((error, isMaster) => {
198
+ if (error) {
199
+ server.s.monitoring = false;
200
+
201
+ // we revert to an `Unknown` by emitting a default description with no isMaster
202
+ server.emit(
203
+ 'descriptionReceived',
204
+ new ServerDescription(server.description.address, null, { error })
205
+ );
206
+
207
+ // we do not reschedule monitoring in this case
208
+ return;
209
+ }
210
+
211
+ successHandler(isMaster);
212
+ });
213
+ });
214
+ });
215
+ }
216
+
217
+ module.exports = {
218
+ ServerDescriptionChangedEvent,
219
+ ServerOpeningEvent,
220
+ ServerClosedEvent,
221
+ TopologyDescriptionChangedEvent,
222
+ TopologyOpeningEvent,
223
+ TopologyClosedEvent,
224
+ ServerHeartbeatStartedEvent,
225
+ ServerHeartbeatSucceededEvent,
226
+ ServerHeartbeatFailedEvent,
227
+ monitorServer
228
+ };