mongodb 3.7.2 → 3.7.4
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/lib/bulk/common.js +36 -31
- package/lib/core/auth/scram.js +2 -2
- package/lib/core/error.js +6 -1
- package/lib/core/sessions.js +2 -1
- package/package.json +1 -1
package/lib/bulk/common.js
CHANGED
|
@@ -414,6 +414,15 @@ class WriteError {
|
|
|
414
414
|
}
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Converts the number to a Long or returns it.
|
|
419
|
+
*
|
|
420
|
+
* @ignore
|
|
421
|
+
*/
|
|
422
|
+
function longOrConvert(value) {
|
|
423
|
+
return typeof value === 'number' ? Long.fromNumber(value) : value;
|
|
424
|
+
}
|
|
425
|
+
|
|
417
426
|
/**
|
|
418
427
|
* Merges results into shared data structure
|
|
419
428
|
* @ignore
|
|
@@ -445,42 +454,37 @@ function mergeBatchResults(batch, bulkResult, err, result) {
|
|
|
445
454
|
return;
|
|
446
455
|
}
|
|
447
456
|
|
|
448
|
-
//
|
|
457
|
+
// The server write command specification states that lastOp is an optional
|
|
458
|
+
// mongod only field that has a type of timestamp. Across various scarce specs
|
|
459
|
+
// where opTime is mentioned, it is an "opaque" object that can have a "ts" and
|
|
460
|
+
// "t" field with Timestamp and Long as their types respectively.
|
|
461
|
+
// The "lastOp" field of the bulk write result is never mentioned in the driver
|
|
462
|
+
// specifications or the bulk write spec, so we should probably just keep its
|
|
463
|
+
// value consistent since it seems to vary.
|
|
464
|
+
// See: https://github.com/mongodb/specifications/blob/master/source/driver-bulk-update.rst#results-object
|
|
449
465
|
if (result.opTime || result.lastOp) {
|
|
450
|
-
|
|
451
|
-
let lastOpTS = null;
|
|
452
|
-
let lastOpT = null;
|
|
466
|
+
let opTime = result.lastOp || result.opTime;
|
|
453
467
|
|
|
454
|
-
//
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
}
|
|
461
|
-
} else {
|
|
462
|
-
// Existing TS
|
|
463
|
-
if (bulkResult.lastOp) {
|
|
464
|
-
lastOpTS =
|
|
465
|
-
typeof bulkResult.lastOp.ts === 'number'
|
|
466
|
-
? Long.fromNumber(bulkResult.lastOp.ts)
|
|
467
|
-
: bulkResult.lastOp.ts;
|
|
468
|
-
lastOpT =
|
|
469
|
-
typeof bulkResult.lastOp.t === 'number'
|
|
470
|
-
? Long.fromNumber(bulkResult.lastOp.t)
|
|
471
|
-
: bulkResult.lastOp.t;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// Current OpTime TS
|
|
475
|
-
const opTimeTS = typeof opTime.ts === 'number' ? Long.fromNumber(opTime.ts) : opTime.ts;
|
|
476
|
-
const opTimeT = typeof opTime.t === 'number' ? Long.fromNumber(opTime.t) : opTime.t;
|
|
468
|
+
// If the opTime is a Timestamp, convert it to a consistent format to be
|
|
469
|
+
// able to compare easily. Converting to the object from a timestamp is
|
|
470
|
+
// much more straightforward than the other direction.
|
|
471
|
+
if (opTime._bsontype === 'Timestamp') {
|
|
472
|
+
opTime = { ts: opTime, t: Long.ZERO };
|
|
473
|
+
}
|
|
477
474
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
475
|
+
// If there's no lastOp, just set it.
|
|
476
|
+
if (!bulkResult.lastOp) {
|
|
477
|
+
bulkResult.lastOp = opTime;
|
|
478
|
+
} else {
|
|
479
|
+
// First compare the ts values and set if the opTimeTS value is greater.
|
|
480
|
+
const lastOpTS = longOrConvert(bulkResult.lastOp.ts);
|
|
481
|
+
const opTimeTS = longOrConvert(opTime.ts);
|
|
482
|
+
if (opTimeTS.greaterThan(lastOpTS)) {
|
|
482
483
|
bulkResult.lastOp = opTime;
|
|
483
484
|
} else if (opTimeTS.equals(lastOpTS)) {
|
|
485
|
+
// If the ts values are equal, then compare using the t values.
|
|
486
|
+
const lastOpT = longOrConvert(bulkResult.lastOp.t);
|
|
487
|
+
const opTimeT = longOrConvert(opTime.t);
|
|
484
488
|
if (opTimeT.greaterThan(lastOpT)) {
|
|
485
489
|
bulkResult.lastOp = opTime;
|
|
486
490
|
}
|
|
@@ -1387,6 +1391,7 @@ Object.defineProperty(BulkOperationBase.prototype, 'length', {
|
|
|
1387
1391
|
module.exports = {
|
|
1388
1392
|
Batch,
|
|
1389
1393
|
BulkOperationBase,
|
|
1394
|
+
mergeBatchResults,
|
|
1390
1395
|
bson,
|
|
1391
1396
|
INSERT: INSERT,
|
|
1392
1397
|
UPDATE: UPDATE,
|
package/lib/core/auth/scram.js
CHANGED
|
@@ -25,7 +25,7 @@ class ScramSHA extends AuthProvider {
|
|
|
25
25
|
|
|
26
26
|
prepare(handshakeDoc, authContext, callback) {
|
|
27
27
|
const cryptoMethod = this.cryptoMethod;
|
|
28
|
-
if (cryptoMethod === 'sha256' && saslprep
|
|
28
|
+
if (cryptoMethod === 'sha256' && typeof saslprep !== 'function') {
|
|
29
29
|
emitWarningOnce('Warning: no saslprep library specified. Passwords will not be sanitized');
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -125,7 +125,7 @@ function continueScramConversation(cryptoMethod, response, authContext, callback
|
|
|
125
125
|
|
|
126
126
|
let processedPassword;
|
|
127
127
|
if (cryptoMethod === 'sha256') {
|
|
128
|
-
processedPassword = saslprep ? saslprep(password) : password;
|
|
128
|
+
processedPassword = typeof saslprep === 'function' ? saslprep(password) : password;
|
|
129
129
|
} else {
|
|
130
130
|
try {
|
|
131
131
|
processedPassword = passwordDigest(username, password);
|
package/lib/core/error.js
CHANGED
|
@@ -246,6 +246,10 @@ const RETRYABLE_WRITE_ERROR_CODES = new Set([
|
|
|
246
246
|
MONGODB_ERROR_CODES.ExceededTimeLimit
|
|
247
247
|
]);
|
|
248
248
|
|
|
249
|
+
function isRetryableEndTransactionError(error) {
|
|
250
|
+
return error.hasErrorLabel('RetryableWriteError');
|
|
251
|
+
}
|
|
252
|
+
|
|
249
253
|
function isRetryableWriteError(error) {
|
|
250
254
|
if (error instanceof MongoWriteConcernError) {
|
|
251
255
|
return (
|
|
@@ -347,5 +351,6 @@ module.exports = {
|
|
|
347
351
|
isSDAMUnrecoverableError,
|
|
348
352
|
isNodeShuttingDownError,
|
|
349
353
|
isRetryableWriteError,
|
|
350
|
-
isNetworkErrorBeforeHandshake
|
|
354
|
+
isNetworkErrorBeforeHandshake,
|
|
355
|
+
isRetryableEndTransactionError
|
|
351
356
|
};
|
package/lib/core/sessions.js
CHANGED
|
@@ -7,6 +7,7 @@ const Binary = BSON.Binary;
|
|
|
7
7
|
const uuidV4 = require('./utils').uuidV4;
|
|
8
8
|
const MongoError = require('./error').MongoError;
|
|
9
9
|
const isRetryableError = require('././error').isRetryableError;
|
|
10
|
+
const isRetryableEndTransactionError = require('././error').isRetryableEndTransactionError;
|
|
10
11
|
const MongoNetworkError = require('./error').MongoNetworkError;
|
|
11
12
|
const MongoWriteConcernError = require('./error').MongoWriteConcernError;
|
|
12
13
|
const Transaction = require('./transactions').Transaction;
|
|
@@ -511,7 +512,7 @@ function endTransaction(session, commandName, callback) {
|
|
|
511
512
|
|
|
512
513
|
// send the command
|
|
513
514
|
session.topology.command('admin.$cmd', command, { session }, (err, reply) => {
|
|
514
|
-
if (err &&
|
|
515
|
+
if (err && isRetryableEndTransactionError(err)) {
|
|
515
516
|
// SPEC-1185: apply majority write concern when retrying commitTransaction
|
|
516
517
|
if (command.commitTransaction) {
|
|
517
518
|
// per txns spec, must unpin session in this case
|