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
package/lib/db.js CHANGED
@@ -7,41 +7,47 @@ const CommandCursor = require('./command_cursor');
7
7
  const handleCallback = require('./utils').handleCallback;
8
8
  const filterOptions = require('./utils').filterOptions;
9
9
  const toError = require('./utils').toError;
10
- const ReadPreference = require('mongodb-core').ReadPreference;
11
- const MongoError = require('mongodb-core').MongoError;
12
- const ObjectID = require('mongodb-core').ObjectID;
13
- const Logger = require('mongodb-core').Logger;
10
+ const ReadPreference = require('./core').ReadPreference;
11
+ const MongoError = require('./core').MongoError;
12
+ const ObjectID = require('./core').ObjectID;
13
+ const Logger = require('./core').Logger;
14
14
  const Collection = require('./collection');
15
15
  const mergeOptionsAndWriteConcern = require('./utils').mergeOptionsAndWriteConcern;
16
- const executeOperation = require('./utils').executeOperation;
17
- const applyWriteConcern = require('./utils').applyWriteConcern;
16
+ const executeLegacyOperation = require('./utils').executeLegacyOperation;
18
17
  const resolveReadPreference = require('./utils').resolveReadPreference;
19
18
  const ChangeStream = require('./change_stream');
20
19
  const deprecate = require('util').deprecate;
21
20
  const deprecateOptions = require('./utils').deprecateOptions;
21
+ const MongoDBNamespace = require('./utils').MongoDBNamespace;
22
22
  const CONSTANTS = require('./constants');
23
+ const WriteConcern = require('./write_concern');
24
+ const ReadConcern = require('./read_concern');
23
25
 
24
26
  // Operations
25
- const addUser = require('./operations/db_ops').addUser;
26
27
  const aggregate = require('./operations/aggregate').aggregate;
27
- const collections = require('./operations/db_ops').collections;
28
- const createCollection = require('./operations/db_ops').createCollection;
29
- const createIndex = require('./operations/db_ops').createIndex;
30
28
  const createListener = require('./operations/db_ops').createListener;
31
- const dropCollection = require('./operations/db_ops').dropCollection;
32
- const dropDatabase = require('./operations/db_ops').dropDatabase;
33
29
  const ensureIndex = require('./operations/db_ops').ensureIndex;
34
30
  const evaluate = require('./operations/db_ops').evaluate;
35
- const executeCommand = require('./operations/db_ops').executeCommand;
36
- const executeDbAdminCommand = require('./operations/db_ops').executeDbAdminCommand;
37
- const indexInformation = require('./operations/db_ops').indexInformation;
38
31
  const listCollectionsTransforms = require('./operations/db_ops').listCollectionsTransforms;
39
32
  const profilingInfo = require('./operations/db_ops').profilingInfo;
40
- const profilingLevel = require('./operations/db_ops').profilingLevel;
41
- const removeUser = require('./operations/db_ops').removeUser;
42
- const setProfilingLevel = require('./operations/db_ops').setProfilingLevel;
43
33
  const validateDatabaseName = require('./operations/db_ops').validateDatabaseName;
44
34
 
