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.
- package/README.md +4 -4
- package/index.js +4 -0
- package/lib/bulk/common.js +6 -3
- package/lib/cmap/connection.js +35 -7
- package/lib/cmap/connection_pool.js +1 -0
- package/lib/collection.js +10 -1
- package/lib/command_utils.js +124 -0
- package/lib/core/auth/mongo_credentials.js +4 -1
- package/lib/core/auth/mongodb_aws.js +17 -15
- package/lib/core/auth/scram.js +1 -0
- package/lib/core/connection/apm.js +10 -123
- package/lib/core/connection/commands.js +11 -2
- package/lib/core/connection/connect.js +10 -1
- package/lib/core/connection/connection.js +7 -3
- package/lib/core/connection/msg.js +11 -2
- package/lib/core/connection/pool.js +7 -2
- package/lib/core/connection/utils.js +35 -2
- package/lib/core/cursor.js +7 -0
- package/lib/core/index.js +10 -0
- package/lib/core/sdam/monitor.js +9 -2
- package/lib/core/sdam/server.js +10 -1
- package/lib/core/sdam/topology.js +34 -16
- package/lib/core/sessions.js +11 -8
- package/lib/core/topologies/mongos.js +1 -0
- package/lib/core/topologies/replset.js +1 -0
- package/lib/core/topologies/server.js +7 -2
- package/lib/core/transactions.js +5 -1
- package/lib/core/uri_parser.js +5 -0
- package/lib/core/utils.js +1 -0
- package/lib/core/wireprotocol/command.js +24 -0
- package/lib/core/wireprotocol/constants.js +2 -2
- package/lib/core/wireprotocol/kill_cursors.js +7 -2
- package/lib/core/wireprotocol/query.js +9 -5
- package/lib/core/wireprotocol/shared.js +1 -0
- package/lib/cursor.js +16 -2
- package/lib/db.js +83 -72
- package/lib/encrypter.js +8 -3
- package/lib/explain.js +5 -12
- package/lib/gridfs-stream/index.js +39 -24
- package/lib/gridfs-stream/upload.js +46 -38
- package/lib/mongo_client.js +31 -5
- package/lib/operations/command.js +4 -1
- package/lib/operations/command_v2.js +7 -1
- package/lib/operations/connect.js +2 -0
- package/lib/operations/db_ops.js +6 -2
- package/lib/operations/estimated_document_count.js +46 -18
- package/lib/topologies/mongos.js +1 -0
- package/lib/topologies/native_topology.js +2 -0
- package/lib/topologies/replset.js +1 -0
- package/lib/topologies/server.js +1 -0
- package/lib/utils.js +87 -1
- package/package.json +7 -3
- 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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
144
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
options
|
|
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
|
-
|
|
427
|
-
|
|
428
|
-
? new ReadConcern(options.readConcern.level)
|
|
429
|
-
: this.readConcern;
|
|
432
|
+
// Set the promise library
|
|
433
|
+
options.promiseLibrary = this.s.promiseLibrary;
|
|
430
434
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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
|
-
|
|
437
|
-
if (
|
|
438
|
-
options
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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
|
|
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
|
-
|
|
16
|
-
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
|
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
|
|
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 =
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
options
|
|
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
|
-
|
|
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 =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
135
|
+
if (!options.chunkSizeBytes) {
|
|
136
|
+
options.chunkSizeBytes = this.s.options.chunkSizeBytes;
|
|
137
|
+
}
|
|
124
138
|
|
|
125
|
-
|
|
139
|
+
options.id = id;
|
|
126
140
|
|
|
127
|
-
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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;
|