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/collection.js CHANGED
@@ -3,63 +3,71 @@
3
3
  const deprecate = require('util').deprecate;
4
4
  const deprecateOptions = require('./utils').deprecateOptions;
5
5
  const checkCollectionName = require('./utils').checkCollectionName;
6
- const ObjectID = require('mongodb-core').BSON.ObjectID;
7
- const MongoError = require('mongodb-core').MongoError;
6
+ const ObjectID = require('./core').BSON.ObjectID;
7
+ const MongoError = require('./core').MongoError;
8
8
  const toError = require('./utils').toError;
9
- const normalizeHintField = require('./utils').normalizeHintField;
10
9
  const handleCallback = require('./utils').handleCallback;
10
+ const normalizeHintField = require('./utils').normalizeHintField;
11
11
  const decorateCommand = require('./utils').decorateCommand;
12
12
  const decorateWithCollation = require('./utils').decorateWithCollation;
13
13
  const decorateWithReadConcern = require('./utils').decorateWithReadConcern;
14
14
  const formattedOrderClause = require('./utils').formattedOrderClause;
15
- const ReadPreference = require('mongodb-core').ReadPreference;
16
- const CommandCursor = require('./command_cursor');
15
+ const ReadPreference = require('./core').ReadPreference;
17
16
  const unordered = require('./bulk/unordered');
18
17
  const ordered = require('./bulk/ordered');
19
18
  const ChangeStream = require('./change_stream');
20
- const executeOperation = require('./utils').executeOperation;
19
+ const executeLegacyOperation = require('./utils').executeLegacyOperation;
21
20
  const resolveReadPreference = require('./utils').resolveReadPreference;
21
+ const WriteConcern = require('./write_concern');
22
+ const ReadConcern = require('./read_concern');
23
+ const MongoDBNamespace = require('./utils').MongoDBNamespace;
22
24
 
23
25
  // Operations
24
26
  const aggregate = require('./operations/aggregate').aggregate;
25
- const bulkWrite = require('./operations/collection_ops').bulkWrite;
26
27
  const checkForAtomicOperators = require('./operations/collection_ops').checkForAtomicOperators;
27
28
  const count = require('./operations/collection_ops').count;
28
- const countDocuments = require('./operations/collection_ops').countDocuments;
29
- const createIndex = require('./operations/collection_ops').createIndex;
30
- const createIndexes = require('./operations/collection_ops').createIndexes;
31
- const deleteMany = require('./operations/collection_ops').deleteMany;
32
- const deleteOne = require('./operations/collection_ops').deleteOne;
33
- const distinct = require('./operations/collection_ops').distinct;
34
- const dropIndex = require('./operations/collection_ops').dropIndex;
35
- const dropIndexes = require('./operations/collection_ops').dropIndexes;
36
29
  const ensureIndex = require('./operations/collection_ops').ensureIndex;
37
30
  const findAndModify = require('./operations/collection_ops').findAndModify;
38
31
  const findAndRemove = require('./operations/collection_ops').findAndRemove;
39
- const findOne = require('./operations/collection_ops').findOne;
40
- const findOneAndDelete = require('./operations/collection_ops').findOneAndDelete;
41
- const findOneAndReplace = require('./operations/collection_ops').findOneAndReplace;
42
- const findOneAndUpdate = require('./operations/collection_ops').findOneAndUpdate;
43
- const geoHaystackSearch = require('./operations/collection_ops').geoHaystackSearch;
44
32
  const group = require('./operations/collection_ops').group;
45
- const indexes = require('./operations/collection_ops').indexes;
46
- const indexExists = require('./operations/collection_ops').indexExists;
47
- const indexInformation = require('./operations/collection_ops').indexInformation;
48
- const insertMany = require('./operations/collection_ops').insertMany;
49
- const insertOne = require('./operations/collection_ops').insertOne;
50
- const isCapped = require('./operations/collection_ops').isCapped;
51
- const mapReduce = require('./operations/collection_ops').mapReduce;
52
- const optionsOp = require('./operations/collection_ops').optionsOp;
53
33
  const parallelCollectionScan = require('./operations/collection_ops').parallelCollectionScan;
54
- const reIndex = require('./operations/collection_ops').reIndex;
55
34
  const removeDocuments = require('./operations/collection_ops').removeDocuments;
56
- const rename = require('./operations/collection_ops').rename;
57
- const replaceOne = require('./operations/collection_ops').replaceOne;
58
35
  const save = require('./operations/collection_ops').save;
59
- const stats = require('./operations/collection_ops').stats;
60
36
  const updateDocuments = require('./operations/collection_ops').updateDocuments;