35
+ const AddUserOperation = require('./operations/add_user');
36
+ const CollectionsOperation = require('./operations/collections');
37
+ const CommandOperation = require('./operations/command');
38
+ const CreateCollectionOperation = require('./operations/create_collection');
39
+ const CreateIndexOperation = require('./operations/create_index');
40
+ const DropCollectionOperation = require('./operations/drop').DropCollectionOperation;
41
+ const DropDatabaseOperation = require('./operations/drop').DropDatabaseOperation;
42
+ const ExecuteDbAdminCommandOperation = require('./operations/execute_db_admin_command');
43
+ const IndexInformationOperation = require('./operations/index_information');
44
+ const ProfilingLevelOperation = require('./operations/profiling_level');
45
+ const RemoveUserOperation = require('./operations/remove_user');
46
+ const RenameOperation = require('./operations/rename');
47
+ const SetProfilingLevelOperation = require('./operations/set_profiling_level');
48
+
49
+ const executeOperation = require('./operations/execute_operation');
50
+
45
51
  /**
46
52
  * @fileOverview The **Db** class is a class that represents a MongoDB Database.
47
53
  *
@@ -146,8 +152,6 @@ function Db(databaseName, topology, options) {
146
152
 
147
153
  // Internal state of the db object
148
154
  this.s = {
149
- // Database name
150
- databaseName: databaseName,
151
155
  // DbCache
152
156
  dbCache: {},
153
157
  // Children db's
@@ -161,7 +165,7 @@ function Db(databaseName, topology, options) {
161
165
  // Get the bson parser
162
166
  bson: topology ? topology.bson : null,
163
167
  // Unpack read preference
164
- readPreference: options.readPreference,
168
+ readPreference: ReadPreference.fromOptions(options),
165
169
  // Set buffermaxEntries
166
170
  bufferMaxEntries: typeof options.bufferMaxEntries === 'number' ? options.bufferMaxEntries : -1,
167
171
  // Parent db (if chained)
@@ -175,16 +179,19 @@ function Db(databaseName, topology, options) {
175
179
  // No listener
176
180
  noListener: typeof options.noListener === 'boolean' ? options.noListener : false,
177
181
  // ReadConcern
178
- readConcern: options.readConcern
182
+ readConcern: ReadConcern.fromOptions(options),
183
+ writeConcern: WriteConcern.fromOptions(options),
184
+ // Namespace
185
+ namespace: new MongoDBNamespace(databaseName)
179
186
  };
180
187
 
181
188
  // Ensure we have a valid db name
182
- validateDatabaseName(this.s.databaseName);
189
+ validateDatabaseName(databaseName);
183
190
 
184
191
  // Add a read Only property
185
192
  getSingleProperty(this, 'serverConfig', this.s.topology);
186
193
  getSingleProperty(this, 'bufferMaxEntries', this.s.bufferMaxEntries);
187
- getSingleProperty(this, 'databaseName', this.s.databaseName);
194
+ getSingleProperty(this, 'databaseName', this.s.namespace.db);
188
195
 
189
196
  // This is a child db, do not register any listeners
190
197
  if (options.parentDb) return;
@@ -234,16 +241,37 @@ Object.defineProperty(Db.prototype, 'slaveOk', {
234
241
  }
235
242
  });
236
243
 
244
+ Object.defineProperty(Db.prototype, 'readConcern', {
245
+ enumerable: true,
246
+ get: function() {
247
+ return this.s.readConcern;
248
+ }
249
+ });
250
+
251
+ Object.defineProperty(Db.prototype, 'readPreference', {
252
+ enumerable: true,
253
+ get: function() {
254
+ if (this.s.readPreference == null) {
255
+ // TODO: check client
256
+ return ReadPreference.primary;
257
+ }
258
+
259
+ return this.s.readPreference;
260
+ }
261
+ });
262
+
237
263
  // get the write Concern
238
264
  Object.defineProperty(Db.prototype, 'writeConcern', {
239
265
  enumerable: true,
240
266
  get: function() {
241
- const ops = {};
242
- if (this.s.options.w != null) ops.w = this.s.options.w;
243
- if (this.s.options.j != null) ops.j = this.s.options.j;
244
- if (this.s.options.fsync != null) ops.fsync = this.s.options.fsync;
245
- if (this.s.options.wtimeout != null) ops.wtimeout = this.s.options.wtimeout;
246
- return ops;
267
+ return this.s.writeConcern;
268
+ }
269
+ });
270
+
271
+ Object.defineProperty(Db.prototype, 'namespace', {
272
+ enumerable: true,
273
+ get: function() {
274
+ return this.s.namespace.toString();
247
275
  }
248
276
  });
249
277
 
@@ -261,7 +289,9 @@ Db.prototype.command = function(command, options, callback) {
261
289
  if (typeof options === 'function') (callback = options), (options = {});
262
290
  options = Object.assign({}, options);
263
291
 
264
- return executeOperation(this.s.topology, executeCommand, [this, command, options, callback]);
292
+ const commandOperation = new CommandOperation(this, options, null, command);
293
+
294
+ return executeOperation(this.s.topology, commandOperation, callback);
265
295
  };
266
296
 
267
297
  /**
@@ -368,7 +398,9 @@ Db.prototype.collection = function(name, options, callback) {
368
398
  options.promiseLibrary = this.s.promiseLibrary;
369
399
 
370
400
  // If we have not set a collection level readConcern set the db level one
371
- options.readConcern = options.readConcern || this.s.readConcern;
401
+ options.readConcern = options.readConcern
402
+ ? new ReadConcern(options.readConcern.level)
403
+ : this.readConcern;
372
404
 
373
405
  // Do we have ignoreUndefined set
374
406
  if (this.s.options.ignoreUndefined) {
@@ -384,7 +416,7 @@ Db.prototype.collection = function(name, options, callback) {
384
416
  const collection = new Collection(
385
417
  this,
386
418
  this.s.topology,
387
- this.s.databaseName,
419
+ this.databaseName,
388
420
  name,
389
421
  this.s.pkFactory,
390
422
  options
@@ -423,7 +455,7 @@ Db.prototype.collection = function(name, options, callback) {
423
455
  return handleCallback(
424
456
  callback,
425
457
  null,
426
- new Collection(this, this.s.topology, this.s.databaseName, name, this.s.pkFactory, options)
458
+ new Collection(this, this.s.topology, this.databaseName, name, this.s.pkFactory, options)
427
459
  );
428
460
  } catch (err) {
429
461
  return handleCallback(callback, err, null);
@@ -473,8 +505,12 @@ Db.prototype.createCollection = deprecateOptions(
473
505
  if (typeof options === 'function') (callback = options), (options = {});
474
506
  options = options || {};
475
507
  options.promiseLibrary = options.promiseLibrary || this.s.promiseLibrary;
508
+ options.readConcern = options.readConcern
509
+ ? new ReadConcern(options.readConcern.level)
510
+ : this.readConcern;
511
+ const createCollectionOperation = new CreateCollectionOperation(this, name, options);
476
512
 
477
- return executeOperation(this.s.topology, createCollection, [this, name, options, callback]);
513
+ return executeOperation(this.s.topology, createCollectionOperation, callback);
478
514
  }
479
515
  );
480
516
 
@@ -501,8 +537,10 @@ Db.prototype.stats = function(options, callback) {
501
537
  options.readPreference = this.s.readPreference;
502
538
  }
503
539
 
540
+ const statsOperation = new CommandOperation(this, options, null, commandObject);
541
+
504
542
  // Execute the command
505
- return this.command(commandObject, options, callback);
543
+ return executeOperation(this.s.topology, statsOperation, callback);
506
544
  };
507
545
 
508
546
  /**
@@ -527,10 +565,7 @@ Db.prototype.listCollections = function(filter, options) {
527
565
  options.promiseLibrary = this.s.promiseLibrary;
528
566
 
529
567
  // Ensure valid readPreference
530
- options.readPreference = resolveReadPreference(options, {
531
- db: this,
532
- default: ReadPreference.primary
533
- });
568
+ options.readPreference = resolveReadPreference(this, options);
534
569
 
535
570
  // Cursor options
536
571
  let cursor = options.batchSize ? { batchSize: options.batchSize } : {};
@@ -543,7 +578,11 @@ Db.prototype.listCollections = function(filter, options) {
543
578
  // Set the AggregationCursor constructor
544
579
  options.cursorFactory = CommandCursor;
545
580
  // Create the cursor
546
- cursor = this.s.topology.cursor(`${this.s.databaseName}.$cmd`, command, options);
581
+ cursor = this.s.topology.cursor(
582
+ this.s.namespace.withCollection('$cmd').toString(),
583
+ command,
584
+ options
585
+ );
547
586
  // Do we have a readPreference, apply it
548
587
  if (options.readPreference) {
549
588
  cursor.setReadPreference(options.readPreference);
@@ -560,13 +599,13 @@ Db.prototype.listCollections = function(filter, options) {
560
599
  !new RegExp('^' + this.databaseName + '\\.').test(filter.name)
561
600
  ) {
562
601
  filter = Object.assign({}, filter);
563
- filter.name = `${this.s.databaseName}.${filter.name}`;
602
+ filter.name = this.s.namespace.withCollection(filter.name).toString();
564
603
  }
565
604
  }
566
605
 
567
606
  // No filter, filter by current database
568
607
  if (filter == null) {
569
- filter.name = `/${this.s.databaseName}/`;
608
+ filter.name = `/${this.databaseName}/`;
570
609
  }
571
610
 
572
611
  // Rewrite the filter to use $and to filter out indexes
@@ -577,7 +616,7 @@ Db.prototype.listCollections = function(filter, options) {
577
616
  }
578
617
 
579
618
  // Return options
580
- const _options = { transforms: listCollectionsTransforms(this.s.databaseName) };
619
+ const _options = { transforms: listCollectionsTransforms(this.databaseName) };
581
620
  // Get the cursor
582
621
  cursor = this.collection(CONSTANTS.SYSTEM_NAMESPACE_COLLECTION).find(filter, _options);
583
622
  // Do we have a readPreference, apply it
@@ -607,7 +646,13 @@ Db.prototype.eval = deprecate(function(code, parameters, options, callback) {
607
646
  parameters = args.length ? args.shift() : parameters;
608
647
  options = args.length ? args.shift() || {} : {};
609
648
 
610
- return executeOperation(this.s.topology, evaluate, [this, code, parameters, options, callback]);
649
+ return executeLegacyOperation(this.s.topology, evaluate, [
650
+ this,
651
+ code,
652
+ parameters,
653
+ options,
654
+ callback
655
+ ]);
611
656
  }, 'Db.eval is deprecated as of MongoDB version 3.2');
612
657
 
613
658
  /**
@@ -624,16 +669,18 @@ Db.prototype.eval = deprecate(function(code, parameters, options, callback) {
624
669
  */
