mongodb 3.6.9 → 3.7.0

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 (53) hide show
  1. package/README.md +4 -4
  2. package/index.js +4 -0
  3. package/lib/bulk/common.js +6 -3
  4. package/lib/cmap/connection.js +35 -7
  5. package/lib/cmap/connection_pool.js +1 -0
  6. package/lib/collection.js +10 -1
  7. package/lib/command_utils.js +124 -0
  8. package/lib/core/auth/mongo_credentials.js +4 -1
  9. package/lib/core/auth/mongodb_aws.js +17 -15
  10. package/lib/core/auth/scram.js +1 -0
  11. package/lib/core/connection/apm.js +10 -123
  12. package/lib/core/connection/commands.js +11 -2
  13. package/lib/core/connection/connect.js +10 -1
  14. package/lib/core/connection/connection.js +7 -3
  15. package/lib/core/connection/msg.js +11 -2
  16. package/lib/core/connection/pool.js +7 -2
  17. package/lib/core/connection/utils.js +35 -2
  18. package/lib/core/cursor.js +7 -0
  19. package/lib/core/index.js +10 -0
  20. package/lib/core/sdam/monitor.js +9 -2
  21. package/lib/core/sdam/server.js +10 -1
  22. package/lib/core/sdam/topology.js +34 -16
  23. package/lib/core/sessions.js +11 -8
  24. package/lib/core/topologies/mongos.js +1 -0
  25. package/lib/core/topologies/replset.js +1 -0
  26. package/lib/core/topologies/server.js +7 -2
  27. package/lib/core/transactions.js +5 -1
  28. package/lib/core/uri_parser.js +5 -0
  29. package/lib/core/utils.js +1 -0
  30. package/lib/core/wireprotocol/command.js +24 -0
  31. package/lib/core/wireprotocol/constants.js +2 -2
  32. package/lib/core/wireprotocol/kill_cursors.js +7 -2
  33. package/lib/core/wireprotocol/query.js +9 -5
  34. package/lib/core/wireprotocol/shared.js +1 -0
  35. package/lib/cursor.js +16 -2
  36. package/lib/db.js +83 -72
  37. package/lib/encrypter.js +8 -3
  38. package/lib/explain.js +5 -12
  39. package/lib/gridfs-stream/index.js +39 -24
  40. package/lib/gridfs-stream/upload.js +46 -38
  41. package/lib/mongo_client.js +31 -5
  42. package/lib/operations/command.js +4 -1
  43. package/lib/operations/command_v2.js +7 -1
  44. package/lib/operations/connect.js +2 -0
  45. package/lib/operations/db_ops.js +6 -2
  46. package/lib/operations/estimated_document_count.js +46 -18
  47. package/lib/topologies/mongos.js +1 -0
  48. package/lib/topologies/native_topology.js +2 -0
  49. package/lib/topologies/replset.js +1 -0
  50. package/lib/topologies/server.js +1 -0
  51. package/lib/utils.js +87 -1
  52. package/package.json +7 -3
  53. package/HISTORY.md +0 -2889
@@ -8,8 +8,13 @@ const maxWireVersion = require('../utils').maxWireVersion;
8
8
  const emitWarning = require('../utils').emitWarning;
9
9
  const command = require('./command');
10
10
 