61
- const updateMany = require('./operations/collection_ops').updateMany;
62
- const updateOne = require('./operations/collection_ops').updateOne;
37
+
38
+ const BulkWriteOperation = require('./operations/bulk_write');
39
+ const CountDocumentsOperation = require('./operations/count_documents');
40
+ const CreateIndexOperation = require('./operations/create_index');
41
+ const CreateIndexesOperation = require('./operations/create_indexes');
42
+ const DeleteManyOperation = require('./operations/delete_many');
43
+ const DeleteOneOperation = require('./operations/delete_one');
44
+ const DistinctOperation = require('./operations/distinct');
45
+ const DropCollectionOperation = require('./operations/drop').DropCollectionOperation;
46
+ const DropIndexOperation = require('./operations/drop_index');
47
+ const DropIndexesOperation = require('./operations/drop_indexes');
48
+ const EstimatedDocumentCountOperation = require('./operations/estimated_document_count');
49
+ const FindOneOperation = require('./operations/find_one');
50
+ const FindOneAndDeleteOperation = require('./operations/find_one_and_delete');
51
+ const FindOneAndReplaceOperation = require('./operations/find_one_and_replace');
52
+ const FindOneAndUpdateOperation = require('./operations/find_one_and_update');
53
+ const GeoHaystackSearchOperation = require('./operations/geo_haystack_search');
54
+ const IndexesOperation = require('./operations/indexes');
55
+ const IndexExistsOperation = require('./operations/index_exists');
56
+ const IndexInformationOperation = require('./operations/index_information');
57
+ const InsertManyOperation = require('./operations/insert_many');
58
+ const InsertOneOperation = require('./operations/insert_one');
59
+ const IsCappedOperation = require('./operations/is_capped');
60
+ const ListIndexesOperation = require('./operations/list_indexes');
61
+ const MapReduceOperation = require('./operations/map_reduce');
62
+ const OptionsOperation = require('./operations/options_operation');
63
+ const RenameOperation = require('./operations/rename');
64
+ const ReIndexOperation = require('./operations/re_index');
65
+ const ReplaceOneOperation = require('./operations/replace_one');
66
+ const StatsOperation = require('./operations/stats');
67
+ const UpdateManyOperation = require('./operations/update_many');
68
+ const UpdateOneOperation = require('./operations/update_one');
69
+
70
+ const executeOperation = require('./operations/execute_operation');
63
71
 