625
670
  Db.prototype.renameCollection = function(fromCollection, toCollection, options, callback) {
626
671
  if (typeof options === 'function') (callback = options), (options = {});
627
- options = options || {};
672
+ options = Object.assign({}, options, { readPreference: ReadPreference.PRIMARY });
673
+
628
674
  // Add return new collection
629
675
  options.new_collection = true;
630
676
 
631
- const collection = this.collection(fromCollection);
632
- return executeOperation(this.s.topology, collection.rename.bind(collection), [
677
+ const renameOperation = new RenameOperation(
678
+ this.collection(fromCollection),
633
679
  toCollection,
634
- options,
635
- callback
636
- ]);
680
+ options
681
+ );
682
+
683
+ return executeOperation(this.s.topology, renameOperation, callback);
637
684
  };
638
685
 
639
686
  /**
@@ -642,6 +689,10 @@ Db.prototype.renameCollection = function(fromCollection, toCollection, options,
642
689
  * @method
643
690
  * @param {string} name Name of collection to drop
644
691
  * @param {Object} [options] Optional settings
692
+ * @param {WriteConcern} [options.writeConcern] A full WriteConcern object
693
+ * @param {(number|string)} [options.w] The write concern
694
+ * @param {number} [options.wtimeout] The write concern timeout
695
+ * @param {boolean} [options.j] The journal write concern
645
696
  * @param {ClientSession} [options.session] optional session to use for this operation
646
697
  * @param {Db~resultCallback} [callback] The results callback
647
698
  * @return {Promise} returns Promise if no callback passed
@@ -650,17 +701,9 @@ Db.prototype.dropCollection = function(name, options, callback) {
650
701
  if (typeof options === 'function') (callback = options), (options = {});
651
702
  options = options || {};
652
703
 
653
- // Command to execute
654
- const cmd = { drop: name };
655
-
656
- // Decorate with write concern
657
- applyWriteConcern(cmd, { db: this }, options);
704
+ const dropCollectionOperation = new DropCollectionOperation(this, name, options);
658
705
 
659
- // options
660
- const opts = Object.assign({}, this.s.options, { readPreference: ReadPreference.PRIMARY });
661
- if (options.session) opts.session = options.session;
662
-
663
- return executeOperation(this.s.topology, dropCollection, [this, cmd, opts, callback]);
706
+ return executeOperation(this.s.topology, dropCollectionOperation, callback);
664
707
  };
665
708
 
666
709
  /**
@@ -675,22 +718,10 @@ Db.prototype.dropCollection = function(name, options, callback) {
675
718
  Db.prototype.dropDatabase = function(options, callback) {
676
719
  if (typeof options === 'function') (callback = options), (options = {});
677
720
  options = options || {};
678
- // Drop database command
679
- const cmd = { dropDatabase: 1 };
680
-
681
- // Decorate with write concern
682
- applyWriteConcern(cmd, { db: this }, options);
683
-
684
- // Ensure primary only
685
- const finalOptions = Object.assign({}, this.s.options, {
686
- readPreference: ReadPreference.PRIMARY
687
- });
688
721
 
689
- if (options.session) {
690
- finalOptions.session = options.session;
691
- }
722
+ const dropDatabaseOperation = new DropDatabaseOperation(this, options);
692
723
 
693
- return executeOperation(this.s.topology, dropDatabase, [this, cmd, finalOptions, callback]);
724
+ return executeOperation(this.s.topology, dropDatabaseOperation, callback);
694
725
  };
695
726
 
696
727
  /**
@@ -706,7 +737,9 @@ Db.prototype.collections = function(options, callback) {
706
737
  if (typeof options === 'function') (callback = options), (options = {});
707
738
  options = options || {};
708
739
 
709
- return executeOperation(this.s.topology, collections, [this, options, callback]);
740
+ const collectionsOperation = new CollectionsOperation(this, options);
741
+
742
+ return executeOperation(this.s.topology, collectionsOperation, callback);
710
743
  };
711
744
 
712
745
  /**
@@ -722,14 +755,15 @@ Db.prototype.collections = function(options, callback) {
722
755
  Db.prototype.executeDbAdminCommand = function(selector, options, callback) {
723
756
  if (typeof options === 'function') (callback = options), (options = {});
724
757
  options = options || {};
725
- options.readPreference = resolveReadPreference(options);
758
+ options.readPreference = resolveReadPreference(this, options);
726
759
 
727
- return executeOperation(this.s.topology, executeDbAdminCommand, [
760
+ const executeDbAdminCommandOperation = new ExecuteDbAdminCommandOperation(
728
761
  this,
729
762
  selector,
730
- options,
731
- callback
732
- ]);
763
+ options
764
+ );
765
+
766
+ return executeOperation(this.s.topology, executeDbAdminCommandOperation, callback);
733
767
  };
734
768
 
735
769
  /**
@@ -759,13 +793,9 @@ Db.prototype.createIndex = function(name, fieldOrSpec, options, callback) {
759
793
  if (typeof options === 'function') (callback = options), (options = {});
760
794
  options = options ? Object.assign({}, options) : {};
761
795
 
762
- return executeOperation(this.s.topology, createIndex, [
763
- this,
764
- name,
765
- fieldOrSpec,
766
- options,
767
- callback
768
- ]);
796
+ const createIndexOperation = new CreateIndexOperation(this, name, fieldOrSpec, options);
797
+
798
+ return executeOperation(this.s.topology, createIndexOperation, callback);
769
799
  };
770
800
 
771
801
  /**
@@ -795,7 +825,7 @@ Db.prototype.ensureIndex = deprecate(function(name, fieldOrSpec, options, callba
795
825
  if (typeof options === 'function') (callback = options), (options = {});
796
826
  options = options || {};
797
827
 
798
- return executeOperation(this.s.topology, ensureIndex, [
828
+ return executeLegacyOperation(this.s.topology, ensureIndex, [
799
829
  this,
800
830
  name,
801
831
  fieldOrSpec,
@@ -828,7 +858,15 @@ Db.prototype.addUser = function(username, password, options, callback) {
828
858
  if (typeof options === 'function') (callback = options), (options = {});
829
859
  options = options || {};
830
860
 
831
- return executeOperation(this.s.topology, addUser, [this, username, password, options, callback]);
861
+ // Special case where there is no password ($external users)
862
+ if (typeof username === 'string' && password != null && typeof password === 'object') {
863
+ options = password;
864
+ password = null;
865
+ }
866
+
867
+ const addUserOperation = new AddUserOperation(this, username, password, options);
868
+
869
+ return executeOperation(this.s.topology, addUserOperation, callback);
832
870
  };
833
871
 
834
872
  /**
@@ -847,7 +885,9 @@ Db.prototype.removeUser = function(username, options, callback) {
847
885
  if (typeof options === 'function') (callback = options), (options = {});
848
886
  options = options || {};
849
887
 
850
- return executeOperation(this.s.topology, removeUser, [this, username, options, callback]);
888
+ const removeUserOperation = new RemoveUserOperation(this, username, options);
889
+
890
+ return executeOperation(this.s.topology, removeUserOperation, callback);
851
891
  };
852
892
 
853
893
  /**
@@ -863,7 +903,9 @@ Db.prototype.setProfilingLevel = function(level, options, callback) {
863
903
  if (typeof options === 'function') (callback = options), (options = {});
864
904
  options = options || {};
865
905
 
866
- return executeOperation(this.s.topology, setProfilingLevel, [this, level, options, callback]);
906
+ const setProfilingLevelOperation = new SetProfilingLevelOperation(this, level, options);
907
+
908
+ return executeOperation(this.s.topology, setProfilingLevelOperation, callback);
867
909
  };
868
910
 
869
911
  /**
@@ -879,7 +921,7 @@ Db.prototype.profilingInfo = deprecate(function(options, callback) {
879
921
  if (typeof options === 'function') (callback = options), (options = {});
880
922
  options = options || {};
881
923
 
882
- return executeOperation(this.s.topology, profilingInfo, [this, options, callback]);
924
+ return executeLegacyOperation(this.s.topology, profilingInfo, [this, options, callback]);
883
925
  }, 'Db.profilingInfo is deprecated. Query the system.profile collection directly.');
884
926
 
885
927
  /**
@@ -894,7 +936,9 @@ Db.prototype.profilingLevel = function(options, callback) {
894
936
  if (typeof options === 'function') (callback = options), (options = {});
895
937
  options = options || {};
896
938
 
897
- return executeOperation(this.s.topology, profilingLevel, [this, options, callback]);
939
+ const profilingLevelOperation = new ProfilingLevelOperation(this, options);
940
+
941
+ return executeOperation(this.s.topology, profilingLevelOperation, callback);
898
942
  };
899
943
 
900
944
  /**
@@ -912,7 +956,9 @@ Db.prototype.indexInformation = function(name, options, callback) {
912
956
  if (typeof options === 'function') (callback = options), (options = {});
913
957
  options = options || {};
914
958
 
915
- return executeOperation(this.s.topology, indexInformation, [this, name, options, callback]);
959
+ const indexInformationOperation = new IndexInformationOperation(this, name, options);
960
+
961
+ return executeOperation(this.s.topology, indexInformationOperation, callback);
916
962
  };
917
963
 
918
964
  /**
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ let collection;
4
+ let cursor;
5
+ let db;
6
+
7
+ function loadCollection() {
8
+ if (!collection) {
9
+ collection = require('./collection');
10
+ }
11
+ return collection;
12
+ }
13
+
14
+ function loadCursor() {
15
+ if (!cursor) {
16
+ cursor = require('./cursor');
17
+ }
18
+ return cursor;
19
+ }
20
+
21
+ function loadDb() {
22
+ if (!db) {
23
+ db = require('./db');
24
+ }
25
+ return db;
26
+ }
27
+
28
+ module.exports = {
29
+ loadCollection,
30
+ loadCursor,
31
+ loadDb
32
+ };
package/lib/error.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const MongoNetworkError = require('mongodb-core').MongoNetworkError;
4
- const mongoErrorContextSymbol = require('mongodb-core').mongoErrorContextSymbol;
3
+ const MongoNetworkError = require('./core').MongoNetworkError;
4
+ const mongoErrorContextSymbol = require('./core').mongoErrorContextSymbol;
5
5
 
6
6
  const GET_MORE_NON_RESUMABLE_CODES = new Set([
7
7
  136, // CappedPositionLost
@@ -9,15 +9,15 @@ const GET_MORE_NON_RESUMABLE_CODES = new Set([
9
9
  11601 // Interrupted
10
10
  ]);
11
11
 
12
- // From spec@https://github.com/mongodb/specifications/blob/35e466ddf25059cb30e4113de71cdebd3754657f/source/change-streams.rst#resumable-error:
12
+ // From spec@https://github.com/mongodb/specifications/blob/7a2e93d85935ee4b1046a8d2ad3514c657dc74fa/source/change-streams/change-streams.rst#resumable-error:
13
13
  //
14
14
  // An error is considered resumable if it meets any of the following criteria:
15
15
  // - any error encountered which is not a server error (e.g. a timeout error or network error)
16
- // - any server error response from a getMore command excluding those containing the following error codes
16
+ // - any server error response from a getMore command excluding those containing the error label
17
+ // NonRetryableChangeStreamError and those containing the following error codes:
17
18
  // - Interrupted: 11601
18
19
  // - CappedPositionLost: 136
19
20
  // - CursorKilled: 237
20
- // - a server error response with an error message containing the substring "not master" or "node is recovering"
21
21
  //
22
22
  // An error on an aggregate command is not a resumable error. Only errors on a getMore command may be considered resumable errors.
23
23
 
@@ -32,11 +32,13 @@ function isResumableError(error) {
32
32
  return false;
33
33
  }
34
34
 
35
- return !!(
36
- error instanceof MongoNetworkError ||
37
- !GET_MORE_NON_RESUMABLE_CODES.has(error.code) ||
38
- error.message.match(/not master/) ||
39
- error.message.match(/node is recovering/)
35
+ if (error instanceof MongoNetworkError) {
36
+ return true;
37
+ }
38
+
39
+ return !(
40
+ GET_MORE_NON_RESUMABLE_CODES.has(error.code) ||
41
+ error.hasErrorLabel('NonRetryableChangeStreamError')
40
42
  );
41
43
  }
42
44
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var Binary = require('mongodb-core').BSON.Binary,
4
- ObjectID = require('mongodb-core').BSON.ObjectID;
3
+ var Binary = require('../core').BSON.Binary,
4
+ ObjectID = require('../core').BSON.ObjectID;
5
5
 
6
6
  var Buffer = require('safe-buffer').Buffer;
7
7