11
- function killCursors(server, ns, cursorState, callback) {
11
+ function killCursors(server, ns, cursorState, defaultOptions, callback) {
12
+ if (typeof defaultOptions === 'function') {
13
+ callback = defaultOptions;
14
+ defaultOptions = {};
15
+ }
12
16
  callback = typeof callback === 'function' ? callback : () => {};
17
+
13
18
  const cursorId = cursorState.cursorId;
14
19
 
15
20
  if (maxWireVersion(server) < 4) {
@@ -45,7 +50,7 @@ function killCursors(server, ns, cursorState, callback) {
45
50
  cursors: [cursorId]
46
51
  };
47
52
 
48
- const options = {};
53
+ const options = defaultOptions || {};
49
54
  if (typeof cursorState.session === 'object') options.session = cursorState.session;
50
55
 
51
56
  command(server, ns, killCursorCmd, options, (err, result) => {
@@ -37,9 +37,13 @@ function query(server, ns, cmd, cursorState, options, callback) {
37
37
 
38
38
  // If we have explain, we need to rewrite the find command
39
39
  // to wrap it in the explain command
40
- const explain = Explain.fromOptions(options);
41
- if (explain) {
42
- findCmd = decorateWithExplain(findCmd, explain);
40
+ try {
41
+ const explain = Explain.fromOptions(options);
42
+ if (explain) {
43
+ findCmd = decorateWithExplain(findCmd, explain);
44
+ }
45
+ } catch (err) {
46
+ return callback(err);
43
47
  }
44
48
 
45
49
  // NOTE: This actually modifies the passed in cmd, and our code _depends_ on this
@@ -140,8 +144,8 @@ function prepareFindCommand(server, ns, cmd, cursorState) {
140
144
  if (cmd.maxTimeMS) findCmd.maxTimeMS = cmd.maxTimeMS;
141
145
  if (cmd.min) findCmd.min = cmd.min;
142
146
  if (cmd.max) findCmd.max = cmd.max;
143
- findCmd.returnKey = cmd.returnKey ? cmd.returnKey : false;
144
- findCmd.showRecordId = cmd.showDiskLoc ? cmd.showDiskLoc : false;
147
+ if (typeof cmd.returnKey === 'boolean') findCmd.returnKey = cmd.returnKey;
148
+ if (typeof cmd.showDiskLoc === 'boolean') findCmd.showRecordId = cmd.showDiskLoc;
145
149
  if (cmd.snapshot) findCmd.snapshot = cmd.snapshot;
146
150
  if (cmd.tailable) findCmd.tailable = cmd.tailable;
147
151
  if (cmd.oplogReplay) findCmd.oplogReplay = cmd.oplogReplay;
@@ -57,6 +57,7 @@ function applyCommonQueryOptions(queryOptions, options) {
57
57
  promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true,
58
58
  promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true,
59
59
  promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false,
60
+ bsonRegExp: typeof options.bsonRegExp === 'boolean' ? options.bsonRegExp : false,
60
61
  monitoring: typeof options.monitoring === 'boolean' ? options.monitoring : false,
61
62
  fullResult: typeof options.fullResult === 'boolean' ? options.fullResult : false
62
63
  });
package/lib/cursor.js CHANGED
@@ -165,6 +165,10 @@ class Cursor extends CoreCursor {
165
165
  return this.cmd.sort;
166
166
  }
167
167
 
168
+ set session(clientSession) {
169
+ this.cursorState.session = clientSession;
170
+ }
171
+
168
172
  _initializeCursor(callback) {
169
173
  if (this.operation && this.operation.session != null) {
170
174
  this.cursorState.session = this.operation.session;
@@ -742,7 +746,12 @@ class Cursor extends CoreCursor {
742
746
  return false;
743
747
  }
744
748
  if (doc != null) {
745
- iterator(doc);
749
+ try {
750
+ iterator(doc);
751
+ } catch (error) {
752
+ callback(error);
753
+ return false;
754
+ }
746
755
  return true;
747
756
  }
748
757
  if (doc == null && callback) {
@@ -762,7 +771,12 @@ class Cursor extends CoreCursor {
762
771
  fulfill(null);
763
772
  return false;
764
773
  } else {
765
- iterator(doc);
774
+ try {
775
+ iterator(doc);
776
+ } catch (error) {
777
+ reject(error);
778
+ return false;
779
+ }
766
780
  return true;
767
781
  }
768
782
  });
package/lib/db.js CHANGED
@@ -83,7 +83,6 @@ const legalOptionNames = [
83
83
  'bufferMaxEntries',
84
84
  'authSource',
85
85
  'ignoreUndefined',
86
- 'promoteLongs',
87
86
  'promiseLibrary',
88
87
  'readConcern',
89
88
  'retryMiliSeconds',
@@ -95,6 +94,7 @@ const legalOptionNames = [
95
94
  'promoteBuffers',
96
95
  'promoteLongs',
97
96
  'promoteValues',
97
+ 'bsonRegExp',
98
98
  'compression',
99
99
  'retryWrites'
100
100
  ];
@@ -117,6 +117,7 @@ const legalOptionNames = [
117
117
  * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
118
118
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
119
119
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
120
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
120
121
  * @param {number} [options.bufferMaxEntries=-1] Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited.
121
122
  * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
122
123
  * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys.
@@ -323,6 +324,7 @@ Db.prototype.command = function(command, options, callback) {
323
324
  * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
324
325
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
325
326
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
327
+ * @param {boolean} [options.bsonRegExp=false] By default, regex returned from MDB will be native to the language. Setting to true will ensure that a BSON.BSONRegExp object is returned.
326
328
  * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
327
329
  * @param {string} [options.comment] Add a comment to an aggregation command
328
330
  * @param {string|object} [options.hint] Add an index selection hint to an aggregation command
@@ -391,7 +393,8 @@ const COLLECTION_OPTION_KEYS = [
391
393
  'ignoreUndefined',
392
394
  'promoteValues',
393
395
  'promoteBuffers',
394
- 'promoteLongs'
396
+ 'promoteLongs',
397
+ 'bsonRegExp'
395
398
  ];
396
399
 
397
400
  /**
@@ -409,91 +412,98 @@ const COLLECTION_OPTION_KEYS = [
409
412
  * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys.
410
413
  * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
411
414
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
412
- * @param {boolean} [options.strict=false] Returns an error if the collection does not exist
415
+ * @param {boolean} [options.strict=false] **Deprecated** Returns an error if the collection does not exist
413
416
  * @param {object} [options.readConcern] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
414
417
  * @param {ReadConcernLevel} [options.readConcern.level='local'] Specify a read concern level for the collection operations (only MongoDB 3.2 or higher supported)
415
418
  * @param {Db~collectionResultCallback} [callback] The collection result callback
416
419
  * @return {Collection} return the new Collection instance if not in strict mode
417
420
  */
418
- Db.prototype.collection = function(name, options, callback) {
419
- if (typeof options === 'function') (callback = options), (options = {});
420
- options = options || {};
421
- options = Object.assign({}, options);
422
-
423
- // Set the promise library
424
- options.promiseLibrary = this.s.promiseLibrary;
421
+ Db.prototype.collection = deprecateOptions(
422
+ {
423
+ name: 'Db.collection',
424
+ deprecatedOptions: ['strict'],
425
+ optionsIndex: 1
426
+ },
427
+ function(name, options, callback) {
428
+ if (typeof options === 'function') (callback = options), (options = {});
429
+ options = options || {};
430
+ options = Object.assign({}, options);
425
431
 
426
- // If we have not set a collection level readConcern set the db level one
427
- options.readConcern = options.readConcern
428
- ? new ReadConcern(options.readConcern.level)
429
- : this.readConcern;
432
+ // Set the promise library
433
+ options.promiseLibrary = this.s.promiseLibrary;
430
434
 
431
- // Do we have ignoreUndefined set
432
- if (this.s.options.ignoreUndefined) {
433
- options.ignoreUndefined = this.s.options.ignoreUndefined;
434
- }
435
+ // If we have not set a collection level readConcern set the db level one
436
+ options.readConcern = options.readConcern
437
+ ? new ReadConcern(options.readConcern.level)
438
+ : this.readConcern;
435
439
 
436
- for (const collectionOptionKey of COLLECTION_OPTION_KEYS) {
437
- if (!(collectionOptionKey in options) && this.s.options[collectionOptionKey] !== undefined) {
438
- options[collectionOptionKey] = this.s.options[collectionOptionKey];
440
+ // Do we have ignoreUndefined set
441
+ if (this.s.options.ignoreUndefined) {
442
+ options.ignoreUndefined = this.s.options.ignoreUndefined;
439
443
  }
440
- }
441
444
 
442
- // Merge in all needed options and ensure correct writeConcern merging from db level
443
- options = conditionallyMergeWriteConcern(options, this.s.options);
444
-
445
- // Execute
446
- if (options == null || !options.strict) {
447
- try {
448
- const collection = new Collection(
449
- this,
450
- this.s.topology,
451
- this.databaseName,
452
- name,
453
- this.s.pkFactory,
454
- options
455
- );
456
- if (callback) callback(null, collection);
457
- return collection;
458
- } catch (err) {
459
- if (err instanceof MongoError && callback) return callback(err);
460
- throw err;
445
+ for (const collectionOptionKey of COLLECTION_OPTION_KEYS) {
446
+ if (!(collectionOptionKey in options) && this.s.options[collectionOptionKey] !== undefined) {
447
+ options[collectionOptionKey] = this.s.options[collectionOptionKey];
448
+ }
461
449
  }
462
- }
463
450
 
464
- // Strict mode
465
- if (typeof callback !== 'function') {
466
- throw toError(`A callback is required in strict mode. While getting collection ${name}`);
467
- }
451
+ // Merge in all needed options and ensure correct writeConcern merging from db level
452
+ options = conditionallyMergeWriteConcern(options, this.s.options);
453
+
454
+ // Execute
455
+ if (options == null || !options.strict) {
456
+ try {
457
+ const collection = new Collection(
458
+ this,
459
+ this.s.topology,
460
+ this.databaseName,
461
+ name,
462
+ this.s.pkFactory,
463
+ options
464
+ );
465
+ if (callback) callback(null, collection);
466
+ return collection;
467
+ } catch (err) {
468
+ if (err instanceof MongoError && callback) return callback(err);
469
+ throw err;
470
+ }
471
+ }
468
472
 
469
- // Did the user destroy the topology
470
- if (this.serverConfig && this.serverConfig.isDestroyed()) {
471
- return callback(new MongoError('topology was destroyed'));
472
- }
473
+ // Strict mode
474
+ if (typeof callback !== 'function') {
475
+ throw toError(`A callback is required in strict mode. While getting collection ${name}`);
476
+ }
473
477
 
474
- const listCollectionOptions = Object.assign({}, options, { nameOnly: true });
475
-
476
- // Strict mode
477
- this.listCollections({ name: name }, listCollectionOptions).toArray((err, collections) => {
478
- if (err != null) return handleCallback(callback, err, null);
479
- if (collections.length === 0)
480
- return handleCallback(
481
- callback,
482
- toError(`Collection ${name} does not exist. Currently in strict mode.`),
483
- null
484
- );
485
-
486
- try {
487
- return handleCallback(
488
- callback,
489
- null,
490
- new Collection(this, this.s.topology, this.databaseName, name, this.s.pkFactory, options)
491
- );
492
- } catch (err) {
493
- return handleCallback(callback, err, null);
478
+ // Did the user destroy the topology
479
+ if (this.serverConfig && this.serverConfig.isDestroyed()) {
480
+ return callback(new MongoError('topology was destroyed'));
494
481
  }
495
- });
496
- };
482
+
483
+ const listCollectionOptions = Object.assign({}, options, { nameOnly: true });
484
+
485
+ // Strict mode
486
+ this.listCollections({ name: name }, listCollectionOptions).toArray((err, collections) => {
487
+ if (err != null) return handleCallback(callback, err, null);
488
+ if (collections.length === 0)
489
+ return handleCallback(
490
+ callback,
491
+ toError(`Collection ${name} does not exist. Currently in strict mode.`),
492
+ null
493
+ );
494
+
495
+ try {
496
+ return handleCallback(
497
+ callback,
498
+ null,
499
+ new Collection(this, this.s.topology, this.databaseName, name, this.s.pkFactory, options)
500
+ );
501
+ } catch (err) {
502
+ return handleCallback(callback, err, null);
503
+ }
504
+ });
505
+ }
506
+ );
497
507
 
498
508
  /**
499
509
  * Create a new collection on a server with the specified options. Use this to create capped collections.
@@ -941,6 +951,7 @@ Db.prototype.indexInformation = function(name, options, callback) {
941
951
  /**
942
952
  * Unref all sockets
943
953
  * @method
954
+ * @deprecated This function is deprecated and will be removed in the next major version.
944
955
  */
945
956
  Db.prototype.unref = function() {
946
957
  this.s.topology.unref();
package/lib/encrypter.js CHANGED
@@ -3,8 +3,10 @@ const MongoClient = require('./mongo_client');
3
3
  const BSON = require('./core/connection/utils').retrieveBSON();
4
4
  const MongoError = require('./core/error').MongoError;
5
5
 
6
+ let mongodbClientEncryption = undefined;
6
7
  try {
7
- require.resolve('mongodb-client-encryption');
8
+ // Ensure you always wrap an optional require in the try block NODE-3199
9
+ mongodbClientEncryption = require('mongodb-client-encryption');
8
10
  } catch (err) {
9
11
  throw new MongoError(
10
12
  'Auto-encryption requested, but the module is not installed. ' +
@@ -12,13 +14,16 @@ try {
12
14
  );
13
15
  }
14
16
 
15
- const mongodbClientEncryption = require('mongodb-client-encryption');
16
- if (typeof mongodbClientEncryption.extension !== 'function') {
17
+ if (
18
+ mongodbClientEncryption === undefined ||
19
+ typeof mongodbClientEncryption.extension !== 'function'
20
+ ) {
17
21
  throw new MongoError(
18
22
  'loaded version of `mongodb-client-encryption` does not have property `extension`. ' +
19
23
  'Please make sure you are loading the correct version of `mongodb-client-encryption`'
20
24
  );
21
25
  }
26
+
22
27
  const AutoEncrypter = mongodbClientEncryption.extension(require('../index')).AutoEncrypter;
23
28
 
24
29
  const kInternalClient = Symbol('internalClient');
package/lib/explain.js CHANGED
@@ -2,16 +2,9 @@
2
2
 
3
3
  const MongoError = require('./core/error').MongoError;
4
4
 
5
- const ExplainVerbosity = {
6
- queryPlanner: 'queryPlanner',
7
- queryPlannerExtended: 'queryPlannerExtended',
8
- executionStats: 'executionStats',
9
- allPlansExecution: 'allPlansExecution'
10
- };
11
-
12
5
  /**
13
6
  * @class
14
- * @property {'queryPlanner'|'queryPlannerExtended'|'executionStats'|'allPlansExecution'} verbosity The verbosity mode for the explain output.
7
+ * @property {string} verbosity The verbosity mode for the explain output, e.g.: 'queryPlanner', 'queryPlannerExtended', 'executionStats', 'allPlansExecution'.
15
8
  */
16
9
  class Explain {
17
10
  /**
@@ -21,7 +14,7 @@ class Explain {
21
14
  * and false as "queryPlanner". Prior to server version 3.6, aggregate()
22
15
  * ignores the verbosity parameter and executes in "queryPlanner".
23
16
  *
24
- * @param {'queryPlanner'|'queryPlannerExtended'|'executionStats'|'allPlansExecution'|boolean} [verbosity] The verbosity mode for the explain output.
17
+ * @param {string|boolean} [verbosity] The verbosity mode for the explain output.
25
18
  */
26
19
  constructor(verbosity) {
27
20
  if (typeof verbosity === 'boolean') {
@@ -35,7 +28,7 @@ class Explain {
35
28
  * Construct an Explain given an options object.
36
29
  *
37
30
  * @param {object} [options] The options object from which to extract the explain.
38
- * @param {'queryPlanner'|'queryPlannerExtended'|'executionStats'|'allPlansExecution'|boolean} [options.explain] The verbosity mode for the explain output
31
+ * @param {string|boolean} [options.explain] The verbosity mode for the explain output.
39
32
  * @return {Explain}
40
33
  */
41
34
  static fromOptions(options) {
@@ -44,11 +37,11 @@ class Explain {
44
37
  }
45
38
 
46
39
  const explain = options.explain;
47
- if (typeof explain === 'boolean' || explain in ExplainVerbosity) {
40
+ if (typeof explain === 'boolean' || typeof explain === 'string') {
48
41
  return new Explain(options.explain);
49
42
  }
50
43
 
51
- throw new MongoError(`explain must be one of ${Object.keys(ExplainVerbosity)} or a boolean`);
44
+ throw new MongoError(`explain must be a string or a boolean`);
52
45
  }
53
46
  }
54
47
 
@@ -7,6 +7,7 @@ var shallowClone = require('../utils').shallowClone;
7
7
  var toError = require('../utils').toError;
8
8
  var util = require('util');
9
9
  var executeLegacyOperation = require('../utils').executeLegacyOperation;
10
+ const deprecateOptions = require('../utils').deprecateOptions;
10
11
 
11
12
  var DEFAULT_GRIDFS_BUCKET_OPTIONS = {
12
13
  bucketName: 'fs',
@@ -79,21 +80,28 @@ util.inherits(GridFSBucket, Emitter);
79
80
  * @param {object} [options.metadata] Optional object to store in the file document's `metadata` field
80
81
  * @param {string} [options.contentType] Optional string to store in the file document's `contentType` field
81
82
  * @param {array} [options.aliases] Optional array of strings to store in the file document's `aliases` field
82
- * @param {boolean} [options.disableMD5=false] If true, disables adding an md5 field to file data
83
+ * @param {boolean} [options.disableMD5=false] **Deprecated** If true, disables adding an md5 field to file data
83
84
  * @return {GridFSBucketWriteStream}
84
85
  */
85
86
 
86
- GridFSBucket.prototype.openUploadStream = function(filename, options) {
87
- if (options) {
88
- options = shallowClone(options);
89
- } else {
90
- options = {};
91
- }
92
- if (!options.chunkSizeBytes) {
93
- options.chunkSizeBytes = this.s.options.chunkSizeBytes;
87
+ GridFSBucket.prototype.openUploadStream = deprecateOptions(
88
+ {
89
+ name: 'GridFSBucket.openUploadStream',
90
+ deprecatedOptions: ['disableMD5'],
91
+ optionsIndex: 1
92
+ },
93
+ function(filename, options) {
94
+ if (options) {
95
+ options = shallowClone(options);
96
+ } else {
97
+ options = {};
98
+ }
99
+ if (!options.chunkSizeBytes) {
100
+ options.chunkSizeBytes = this.s.options.chunkSizeBytes;
101
+ }
102
+ return new GridFSBucketWriteStream(this, filename, options);
94
103
  }
95
- return new GridFSBucketWriteStream(this, filename, options);
96
- };
104
+ );
97
105
 
98
106
  /**
99
107
  * Returns a writable stream (GridFSBucketWriteStream) for writing
@@ -107,25 +115,32 @@ GridFSBucket.prototype.openUploadStream = function(filename, options) {
107
115
  * @param {object} [options.metadata] Optional object to store in the file document's `metadata` field
108
116
  * @param {string} [options.contentType] Optional string to store in the file document's `contentType` field
109
117
  * @param {array} [options.aliases] Optional array of strings to store in the file document's `aliases` field
110
- * @param {boolean} [options.disableMD5=false] If true, disables adding an md5 field to file data
118
+ * @param {boolean} [options.disableMD5=false] **Deprecated** If true, disables adding an md5 field to file data
111
119
  * @return {GridFSBucketWriteStream}
112
120
  */
113
121
 
114
- GridFSBucket.prototype.openUploadStreamWithId = function(id, filename, options) {
115
- if (options) {
116
- options = shallowClone(options);
117
- } else {
118
- options = {};
119
- }
122
+ GridFSBucket.prototype.openUploadStreamWithId = deprecateOptions(
123
+ {
124
+ name: 'GridFSBucket.openUploadStreamWithId',
125
+ deprecatedOptions: ['disableMD5'],
126
+ optionsIndex: 2
127
+ },
128
+ function(id, filename, options) {
129
+ if (options) {
130
+ options = shallowClone(options);
131
+ } else {
132
+ options = {};
133
+ }
120
134
 
121
- if (!options.chunkSizeBytes) {
122
- options.chunkSizeBytes = this.s.options.chunkSizeBytes;
123
- }
135
+ if (!options.chunkSizeBytes) {
136
+ options.chunkSizeBytes = this.s.options.chunkSizeBytes;
137
+ }
124
138
 
125
- options.id = id;
139
+ options.id = id;
126
140
 
127
- return new GridFSBucketWriteStream(this, filename, options);
128
- };
141
+ return new GridFSBucketWriteStream(this, filename, options);
142
+ }
143
+ );
129
144
 
130
145
  /**
131
146
  * Returns a readable stream (GridFSBucketReadStream) for streaming file
@@ -5,10 +5,9 @@ var crypto = require('crypto');
5
5
  var stream = require('stream');
6
6
  var util = require('util');
7
7
  var Buffer = require('safe-buffer').Buffer;
8
+ const deprecateOptions = require('../utils').deprecateOptions;
8
9
 
9
- var ERROR_NAMESPACE_NOT_FOUND = 26;
10
-
11
- module.exports = GridFSBucketWriteStream;
10
+ const ERROR_NAMESPACE_NOT_FOUND = 26;
12
11
 
13
12
  /**
14
13
  * A writable stream that enables you to write buffers to GridFS.
@@ -31,42 +30,49 @@ module.exports = GridFSBucketWriteStream;
31
30
  * @fires GridFSBucketWriteStream#finish
32
31
  */
33
32
 
34
- function GridFSBucketWriteStream(bucket, filename, options) {
35
- options = options || {};
36
- stream.Writable.call(this, options);
37
- this.bucket = bucket;
38
- this.chunks = bucket.s._chunksCollection;
39
- this.filename = filename;
40
- this.files = bucket.s._filesCollection;
41
- this.options = options;
42
- // Signals the write is all done
43
- this.done = false;
44
-
45
- this.id = options.id ? options.id : core.BSON.ObjectId();
46
- this.chunkSizeBytes = this.options.chunkSizeBytes;
47
- this.bufToStore = Buffer.alloc(this.chunkSizeBytes);
48
- this.length = 0;
49
- this.md5 = !options.disableMD5 && crypto.createHash('md5');
50
- this.n = 0;
51
- this.pos = 0;
52
- this.state = {
53
- streamEnd: false,
54
- outstandingRequests: 0,
55
- errored: false,
56
- aborted: false,
57
- promiseLibrary: this.bucket.s.promiseLibrary
58
- };
59
-
60
- if (!this.bucket.s.calledOpenUploadStream) {
61
- this.bucket.s.calledOpenUploadStream = true;
62
-
63
- var _this = this;
64
- checkIndexes(this, function() {
65
- _this.bucket.s.checkedIndexes = true;
66
- _this.bucket.emit('index');
67
- });
33
+ const GridFSBucketWriteStream = deprecateOptions(
34
+ {
35
+ name: 'GridFSBucketWriteStream',
36
+ deprecatedOptions: ['disableMD5'],
37
+ optionsIndex: 2
38
+ },
39
+ function(bucket, filename, options) {
40
+ options = options || {};
41
+ stream.Writable.call(this, options);
42
+ this.bucket = bucket;
43
+ this.chunks = bucket.s._chunksCollection;
44
+ this.filename = filename;
45
+ this.files = bucket.s._filesCollection;
46
+ this.options = options;
47
+ // Signals the write is all done
48
+ this.done = false;
49
+
50
+ this.id = options.id ? options.id : core.BSON.ObjectId();
51
+ this.chunkSizeBytes = this.options.chunkSizeBytes;
52
+ this.bufToStore = Buffer.alloc(this.chunkSizeBytes);
53
+ this.length = 0;
54
+ this.md5 = !options.disableMD5 && crypto.createHash('md5');
55
+ this.n = 0;
56
+ this.pos = 0;
57
+ this.state = {
58
+ streamEnd: false,
59
+ outstandingRequests: 0,
60
+ errored: false,
61
+ aborted: false,
62
+ promiseLibrary: this.bucket.s.promiseLibrary
63
+ };
64
+
65
+ if (!this.bucket.s.calledOpenUploadStream) {
66
+ this.bucket.s.calledOpenUploadStream = true;
67
+
68
+ var _this = this;
69
+ checkIndexes(this, function() {
70
+ _this.bucket.s.checkedIndexes = true;
71
+ _this.bucket.emit('index');
72
+ });
73
+ }
68
74
  }
69
- }
75
+ );
70
76
 
71
77
  util.inherits(GridFSBucketWriteStream, stream.Writable);
72
78
 
@@ -539,3 +545,5 @@ function checkAborted(_this, callback) {
539
545
  }
540
546
  return false;
541
547
  }
548
+
549
+ module.exports = GridFSBucketWriteStream;