64
72
  /**
65
73
  * @fileOverview The **Collection** class is an internal class that embodies a MongoDB collection
@@ -121,20 +129,13 @@ function Collection(db, topology, dbName, name, pkFactory, options) {
121
129
  options == null || options.promoteBuffers == null
122
130
  ? db.s.options.promoteBuffers
123
131
  : options.promoteBuffers;
124
- let readPreference = null;
125
132
  const collectionHint = null;
126
- const namespace = `${dbName}.${name}`;
133
+
134
+ const namespace = new MongoDBNamespace(dbName, name);
127
135
 
128
136
  // Get the promiseLibrary
129
137
  const promiseLibrary = options.promiseLibrary || Promise;
130
138
 
131
- // Assign the right collection level readPreference
132
- if (options && options.readPreference) {
133
- readPreference = options.readPreference;
134
- } else if (db.options.readPreference) {
135
- readPreference = db.options.readPreference;
136
- }
137
-
138
139
  // Set custom primary key factory if provided
139
140
  pkFactory = pkFactory == null ? ObjectID : pkFactory;
140
141
 
@@ -146,14 +147,12 @@ function Collection(db, topology, dbName, name, pkFactory, options) {
146
147
  db: db,
147
148
  // Topology
148
149
  topology: topology,
149
- // dbName
150
- dbName: dbName,
151
150
  // Options
152
151
  options: options,
153
152
  // Namespace
154
153
  namespace: namespace,
155
154
  // Read preference
156
- readPreference: readPreference,
155
+ readPreference: ReadPreference.fromOptions(options),
157
156
  // SlaveOK
158
157
  slaveOk: slaveOk,
159
158
  // Serialize functions
@@ -170,58 +169,64 @@ function Collection(db, topology, dbName, name, pkFactory, options) {
170
169
  internalHint: internalHint,
171
170
  // collectionHint
172
171
  collectionHint: collectionHint,
173
- // Name
174
- name: name,
175
172
  // Promise library
176
173
  promiseLibrary: promiseLibrary,
177
174
  // Read Concern
178
- readConcern: options.readConcern,
175
+ readConcern: ReadConcern.fromOptions(options),
179
176
  // Write Concern
180
- writeConcern: options.writeConcern
177
+ writeConcern: WriteConcern.fromOptions(options)
181
178
  };
182
179
  }
183
180
 
184
181
  Object.defineProperty(Collection.prototype, 'dbName', {
185
182
  enumerable: true,
186
183
  get: function() {
187
- return this.s.dbName;
184
+ return this.s.namespace.db;
188
185
  }
189
186
  });
190
187
 
191
188
  Object.defineProperty(Collection.prototype, 'collectionName', {
192
189
  enumerable: true,
193
190
  get: function() {
194
- return this.s.name;
191
+ return this.s.namespace.collection;
195
192
  }
196
193
  });
197
194
 
198
195
  Object.defineProperty(Collection.prototype, 'namespace', {
199
196
  enumerable: true,
200
197
  get: function() {
201
- return this.s.namespace;
198
+ return this.s.namespace.toString();
202
199
  }
203
200
  });
204
201
 
205
202
  Object.defineProperty(Collection.prototype, 'readConcern', {
206
203
  enumerable: true,
207
204
  get: function() {
208
- return this.s.readConcern || { level: 'local' };
205
+ if (this.s.readConcern == null) {
206
+ return this.s.db.readConcern;
207
+ }
208
+ return this.s.readConcern;
209
209
  }
210
210
  });
211
211
 
212
- Object.defineProperty(Collection.prototype, 'writeConcern', {
212
+ Object.defineProperty(Collection.prototype, 'readPreference', {
213
213
  enumerable: true,
214
214
  get: function() {
215
- let ops = {};
216
- if (this.s.writeConcern) {
217
- return this.s.writeConcern;
215
+ if (this.s.readPreference == null) {
216
+ return this.s.db.readPreference;
218
217
  }
219
218
 
220
- if (this.s.options.w != null) ops.w = this.s.options.w;
221
- if (this.s.options.j != null) ops.j = this.s.options.j;
222
- if (this.s.options.fsync != null) ops.fsync = this.s.options.fsync;
223
- if (this.s.options.wtimeout != null) ops.wtimeout = this.s.options.wtimeout;
224
- return ops;
219
+ return this.s.readPreference;
220
+ }
221
+ });
222
+
223
+ Object.defineProperty(Collection.prototype, 'writeConcern', {
224
+ enumerable: true,
225
+ get: function() {
226
+ if (this.s.writeConcern == null) {
227
+ return this.s.db.writeConcern;
228
+ }
229
+ return this.s.writeConcern;
225
230
  }
226
231
  });
227
232
 
@@ -356,10 +361,7 @@ Collection.prototype.find = deprecateOptions(
356
361
  newOptions.slaveOk = options.slaveOk != null ? options.slaveOk : this.s.db.slaveOk;
357
362
 
358
363
  // Add read preference if needed
359
- newOptions.readPreference = resolveReadPreference(newOptions, {
360
- db: this.s.db,
361
- collection: this
362
- });
364
+ newOptions.readPreference = resolveReadPreference(this, newOptions);
363
365
 
364
366
  // Set slave ok to true if read preference different from primary
365
367
  if (
@@ -376,7 +378,7 @@ Collection.prototype.find = deprecateOptions(
376
378
 
377
379
  // Build the find command
378
380
  const findCommand = {
379
- find: this.s.namespace,
381
+ find: this.s.namespace.toString(),
380
382
  limit: newOptions.limit,
381
383
  skip: newOptions.skip,
382
384
  query: selector
@@ -426,7 +428,8 @@ Collection.prototype.find = deprecateOptions(
426
428
  throw err;
427
429
  }
428
430
 
429
- const cursor = this.s.topology.cursor(this.s.namespace, findCommand, newOptions);
431
+ // TODO: pass object cursor
432
+ const cursor = this.s.topology.cursor(this.s.namespace.toString(), findCommand, newOptions);
430
433
 
431
434
  return typeof callback === 'function' ? handleCallback(callback, null, cursor) : cursor;
432
435
  }
@@ -460,7 +463,9 @@ Collection.prototype.insertOne = function(doc, options, callback) {
460
463
  options.ignoreUndefined = this.s.options.ignoreUndefined;
461
464
  }
462
465
 
463
- return executeOperation(this.s.topology, insertOne, [this, doc, options, callback]);
466
+ const insertOneOperation = new InsertOneOperation(this, doc, options);
467
+
468
+ return executeOperation(this.s.topology, insertOneOperation, callback);
464
469
  };
465
470
 
466
471
  /**
@@ -486,7 +491,9 @@ Collection.prototype.insertMany = function(docs, options, callback) {
486
491
  if (typeof options === 'function') (callback = options), (options = {});
487
492
  options = options ? Object.assign({}, options) : { ordered: true };
488
493
 
489
- return executeOperation(this.s.topology, insertMany, [this, docs, options, callback]);
494
+ const insertManyOperation = new InsertManyOperation(this, docs, options);
495
+
496
+ return executeOperation(this.s.topology, insertManyOperation, callback);
490
497
  };
491
498
 
492
499
  /**
@@ -519,6 +526,8 @@ Collection.prototype.insertMany = function(docs, options, callback) {
519
526
  *
520
527
  * { updateMany: { filter: {a:2}, update: {$set: {a:2}}, upsert:true } }
521
528
  *
529
+ * { updateMany: { filter: {}, update: {$set: {"a.$[i].x": 5}}, arrayFilters: [{ "i.x": 5 }]} }
530
+ *
522
531
  * { deleteOne: { filter: {c:1} } }
523
532
  *
524
533
  * { deleteMany: { filter: {c:1} } }
@@ -532,6 +541,7 @@ Collection.prototype.insertMany = function(docs, options, callback) {
532
541
  * @method
533
542
  * @param {object[]} operations Bulk operations to perform.
534
543
  * @param {object} [options] Optional settings.
544
+ * @param {object[]} [options.arrayFilters] Determines which array elements to modify for update operation in MongoDB 3.6 or higher.
535
545
  * @param {(number|string)} [options.w] The write concern.
536
546
  * @param {number} [options.wtimeout] The write concern timeout.
537
547
  * @param {boolean} [options.j=false] Specify a journal write concern.
@@ -550,7 +560,9 @@ Collection.prototype.bulkWrite = function(operations, options, callback) {
550
560
  throw MongoError.create({ message: 'operations must be an array of documents', driver: true });
551
561
  }
552
562
 
553
- return executeOperation(this.s.topology, bulkWrite, [this, operations, options, callback]);
563
+ const bulkWriteOperation = new BulkWriteOperation(this, operations, options);
564
+
565
+ return executeOperation(this.s.topology, bulkWriteOperation, callback);
554
566
  };
555
567
 
556
568
  /**
@@ -691,7 +703,9 @@ Collection.prototype.updateOne = function(filter, update, options, callback) {
691
703
  options.ignoreUndefined = this.s.options.ignoreUndefined;
692
704
  }
693
705
 
694
- return executeOperation(this.s.topology, updateOne, [this, filter, update, options, callback]);
706
+ const updateOneOperation = new UpdateOneOperation(this, filter, update, options);
707
+
708
+ return executeOperation(this.s.topology, updateOneOperation, callback);
695
709
  };
696
710
 
697
711
  /**
@@ -719,7 +733,9 @@ Collection.prototype.replaceOne = function(filter, doc, options, callback) {
719
733
  options.ignoreUndefined = this.s.options.ignoreUndefined;
720
734
  }
721
735
 
722
- return executeOperation(this.s.topology, replaceOne, [this, filter, doc, options, callback]);
736
+ const replaceOneOperation = new ReplaceOneOperation(this, filter, doc, options);
737
+
738
+ return executeOperation(this.s.topology, replaceOneOperation, callback);
723
739
  };
724
740
 
725
741
  /**
@@ -755,7 +771,9 @@ Collection.prototype.updateMany = function(filter, update, options, callback) {
755
771
  options.ignoreUndefined = this.s.options.ignoreUndefined;
756
772
  }
757
773
 
758
- return executeOperation(this.s.topology, updateMany, [this, filter, update, options, callback]);
774
+ const updateManyOperation = new UpdateManyOperation(this, filter, update, options);
775
+
776
+ return executeOperation(this.s.topology, updateManyOperation, callback);
759
777
  };
760
778
 
761
779
  /**
@@ -788,7 +806,7 @@ Collection.prototype.update = deprecate(function(selector, update, options, call
788
806
  options.ignoreUndefined = this.s.options.ignoreUndefined;
789
807
  }
790
808
 
791
- return executeOperation(this.s.topology, updateDocuments, [
809
+ return executeLegacyOperation(this.s.topology, updateDocuments, [
792
810
  this,
793
811
  selector,
794
812
  update,
@@ -835,7 +853,9 @@ Collection.prototype.deleteOne = function(filter, options, callback) {
835
853
  options.ignoreUndefined = this.s.options.ignoreUndefined;
836
854
  }
837
855
 
838
- return executeOperation(this.s.topology, deleteOne, [this, filter, options, callback]);
856
+ const deleteOneOperation = new DeleteOneOperation(this, filter, options);
857
+
858
+ return executeOperation(this.s.topology, deleteOneOperation, callback);
839
859
  };
840
860
 
841
861
  Collection.prototype.removeOne = Collection.prototype.deleteOne;
@@ -862,7 +882,9 @@ Collection.prototype.deleteMany = function(filter, options, callback) {
862
882
  options.ignoreUndefined = this.s.options.ignoreUndefined;
863
883
  }
864
884
 
865
- return executeOperation(this.s.topology, deleteMany, [this, filter, options, callback]);
885
+ const deleteManyOperation = new DeleteManyOperation(this, filter, options);
886
+
887
+ return executeOperation(this.s.topology, deleteManyOperation, callback);
866
888
  };
867
889
 
868
890
  Collection.prototype.removeMany = Collection.prototype.deleteMany;
@@ -891,7 +913,12 @@ Collection.prototype.remove = deprecate(function(selector, options, callback) {
891
913
  options.ignoreUndefined = this.s.options.ignoreUndefined;
892
914
  }
893
915
 
894
- return executeOperation(this.s.topology, removeDocuments, [this, selector, options, callback]);
916
+ return executeLegacyOperation(this.s.topology, removeDocuments, [
917
+ this,
918
+ selector,
919
+ options,
920
+ callback
921
+ ]);
895
922
  }, 'collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.');
896
923
 
897
924
  /**
@@ -918,7 +945,7 @@ Collection.prototype.save = deprecate(function(doc, options, callback) {
918
945
  options.ignoreUndefined = this.s.options.ignoreUndefined;
919
946
  }
920
947
 
921
- return executeOperation(this.s.topology, save, [this, doc, options, callback]);
948
+ return executeLegacyOperation(this.s.topology, save, [this, doc, options, callback]);
922
949
  }, 'collection.save is deprecated. Use insertOne, insertMany, updateOne, or updateMany instead.');
923
950
 
924
951
  /**
@@ -986,7 +1013,9 @@ Collection.prototype.findOne = deprecateOptions(
986
1013
  query = query || {};
987
1014
  options = options || {};
988
1015
 
989
- return executeOperation(this.s.topology, findOne, [this, query, options, callback]);
1016
+ const findOneOperation = new FindOneOperation(this, query, options);
1017
+
1018
+ return executeOperation(this.s.topology, findOneOperation, callback);
990
1019
  }
991
1020
  );
992
1021
 
@@ -1012,7 +1041,9 @@ Collection.prototype.rename = function(newName, options, callback) {
1012
1041
  if (typeof options === 'function') (callback = options), (options = {});
1013
1042
  options = Object.assign({}, options, { readPreference: ReadPreference.PRIMARY });
1014
1043
 
1015
- return executeOperation(this.s.topology, rename, [this, newName, options, callback]);
1044
+ const renameOperation = new RenameOperation(this, newName, options);
1045
+
1046
+ return executeOperation(this.s.topology, renameOperation, callback);
1016
1047
  };
1017
1048
 
1018
1049
  /**
@@ -1020,6 +1051,10 @@ Collection.prototype.rename = function(newName, options, callback) {
1020
1051
  *
1021
1052
  * @method
1022
1053
  * @param {object} [options] Optional settings.
1054
+ * @param {WriteConcern} [options.writeConcern] A full WriteConcern object
1055
+ * @param {(number|string)} [options.w] The write concern
1056
+ * @param {number} [options.wtimeout] The write concern timeout
1057
+ * @param {boolean} [options.j] The journal write concern
1023
1058
  * @param {ClientSession} [options.session] optional session to use for this operation
1024
1059
  * @param {Collection~resultCallback} [callback] The results callback
1025
1060
  * @return {Promise} returns Promise if no callback passed
@@ -1028,11 +1063,13 @@ Collection.prototype.drop = function(options, callback) {
1028
1063
  if (typeof options === 'function') (callback = options), (options = {});
1029
1064
  options = options || {};
1030
1065
 
1031
- return executeOperation(this.s.topology, this.s.db.dropCollection.bind(this.s.db), [
1032
- this.s.name,
1033
- options,
1034
- callback
1035
- ]);
1066
+ const dropCollectionOperation = new DropCollectionOperation(
1067
+ this.s.db,
1068
+ this.collectionName,
1069
+ options
1070
+ );
1071
+
1072
+ return executeOperation(this.s.topology, dropCollectionOperation, callback);
1036
1073
  };
1037
1074
 
1038
1075
  /**
@@ -1048,7 +1085,9 @@ Collection.prototype.options = function(opts, callback) {
1048
1085
  if (typeof opts === 'function') (callback = opts), (opts = {});
1049
1086
  opts = opts || {};
1050
1087
 
1051
- return executeOperation(this.s.topology, optionsOp, [this, opts, callback]);
1088
+ const optionsOperation = new OptionsOperation(this, opts);
1089
+
1090
+ return executeOperation(this.s.topology, optionsOperation, callback);
1052
1091
  };
1053
1092
 
1054
1093
  /**
@@ -1064,7 +1103,9 @@ Collection.prototype.isCapped = function(options, callback) {
1064
1103
  if (typeof options === 'function') (callback = options), (options = {});
1065
1104
  options = options || {};
1066
1105
 
1067
- return executeOperation(this.s.topology, isCapped, [this, options, callback]);
1106
+ const isCappedOperation = new IsCappedOperation(this, options);
1107
+
1108
+ return executeOperation(this.s.topology, isCappedOperation, callback);
1068
1109
  };
1069
1110
 
1070
1111
  /**
@@ -1094,7 +1135,14 @@ Collection.prototype.createIndex = function(fieldOrSpec, options, callback) {
1094
1135
  if (typeof options === 'function') (callback = options), (options = {});
1095
1136
  options = options || {};
1096
1137
 
1097
- return executeOperation(this.s.topology, createIndex, [this, fieldOrSpec, options, callback]);
1138
+ const createIndexOperation = new CreateIndexOperation(
1139
+ this.s.db,
1140
+ this.collectionName,
1141
+ fieldOrSpec,
1142
+ options
1143
+ );
1144
+
1145
+ return executeOperation(this.s.topology, createIndexOperation, callback);
1098
1146
  };
1099
1147
 
1100
1148
  /**
@@ -1114,7 +1162,9 @@ Collection.prototype.createIndexes = function(indexSpecs, options, callback) {
1114
1162
  options = options ? Object.assign({}, options) : {};
1115
1163
  if (typeof options.maxTimeMS !== 'number') delete options.maxTimeMS;
1116
1164
 
1117
- return executeOperation(this.s.topology, createIndexes, [this, indexSpecs, options, callback]);
1165
+ const createIndexesOperation = new CreateIndexesOperation(this, indexSpecs, options);
1166
+
1167
+ return executeOperation(this.s.topology, createIndexesOperation, callback);
1118
1168
  };
1119
1169
 
1120
1170
  /**
@@ -1138,7 +1188,9 @@ Collection.prototype.dropIndex = function(indexName, options, callback) {
1138
1188
  // Run only against primary
1139
1189
  options.readPreference = ReadPreference.PRIMARY;
1140
1190
 
1141
- return executeOperation(this.s.topology, dropIndex, [this, indexName, options, callback]);
1191
+ const dropIndexOperation = new DropIndexOperation(this, indexName, options);
1192
+
1193
+ return executeOperation(this.s.topology, dropIndexOperation, callback);
1142
1194
  };
1143
1195
 
1144
1196
  /**
@@ -1156,7 +1208,9 @@ Collection.prototype.dropIndexes = function(options, callback) {
1156
1208
 
1157
1209
  if (typeof options.maxTimeMS !== 'number') delete options.maxTimeMS;
1158
1210
 
1159
- return executeOperation(this.s.topology, dropIndexes, [this, options, callback]);
1211
+ const dropIndexesOperation = new DropIndexesOperation(this, options);
1212
+
1213
+ return executeOperation(this.s.topology, dropIndexesOperation, callback);
1160
1214
  };
1161
1215
 
1162
1216
  /**
@@ -1184,7 +1238,9 @@ Collection.prototype.reIndex = function(options, callback) {
1184
1238
  if (typeof options === 'function') (callback = options), (options = {});
1185
1239
  options = options || {};
1186
1240
 
1187
- return executeOperation(this.s.topology, reIndex, [this, options, callback]);
1241
+ const reIndexOperation = new ReIndexOperation(this, options);
1242
+
1243
+ return executeOperation(this.s.topology, reIndexOperation, callback);
1188
1244
  };
1189
1245
 
1190
1246
  /**
@@ -1198,45 +1254,9 @@ Collection.prototype.reIndex = function(options, callback) {
1198
1254
  * @return {CommandCursor}
1199
1255
  */
1200
1256
  Collection.prototype.listIndexes = function(options) {
1201
- options = options || {};
1202
- // Clone the options
1203
- options = Object.assign({}, options);
1204
- // Determine the read preference in the options.
1205
- options.readPreference = resolveReadPreference(options, { db: this.s.db, collection: this });
1206
- // Set the CommandCursor constructor
1207
- options.cursorFactory = CommandCursor;
1208
- // Set the promiseLibrary
1209
- options.promiseLibrary = this.s.promiseLibrary;
1257
+ const listIndexesOperation = new ListIndexesOperation(this, options);
1210
1258
 
1211
- if (!this.s.topology.capabilities()) {
1212
- throw new MongoError('cannot connect to server');
1213
- }
1214
-
1215
- // Cursor options
1216
- let cursor = options.batchSize ? { batchSize: options.batchSize } : {};
1217
-
1218
- // We have a list collections command
1219
- if (this.s.topology.capabilities().hasListIndexesCommand) {
1220
- // Build the command
1221
- const command = { listIndexes: this.s.name, cursor: cursor };
1222
- // Execute the cursor
1223
- cursor = this.s.topology.cursor(`${this.s.dbName}.$cmd`, command, options);
1224
- // Do we have a readPreference, apply it
1225
- if (options.readPreference) cursor.setReadPreference(options.readPreference);
1226
- // Return the cursor
1227
- return cursor;
1228
- }
1229
-
1230
- // Get the namespace
1231
- const ns = `${this.s.dbName}.system.indexes`;
1232
- // Get the query
1233
- cursor = this.s.topology.cursor(ns, { find: ns, query: { ns: this.s.namespace } }, options);
1234
- // Do we have a readPreference, apply it
1235
- if (options.readPreference) cursor.setReadPreference(options.readPreference);
1236
- // Set the passed in batch size if one was provided
1237
- if (options.batchSize) cursor = cursor.batchSize(options.batchSize);
1238
- // Return the cursor
1239
- return cursor;
1259
+ return listIndexesOperation.execute();
1240
1260
  };
1241
1261
 
1242
1262
  /**
@@ -1266,7 +1286,12 @@ Collection.prototype.ensureIndex = deprecate(function(fieldOrSpec, options, call
1266
1286
  if (typeof options === 'function') (callback = options), (options = {});
1267
1287
  options = options || {};
1268
1288
 
1269
- return executeOperation(this.s.topology, ensureIndex, [this, fieldOrSpec, options, callback]);
1289
+ return executeLegacyOperation(this.s.topology, ensureIndex, [
1290
+ this,
1291
+ fieldOrSpec,
1292
+ options,
1293
+ callback
1294
+ ]);
1270
1295
  }, 'collection.ensureIndex is deprecated. Use createIndexes instead.');
1271
1296
 
1272
1297
  /**
@@ -1282,7 +1307,9 @@ Collection.prototype.indexExists = function(indexes, options, callback) {
1282
1307
  if (typeof options === 'function') (callback = options), (options = {});
1283
1308
  options = options || {};
1284
1309
 
1285
- return executeOperation(this.s.topology, indexExists, [this, indexes, options, callback]);
1310
+ const indexExistsOperation = new IndexExistsOperation(this, indexes, options);
1311
+
1312
+ return executeOperation(this.s.topology, indexExistsOperation, callback);
1286
1313
  };
1287
1314
 
1288
1315
  /**
@@ -1299,7 +1326,13 @@ Collection.prototype.indexInformation = function(options, callback) {
1299
1326
  callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
1300
1327
  options = args.length ? args.shift() || {} : {};
1301
1328
 
1302
- return executeOperation(this.s.topology, indexInformation, [this, options, callback]);
1329
+ const indexInformationOperation = new IndexInformationOperation(
1330
+ this.s.db,
1331
+ this.collectionName,
1332
+ options
1333
+ );
1334
+
1335
+ return executeOperation(this.s.topology, indexInformationOperation, callback);
1303
1336
  };
1304
1337
 
1305
1338
  /**
@@ -1330,7 +1363,7 @@ Collection.prototype.count = deprecate(function(query, options, callback) {
1330
1363
  query = args.length ? args.shift() || {} : {};
1331
1364
  options = args.length ? args.shift() || {} : {};
1332
1365
 
1333
- return executeOperation(this.s.topology, count, [this, query, options, callback]);
1366
+ return executeLegacyOperation(this.s.topology, count, [this, query, options, callback]);
1334
1367
  }, 'collection.count is deprecated, and will be removed in a future version.' +
1335
1368
  ' Use collection.countDocuments or collection.estimatedDocumentCount instead');
1336
1369
 
@@ -1347,12 +1380,14 @@ Collection.prototype.estimatedDocumentCount = function(options, callback) {
1347
1380
  if (typeof options === 'function') (callback = options), (options = {});
1348
1381
  options = options || {};
1349
1382
 
1350
- return executeOperation(this.s.topology, count, [this, null, options, callback]);
1383
+ const estimatedDocumentCountOperation = new EstimatedDocumentCountOperation(this, options);
1384
+
1385
+ return executeOperation(this.s.topology, estimatedDocumentCountOperation, callback);
1351
1386
  };
1352
1387
 
1353
1388
  /**
1354
1389
  * Gets the number of documents matching the filter.
1355
- *
1390
+ * For a fast count of the total documents in a collection see {@link Collection#estimatedDocumentCount estimatedDocumentCount}.
1356
1391
  * **Note**: When migrating from {@link Collection#count count} to {@link Collection#countDocuments countDocuments}
1357
1392
  * the following query operators must be replaced:
1358
1393
  *
@@ -1388,7 +1423,9 @@ Collection.prototype.countDocuments = function(query, options, callback) {
1388
1423
  query = args.length ? args.shift() || {} : {};
1389
1424
  options = args.length ? args.shift() || {} : {};
1390
1425
 
1391
- return executeOperation(this.s.topology, countDocuments, [this, query, options, callback]);
1426
+ const countDocumentsOperation = new CountDocumentsOperation(this, query, options);
1427
+
1428
+ return executeOperation(this.s.topology, countDocumentsOperation, callback);
1392
1429
  };
1393
1430
 
1394
1431
  /**
@@ -1409,13 +1446,9 @@ Collection.prototype.distinct = function(key, query, options, callback) {
1409
1446
  const queryOption = args.length ? args.shift() || {} : {};
1410
1447
  const optionsOption = args.length ? args.shift() || {} : {};
1411
1448
 
1412
- return executeOperation(this.s.topology, distinct, [
1413
- this,
1414
- key,
1415
- queryOption,
1416
- optionsOption,
1417
- callback
1418
- ]);
1449
+ const distinctOperation = new DistinctOperation(this, key, queryOption, optionsOption);
1450
+
1451
+ return executeOperation(this.s.topology, distinctOperation, callback);
1419
1452
  };
1420
1453
 
1421
1454
  /**
@@ -1430,7 +1463,9 @@ Collection.prototype.indexes = function(options, callback) {
1430
1463
  if (typeof options === 'function') (callback = options), (options = {});
1431
1464
  options = options || {};
1432
1465
 
1433
- return executeOperation(this.s.topology, indexes, [this, options, callback]);
1466
+ const indexesOperation = new IndexesOperation(this, options);
1467
+
1468
+ return executeOperation(this.s.topology, indexesOperation, callback);
1434
1469
  };
1435
1470
 
1436
1471
  /**
@@ -1448,7 +1483,9 @@ Collection.prototype.stats = function(options, callback) {
1448
1483
  callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
1449
1484
  options = args.length ? args.shift() || {} : {};
1450
1485
 
1451
- return executeOperation(this.s.topology, stats, [this, options, callback]);
1486
+ const statsOperation = new StatsOperation(this, options);
1487
+
1488
+ return executeOperation(this.s.topology, statsOperation, callback);
1452
1489
  };
1453
1490
 
1454
1491
  /**
@@ -1486,7 +1523,9 @@ Collection.prototype.findOneAndDelete = function(filter, options, callback) {
1486
1523
  if (filter == null || typeof filter !== 'object')
1487
1524
  throw toError('filter parameter must be an object');
1488
1525
 
1489
- return executeOperation(this.s.topology, findOneAndDelete, [this, filter, options, callback]);
1526
+ const findOneAndDeleteOperation = new FindOneAndDeleteOperation(this, filter, options);
1527
+
1528
+ return executeOperation(this.s.topology, findOneAndDeleteOperation, callback);
1490
1529
  };
1491
1530
 
1492
1531
  /**
@@ -1515,13 +1554,14 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options,
1515
1554
  if (replacement == null || typeof replacement !== 'object')
1516
1555
  throw toError('replacement parameter must be an object');
1517
1556
 
1518
- return executeOperation(this.s.topology, findOneAndReplace, [
1557
+ const findOneAndReplaceOperation = new FindOneAndReplaceOperation(
1519
1558
  this,
1520
1559
  filter,
1521
1560
  replacement,
1522
- options,
1523
- callback
1524
- ]);
1561
+ options
1562
+ );
1563
+
1564
+ return executeOperation(this.s.topology, findOneAndReplaceOperation, callback);
1525
1565
  };
1526
1566
 
1527
1567
  /**
@@ -1557,13 +1597,9 @@ Collection.prototype.findOneAndUpdate = function(filter, update, options, callba
1557
1597
  return this.s.promiseLibrary.reject(err);
1558
1598
  }
1559
1599
 
1560
- return executeOperation(this.s.topology, findOneAndUpdate, [
1561
- this,
1562
- filter,
1563
- update,
1564
- options,
1565
- callback
1566
- ]);
1600
+ const findOneAndUpdateOperation = new FindOneAndUpdateOperation(this, filter, update, options);
1601
+
1602
+ return executeOperation(this.s.topology, findOneAndUpdateOperation, callback);
1567
1603
  };
1568
1604
 
1569
1605
  /**
@@ -1610,7 +1646,7 @@ function _findAndModify(query, sort, doc, options, callback) {
1610
1646
  // Force read preference primary
1611
1647
  options.readPreference = ReadPreference.PRIMARY;
1612
1648
 
1613
- return executeOperation(this.s.topology, findAndModify, [
1649
+ return executeLegacyOperation(this.s.topology, findAndModify, [
1614
1650
  this,
1615
1651
  query,
1616
1652
  sort,
@@ -1640,7 +1676,13 @@ Collection.prototype.findAndRemove = deprecate(function(query, sort, options, ca
1640
1676
  sort = args.length ? args.shift() || [] : [];
1641
1677
  options = args.length ? args.shift() || {} : {};
1642
1678
 
1643
- return executeOperation(this.s.topology, findAndRemove, [this, query, sort, options, callback]);
1679
+ return executeLegacyOperation(this.s.topology, findAndRemove, [
1680
+ this,
1681
+ query,
1682
+ sort,
1683
+ options,
1684
+ callback
1685
+ ]);
1644
1686
  }, 'collection.findAndRemove is deprecated. Use findOneAndDelete instead.');
1645
1687
 
1646
1688
  /**
@@ -1761,7 +1803,7 @@ Collection.prototype.parallelCollectionScan = deprecate(function(options, callba
1761
1803
 
1762
1804
  options = Object.assign({}, options);
1763
1805
  // Ensure we have the right read preference inheritance
1764
- options.readPreference = resolveReadPreference(options, { db: this.s.db, collection: this });
1806
+ options.readPreference = resolveReadPreference(this, options);
1765
1807
 
1766
1808
  // Add a promiseLibrary
1767
1809
  options.promiseLibrary = this.s.promiseLibrary;
@@ -1770,9 +1812,12 @@ Collection.prototype.parallelCollectionScan = deprecate(function(options, callba
1770
1812
  options.session = undefined;
1771
1813
  }
1772
1814
 
1773
- return executeOperation(this.s.topology, parallelCollectionScan, [this, options, callback], {
1774
- skipSessions: true
1775
- });
1815
+ return executeLegacyOperation(
1816
+ this.s.topology,
1817
+ parallelCollectionScan,
1818
+ [this, options, callback],
1819
+ { skipSessions: true }
1820
+ );
1776
1821
  }, 'parallelCollectionScan is deprecated in MongoDB v4.1');
1777
1822
 
1778
1823
  /**
@@ -1795,7 +1840,9 @@ Collection.prototype.geoHaystackSearch = function(x, y, options, callback) {
1795
1840
  callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
1796
1841
  options = args.length ? args.shift() || {} : {};
1797
1842
 
1798
- return executeOperation(this.s.topology, geoHaystackSearch, [this, x, y, options, callback]);
1843
+ const geoHaystackSearchOperation = new GeoHaystackSearchOperation(this, x, y, options);
1844
+
1845
+ return executeOperation(this.s.topology, geoHaystackSearchOperation, callback);
1799
1846
  };
1800
1847
 
1801
1848
  /**
@@ -1858,7 +1905,7 @@ Collection.prototype.group = deprecate(function(
1858
1905
  // Set up the command as default
1859
1906
  command = command == null ? true : command;
1860
1907
 
1861
- return executeOperation(this.s.topology, group, [
1908
+ return executeLegacyOperation(this.s.topology, group, [
1862
1909
  this,
1863
1910
  keys,
1864
1911
  condition,
@@ -1915,8 +1962,9 @@ Collection.prototype.mapReduce = function(map, reduce, options, callback) {
1915
1962
  if ('function' === typeof options.finalize) {
1916
1963
  options.finalize = options.finalize.toString();
1917
1964
  }
1965
+ const mapReduceOperation = new MapReduceOperation(this, map, reduce, options);
1918
1966
 
1919
- return executeOperation(this.s.topology, mapReduce, [this, map, reduce, options, callback]);
1967
+ return executeOperation(this.s.topology, mapReduceOperation, callback);
1920
1968
  };
1921
1969
 
1922
1970
  /**