mongodb 4.1.3 → 4.2.2
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 +15 -14
- package/lib/admin.js +5 -5
- package/lib/admin.js.map +1 -1
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +54 -56
- package/lib/bulk/common.js.map +1 -1
- package/lib/change_stream.js +13 -14
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +1 -1
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongocr.js +2 -2
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +3 -3
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/plain.js +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/scram.js +5 -5
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +1 -1
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +15 -15
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +10 -7
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +2 -2
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +15 -15
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +3 -3
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/message_stream.js +2 -2
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/stream_description.js +4 -4
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/constants.js +4 -4
- package/lib/collection.js +42 -41
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +73 -45
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +16 -13
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +14 -14
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +23 -23
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +20 -20
- package/lib/db.js.map +1 -1
- package/lib/deps.js +1 -1
- package/lib/deps.js.map +1 -1
- package/lib/error.js +47 -24
- package/lib/error.js.map +1 -1
- package/lib/gridfs/index.js +3 -3
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +1 -1
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/logger.js +5 -5
- package/lib/logger.js.map +1 -1
- package/lib/mongo_client.js +7 -7
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/add_user.js +3 -3
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/aggregate.js +3 -4
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js +1 -1
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/command.js +7 -3
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/common_functions.js +1 -1
- package/lib/operations/common_functions.js.map +1 -1
- package/lib/operations/connect.js +1 -1
- package/lib/operations/connect.js.map +1 -1
- package/lib/operations/count.js +1 -1
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/create_collection.js +1 -1
- package/lib/operations/create_collection.js.map +1 -1
- package/lib/operations/delete.js +6 -6
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js +4 -4
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/drop.js +2 -2
- package/lib/operations/drop.js.map +1 -1
- package/lib/operations/estimated_document_count.js +2 -2
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/execute_operation.js +24 -7
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +8 -8
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +7 -7
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/get_more.js +28 -0
- package/lib/operations/get_more.js.map +1 -0
- package/lib/operations/indexes.js +14 -14
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +5 -5
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/list_collections.js +12 -7
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js +1 -1
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/map_reduce.js +6 -6
- package/lib/operations/map_reduce.js.map +1 -1
- package/lib/operations/operation.js +4 -2
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/remove_user.js +1 -1
- package/lib/operations/remove_user.js.map +1 -1
- package/lib/operations/rename.js +2 -2
- package/lib/operations/rename.js.map +1 -1
- package/lib/operations/set_profiling_level.js +1 -1
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/stats.js +2 -2
- package/lib/operations/stats.js.map +1 -1
- package/lib/operations/update.js +12 -12
- package/lib/operations/update.js.map +1 -1
- package/lib/read_preference.js +4 -1
- package/lib/read_preference.js.map +1 -1
- package/lib/sdam/monitor.js +14 -14
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +19 -12
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +3 -3
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +36 -1
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +9 -9
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +29 -21
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +34 -12
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +19 -19
- package/lib/sessions.js.map +1 -1
- package/lib/transactions.js.map +1 -1
- package/lib/utils.js +53 -46
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +60 -37
- package/mongodb.ts34.d.ts +61 -37
- package/package.json +26 -30
- package/src/bson.ts +1 -0
- package/src/bulk/common.ts +50 -37
- package/src/change_stream.ts +10 -8
- package/src/cmap/commands.ts +11 -8
- package/src/cmap/connection.ts +1 -0
- package/src/cmap/stream_description.ts +3 -3
- package/src/cmap/wire_protocol/constants.ts +4 -4
- package/src/collection.ts +40 -25
- package/src/connection_string.ts +75 -36
- package/src/cursor/abstract_cursor.ts +9 -11
- package/src/db.ts +5 -6
- package/src/error.ts +51 -23
- package/src/mongo_client.ts +12 -0
- package/src/mongo_types.ts +11 -14
- package/src/operations/aggregate.ts +1 -2
- package/src/operations/command.ts +5 -0
- package/src/operations/create_collection.ts +1 -1
- package/src/operations/execute_operation.ts +22 -2
- package/src/operations/get_more.ts +49 -0
- package/src/operations/list_collections.ts +12 -4
- package/src/operations/operation.ts +5 -1
- package/src/read_preference.ts +4 -1
- package/src/sdam/server.ts +8 -0
- package/src/sdam/server_selection.ts +43 -0
- package/src/sdam/srv_polling.ts +12 -11
- package/src/sdam/topology.ts +27 -10
- package/src/sdam/topology_description.ts +35 -11
- package/src/sessions.ts +2 -1
- package/src/transactions.ts +2 -2
- package/src/utils.ts +67 -56
package/src/connection_string.ts
CHANGED
|
@@ -75,7 +75,7 @@ export function resolveSRVRecord(options: MongoOptions, callback: Callback<HostA
|
|
|
75
75
|
|
|
76
76
|
// Resolve the SRV record and use the result as the list of hosts to connect to.
|
|
77
77
|
const lookupAddress = options.srvHost;
|
|
78
|
-
dns.resolveSrv(`
|
|
78
|
+
dns.resolveSrv(`_${options.srvServiceName}._tcp.${lookupAddress}`, (err, addresses) => {
|
|
79
79
|
if (err) return callback(err);
|
|
80
80
|
|
|
81
81
|
if (addresses.length === 0) {
|
|
@@ -92,7 +92,7 @@ export function resolveSRVRecord(options: MongoOptions, callback: Callback<HostA
|
|
|
92
92
|
HostAddress.fromString(`${r.name}:${r.port ?? 27017}`)
|
|
93
93
|
);
|
|
94
94
|
|
|
95
|
-
const lbError = validateLoadBalancedOptions(hostAddresses, options);
|
|
95
|
+
const lbError = validateLoadBalancedOptions(hostAddresses, options, true);
|
|
96
96
|
if (lbError) {
|
|
97
97
|
return callback(lbError);
|
|
98
98
|
}
|
|
@@ -116,14 +116,14 @@ export function resolveSRVRecord(options: MongoOptions, callback: Callback<HostA
|
|
|
116
116
|
);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
if (VALID_TXT_RECORDS.some(option => txtRecordOptions.get(option) === '')) {
|
|
120
|
+
return callback(new MongoParseError('Cannot have empty URI params in DNS TXT Record'));
|
|
121
|
+
}
|
|
122
|
+
|
|
119
123
|
const source = txtRecordOptions.get('authSource') ?? undefined;
|
|
120
124
|
const replicaSet = txtRecordOptions.get('replicaSet') ?? undefined;
|
|
121
125
|
const loadBalanced = txtRecordOptions.get('loadBalanced') ?? undefined;
|
|
122
126
|
|
|
123
|
-
if (source === '' || replicaSet === '') {
|
|
124
|
-
return callback(new MongoParseError('Cannot have empty URI params in DNS TXT Record'));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
127
|
if (!options.userSpecifiedAuthSource && source) {
|
|
128
128
|
options.credentials = MongoCredentials.merge(options.credentials, { source });
|
|
129
129
|
}
|
|
@@ -136,7 +136,11 @@ export function resolveSRVRecord(options: MongoOptions, callback: Callback<HostA
|
|
|
136
136
|
options.loadBalanced = true;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
if (options.replicaSet && options.srvMaxHosts > 0) {
|
|
140
|
+
return callback(new MongoParseError('Cannot combine replicaSet option with srvMaxHosts'));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const lbError = validateLoadBalancedOptions(hostAddresses, options, true);
|
|
140
144
|
if (lbError) {
|
|
141
145
|
return callback(lbError);
|
|
142
146
|
}
|
|
@@ -251,13 +255,6 @@ export function parseOptions(
|
|
|
251
255
|
|
|
252
256
|
const mongoOptions = Object.create(null);
|
|
253
257
|
mongoOptions.hosts = isSRV ? [] : hosts.map(HostAddress.fromString);
|
|
254
|
-
if (isSRV) {
|
|
255
|
-
// SRV Record is resolved upon connecting
|
|
256
|
-
mongoOptions.srvHost = hosts[0];
|
|
257
|
-
if (!url.searchParams.has('tls') && !url.searchParams.has('ssl')) {
|
|
258
|
-
options.tls = true;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
258
|
|
|
262
259
|
const urlOptions = new CaseInsensitiveMap();
|
|
263
260
|
|
|
@@ -289,17 +286,6 @@ export function parseOptions(
|
|
|
289
286
|
throw new MongoAPIError('URI cannot contain options with no value');
|
|
290
287
|
}
|
|
291
288
|
|
|
292
|
-
if (key.toLowerCase() === 'serverapi') {
|
|
293
|
-
throw new MongoParseError(
|
|
294
|
-
'URI cannot contain `serverApi`, it can only be passed to the client'
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (key.toLowerCase() === 'authsource' && urlOptions.has('authSource')) {
|
|
299
|
-
// If authSource is an explicit key in the urlOptions we need to remove the implicit dbName
|
|
300
|
-
urlOptions.delete('authSource');
|
|
301
|
-
}
|
|
302
|
-
|
|
303
289
|
if (!urlOptions.has(key)) {
|
|
304
290
|
urlOptions.set(key, values);
|
|
305
291
|
}
|
|
@@ -309,10 +295,20 @@ export function parseOptions(
|
|
|
309
295
|
Object.entries(options).filter(([, v]) => v != null)
|
|
310
296
|
);
|
|
311
297
|
|
|
298
|
+
// Validate options that can only be provided by one of uri or object
|
|
299
|
+
|
|
300
|
+
if (urlOptions.has('serverApi')) {
|
|
301
|
+
throw new MongoParseError(
|
|
302
|
+
'URI cannot contain `serverApi`, it can only be passed to the client'
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
312
306
|
if (objectOptions.has('loadBalanced')) {
|
|
313
307
|
throw new MongoParseError('loadBalanced is only a valid option in the URI');
|
|
314
308
|
}
|
|
315
309
|
|
|
310
|
+
// All option collection
|
|
311
|
+
|
|
316
312
|
const allOptions = new CaseInsensitiveMap();
|
|
317
313
|
|
|
318
314
|
const allKeys = new Set<string>([
|
|
@@ -360,6 +356,8 @@ export function parseOptions(
|
|
|
360
356
|
);
|
|
361
357
|
}
|
|
362
358
|
|
|
359
|
+
// Option parsing and setting
|
|
360
|
+
|
|
363
361
|
for (const [key, descriptor] of Object.entries(OPTIONS)) {
|
|
364
362
|
const values = allOptions.get(key);
|
|
365
363
|
if (!values || values.length === 0) continue;
|
|
@@ -401,25 +399,53 @@ export function parseOptions(
|
|
|
401
399
|
|
|
402
400
|
if (options.promiseLibrary) PromiseProvider.set(options.promiseLibrary);
|
|
403
401
|
|
|
404
|
-
|
|
405
|
-
throw new MongoAPIError('SRV URI does not support directConnection');
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
const lbError = validateLoadBalancedOptions(hosts, mongoOptions);
|
|
402
|
+
const lbError = validateLoadBalancedOptions(hosts, mongoOptions, isSRV);
|
|
409
403
|
if (lbError) {
|
|
410
404
|
throw lbError;
|
|
411
405
|
}
|
|
406
|
+
if (mongoClient && mongoOptions.autoEncryption) {
|
|
407
|
+
Encrypter.checkForMongoCrypt();
|
|
408
|
+
mongoOptions.encrypter = new Encrypter(mongoClient, uri, options);
|
|
409
|
+
mongoOptions.autoEncrypter = mongoOptions.encrypter.autoEncrypter;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Potential SRV Overrides and SRV connection string validations
|
|
412
413
|
|
|
413
|
-
// Potential SRV Overrides
|
|
414
414
|
mongoOptions.userSpecifiedAuthSource =
|
|
415
415
|
objectOptions.has('authSource') || urlOptions.has('authSource');
|
|
416
416
|
mongoOptions.userSpecifiedReplicaSet =
|
|
417
417
|
objectOptions.has('replicaSet') || urlOptions.has('replicaSet');
|
|
418
418
|
|
|
419
|
-
if (
|
|
420
|
-
|
|
421
|
-
mongoOptions.
|
|
422
|
-
|
|
419
|
+
if (isSRV) {
|
|
420
|
+
// SRV Record is resolved upon connecting
|
|
421
|
+
mongoOptions.srvHost = hosts[0];
|
|
422
|
+
|
|
423
|
+
if (mongoOptions.directConnection) {
|
|
424
|
+
throw new MongoAPIError('SRV URI does not support directConnection');
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (mongoOptions.srvMaxHosts > 0 && typeof mongoOptions.replicaSet === 'string') {
|
|
428
|
+
throw new MongoParseError('Cannot use srvMaxHosts option with replicaSet');
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// SRV turns on TLS by default, but users can override and turn it off
|
|
432
|
+
const noUserSpecifiedTLS = !objectOptions.has('tls') && !urlOptions.has('tls');
|
|
433
|
+
const noUserSpecifiedSSL = !objectOptions.has('ssl') && !urlOptions.has('ssl');
|
|
434
|
+
if (noUserSpecifiedTLS && noUserSpecifiedSSL) {
|
|
435
|
+
mongoOptions.tls = true;
|
|
436
|
+
}
|
|
437
|
+
} else {
|
|
438
|
+
const userSpecifiedSrvOptions =
|
|
439
|
+
urlOptions.has('srvMaxHosts') ||
|
|
440
|
+
objectOptions.has('srvMaxHosts') ||
|
|
441
|
+
urlOptions.has('srvServiceName') ||
|
|
442
|
+
objectOptions.has('srvServiceName');
|
|
443
|
+
|
|
444
|
+
if (userSpecifiedSrvOptions) {
|
|
445
|
+
throw new MongoParseError(
|
|
446
|
+
'Cannot use srvMaxHosts or srvServiceName with a non-srv connection string'
|
|
447
|
+
);
|
|
448
|
+
}
|
|
423
449
|
}
|
|
424
450
|
|
|
425
451
|
return mongoOptions;
|
|
@@ -427,7 +453,8 @@ export function parseOptions(
|
|
|
427
453
|
|
|
428
454
|
function validateLoadBalancedOptions(
|
|
429
455
|
hosts: HostAddress[] | string[],
|
|
430
|
-
mongoOptions: MongoOptions
|
|
456
|
+
mongoOptions: MongoOptions,
|
|
457
|
+
isSrv: boolean
|
|
431
458
|
): MongoParseError | undefined {
|
|
432
459
|
if (mongoOptions.loadBalanced) {
|
|
433
460
|
if (hosts.length > 1) {
|
|
@@ -439,6 +466,10 @@ function validateLoadBalancedOptions(
|
|
|
439
466
|
if (mongoOptions.directConnection) {
|
|
440
467
|
return new MongoParseError(LB_DIRECT_CONNECTION_ERROR);
|
|
441
468
|
}
|
|
469
|
+
|
|
470
|
+
if (isSrv && mongoOptions.srvMaxHosts > 0) {
|
|
471
|
+
return new MongoParseError('Cannot limit srv hosts with loadBalanced enabled');
|
|
472
|
+
}
|
|
442
473
|
}
|
|
443
474
|
}
|
|
444
475
|
|
|
@@ -924,6 +955,14 @@ export const OPTIONS = {
|
|
|
924
955
|
default: 0,
|
|
925
956
|
type: 'uint'
|
|
926
957
|
},
|
|
958
|
+
srvMaxHosts: {
|
|
959
|
+
type: 'uint',
|
|
960
|
+
default: 0
|
|
961
|
+
},
|
|
962
|
+
srvServiceName: {
|
|
963
|
+
type: 'string',
|
|
964
|
+
default: 'mongodb'
|
|
965
|
+
},
|
|
927
966
|
ssl: {
|
|
928
967
|
target: 'tls',
|
|
929
968
|
type: 'boolean'
|
|
@@ -14,7 +14,8 @@ import { ReadPreference, ReadPreferenceLike } from '../read_preference';
|
|
|
14
14
|
import type { Server } from '../sdam/server';
|
|
15
15
|
import type { Topology } from '../sdam/topology';
|
|
16
16
|
import { Readable, Transform } from 'stream';
|
|
17
|
-
import
|
|
17
|
+
import { executeOperation, ExecutionResult } from '../operations/execute_operation';
|
|
18
|
+
import { GetMoreOperation } from '../operations/get_more';
|
|
18
19
|
import { ReadConcern, ReadConcernLike } from '../read_concern';
|
|
19
20
|
import { TODO_NODE_3286, TypedEventEmitter } from '../mongo_types';
|
|
20
21
|
|
|
@@ -610,16 +611,13 @@ export abstract class AbstractCursor<
|
|
|
610
611
|
return;
|
|
611
612
|
}
|
|
612
613
|
|
|
613
|
-
server
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
},
|
|
621
|
-
callback
|
|
622
|
-
);
|
|
614
|
+
const getMoreOperation = new GetMoreOperation(cursorNs, cursorId, server, {
|
|
615
|
+
...this[kOptions],
|
|
616
|
+
session: this[kSession],
|
|
617
|
+
batchSize
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
executeOperation(this.topology, getMoreOperation, callback);
|
|
623
621
|
}
|
|
624
622
|
}
|
|
625
623
|
|
package/src/db.ts
CHANGED
|
@@ -226,18 +226,17 @@ export class Db {
|
|
|
226
226
|
* @param options - Optional settings for the command
|
|
227
227
|
* @param callback - An optional callback, a Promise will be returned if none is provided
|
|
228
228
|
*/
|
|
229
|
-
createCollection<TSchema extends Document = Document>(name: string): Promise<Collection<TSchema>>;
|
|
230
229
|
createCollection<TSchema extends Document = Document>(
|
|
231
230
|
name: string,
|
|
232
|
-
|
|
233
|
-
):
|
|
231
|
+
options?: CreateCollectionOptions
|
|
232
|
+
): Promise<Collection<TSchema>>;
|
|
234
233
|
createCollection<TSchema extends Document = Document>(
|
|
235
234
|
name: string,
|
|
236
|
-
|
|
237
|
-
):
|
|
235
|
+
callback: Callback<Collection<TSchema>>
|
|
236
|
+
): void;
|
|
238
237
|
createCollection<TSchema extends Document = Document>(
|
|
239
238
|
name: string,
|
|
240
|
-
options: CreateCollectionOptions,
|
|
239
|
+
options: CreateCollectionOptions | undefined,
|
|
241
240
|
callback: Callback<Collection<TSchema>>
|
|
242
241
|
): void;
|
|
243
242
|
createCollection<TSchema extends Document = Document>(
|
package/src/error.ts
CHANGED
|
@@ -8,6 +8,27 @@ export type AnyError = MongoError | Error;
|
|
|
8
8
|
/** @internal */
|
|
9
9
|
const kErrorLabels = Symbol('errorLabels');
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @internal
|
|
13
|
+
* The legacy error message from the server that indicates the node is not a writable primary
|
|
14
|
+
* https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
|
|
15
|
+
*/
|
|
16
|
+
export const LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE = 'not master';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @internal
|
|
20
|
+
* The legacy error message from the server that indicates the node is not a primary or secondary
|
|
21
|
+
* https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
|
|
22
|
+
*/
|
|
23
|
+
export const LEGACY_NOT_PRIMARY_OR_SECONDARY_ERROR_MESSAGE = 'not master or secondary';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
* The error message from the server that indicates the node is recovering
|
|
28
|
+
* https://github.com/mongodb/specifications/blob/b07c26dc40d04ac20349f989db531c9845fdd755/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-writable-primary-and-node-is-recovering
|
|
29
|
+
*/
|
|
30
|
+
export const NODE_IS_RECOVERING_ERROR_MESSAGE = 'node is recovering';
|
|
31
|
+
|
|
11
32
|
/** @internal MongoDB Error Codes */
|
|
12
33
|
export const MONGODB_ERROR_CODES = Object.freeze({
|
|
13
34
|
HostUnreachable: 6,
|
|
@@ -17,11 +38,11 @@ export const MONGODB_ERROR_CODES = Object.freeze({
|
|
|
17
38
|
PrimarySteppedDown: 189,
|
|
18
39
|
ExceededTimeLimit: 262,
|
|
19
40
|
SocketException: 9001,
|
|
20
|
-
|
|
41
|
+
NotWritablePrimary: 10107,
|
|
21
42
|
InterruptedAtShutdown: 11600,
|
|
22
43
|
InterruptedDueToReplStateChange: 11602,
|
|
23
|
-
|
|
24
|
-
|
|
44
|
+
NotPrimaryNoSecondaryOk: 13435,
|
|
45
|
+
NotPrimaryOrSecondary: 13436,
|
|
25
46
|
StaleShardVersion: 63,
|
|
26
47
|
StaleEpoch: 150,
|
|
27
48
|
StaleConfig: 13388,
|
|
@@ -46,11 +67,11 @@ export const GET_MORE_RESUMABLE_CODES = new Set<number>([
|
|
|
46
67
|
MONGODB_ERROR_CODES.PrimarySteppedDown,
|
|
47
68
|
MONGODB_ERROR_CODES.ExceededTimeLimit,
|
|
48
69
|
MONGODB_ERROR_CODES.SocketException,
|
|
49
|
-
MONGODB_ERROR_CODES.
|
|
70
|
+
MONGODB_ERROR_CODES.NotWritablePrimary,
|
|
50
71
|
MONGODB_ERROR_CODES.InterruptedAtShutdown,
|
|
51
72
|
MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
|
|
52
|
-
MONGODB_ERROR_CODES.
|
|
53
|
-
MONGODB_ERROR_CODES.
|
|
73
|
+
MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
|
|
74
|
+
MONGODB_ERROR_CODES.NotPrimaryOrSecondary,
|
|
54
75
|
MONGODB_ERROR_CODES.StaleShardVersion,
|
|
55
76
|
MONGODB_ERROR_CODES.StaleEpoch,
|
|
56
77
|
MONGODB_ERROR_CODES.StaleConfig,
|
|
@@ -675,19 +696,19 @@ const RETRYABLE_ERROR_CODES = new Set<number>([
|
|
|
675
696
|
MONGODB_ERROR_CODES.ShutdownInProgress,
|
|
676
697
|
MONGODB_ERROR_CODES.PrimarySteppedDown,
|
|
677
698
|
MONGODB_ERROR_CODES.SocketException,
|
|
678
|
-
MONGODB_ERROR_CODES.
|
|
699
|
+
MONGODB_ERROR_CODES.NotWritablePrimary,
|
|
679
700
|
MONGODB_ERROR_CODES.InterruptedAtShutdown,
|
|
680
701
|
MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
|
|
681
|
-
MONGODB_ERROR_CODES.
|
|
682
|
-
MONGODB_ERROR_CODES.
|
|
702
|
+
MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
|
|
703
|
+
MONGODB_ERROR_CODES.NotPrimaryOrSecondary
|
|
683
704
|
]);
|
|
684
705
|
|
|
685
706
|
const RETRYABLE_WRITE_ERROR_CODES = new Set<number>([
|
|
686
707
|
MONGODB_ERROR_CODES.InterruptedAtShutdown,
|
|
687
708
|
MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
|
|
688
|
-
MONGODB_ERROR_CODES.
|
|
689
|
-
MONGODB_ERROR_CODES.
|
|
690
|
-
MONGODB_ERROR_CODES.
|
|
709
|
+
MONGODB_ERROR_CODES.NotWritablePrimary,
|
|
710
|
+
MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
|
|
711
|
+
MONGODB_ERROR_CODES.NotPrimaryOrSecondary,
|
|
691
712
|
MONGODB_ERROR_CODES.PrimarySteppedDown,
|
|
692
713
|
MONGODB_ERROR_CODES.ShutdownInProgress,
|
|
693
714
|
MONGODB_ERROR_CODES.HostNotFound,
|
|
@@ -697,6 +718,10 @@ const RETRYABLE_WRITE_ERROR_CODES = new Set<number>([
|
|
|
697
718
|
MONGODB_ERROR_CODES.ExceededTimeLimit
|
|
698
719
|
]);
|
|
699
720
|
|
|
721
|
+
export function isRetryableEndTransactionError(error: MongoError): boolean {
|
|
722
|
+
return error.hasErrorLabel('RetryableWriteError');
|
|
723
|
+
}
|
|
724
|
+
|
|
700
725
|
export function isRetryableWriteError(error: MongoError): boolean {
|
|
701
726
|
if (error instanceof MongoWriteConcernError) {
|
|
702
727
|
return RETRYABLE_WRITE_ERROR_CODES.has(error.result?.code ?? error.code ?? 0);
|
|
@@ -710,8 +735,8 @@ export function isRetryableError(error: MongoError): boolean {
|
|
|
710
735
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
711
736
|
(typeof error.code === 'number' && RETRYABLE_ERROR_CODES.has(error.code!)) ||
|
|
712
737
|
error instanceof MongoNetworkError ||
|
|
713
|
-
!!error.message.match(
|
|
714
|
-
!!error.message.match(
|
|
738
|
+
!!error.message.match(new RegExp(LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE)) ||
|
|
739
|
+
!!error.message.match(new RegExp(NODE_IS_RECOVERING_ERROR_MESSAGE))
|
|
715
740
|
);
|
|
716
741
|
}
|
|
717
742
|
|
|
@@ -720,12 +745,12 @@ const SDAM_RECOVERING_CODES = new Set<number>([
|
|
|
720
745
|
MONGODB_ERROR_CODES.PrimarySteppedDown,
|
|
721
746
|
MONGODB_ERROR_CODES.InterruptedAtShutdown,
|
|
722
747
|
MONGODB_ERROR_CODES.InterruptedDueToReplStateChange,
|
|
723
|
-
MONGODB_ERROR_CODES.
|
|
748
|
+
MONGODB_ERROR_CODES.NotPrimaryOrSecondary
|
|
724
749
|
]);
|
|
725
750
|
|
|
726
|
-
const
|
|
727
|
-
MONGODB_ERROR_CODES.
|
|
728
|
-
MONGODB_ERROR_CODES.
|
|
751
|
+
const SDAM_NOTPRIMARY_CODES = new Set<number>([
|
|
752
|
+
MONGODB_ERROR_CODES.NotWritablePrimary,
|
|
753
|
+
MONGODB_ERROR_CODES.NotPrimaryNoSecondaryOk,
|
|
729
754
|
MONGODB_ERROR_CODES.LegacyNotPrimary
|
|
730
755
|
]);
|
|
731
756
|
|
|
@@ -740,20 +765,23 @@ function isRecoveringError(err: MongoError) {
|
|
|
740
765
|
return SDAM_RECOVERING_CODES.has(err.code);
|
|
741
766
|
}
|
|
742
767
|
|
|
743
|
-
return
|
|
768
|
+
return (
|
|
769
|
+
new RegExp(LEGACY_NOT_PRIMARY_OR_SECONDARY_ERROR_MESSAGE).test(err.message) ||
|
|
770
|
+
new RegExp(NODE_IS_RECOVERING_ERROR_MESSAGE).test(err.message)
|
|
771
|
+
);
|
|
744
772
|
}
|
|
745
773
|
|
|
746
|
-
function
|
|
774
|
+
function isNotWritablePrimaryError(err: MongoError) {
|
|
747
775
|
if (typeof err.code === 'number') {
|
|
748
776
|
// If any error code exists, we ignore the error.message
|
|
749
|
-
return
|
|
777
|
+
return SDAM_NOTPRIMARY_CODES.has(err.code);
|
|
750
778
|
}
|
|
751
779
|
|
|
752
780
|
if (isRecoveringError(err)) {
|
|
753
781
|
return false;
|
|
754
782
|
}
|
|
755
783
|
|
|
756
|
-
return
|
|
784
|
+
return new RegExp(LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE).test(err.message);
|
|
757
785
|
}
|
|
758
786
|
|
|
759
787
|
export function isNodeShuttingDownError(err: MongoError): boolean {
|
|
@@ -774,7 +802,7 @@ export function isSDAMUnrecoverableError(error: MongoError): boolean {
|
|
|
774
802
|
return true;
|
|
775
803
|
}
|
|
776
804
|
|
|
777
|
-
return isRecoveringError(error) ||
|
|
805
|
+
return isRecoveringError(error) || isNotWritablePrimaryError(error);
|
|
778
806
|
}
|
|
779
807
|
|
|
780
808
|
export function isNetworkTimeoutError(err: MongoError): err is MongoNetworkError {
|
package/src/mongo_client.ts
CHANGED
|
@@ -132,6 +132,16 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
|
|
|
132
132
|
compressors?: CompressorName[] | string;
|
|
133
133
|
/** An integer that specifies the compression level if using zlib for network compression. */
|
|
134
134
|
zlibCompressionLevel?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | undefined;
|
|
135
|
+
/** The maximum number of hosts to connect to when using an srv connection string, a setting of `0` means unlimited hosts */
|
|
136
|
+
srvMaxHosts?: number;
|
|
137
|
+
/**
|
|
138
|
+
* Modifies the srv URI to look like:
|
|
139
|
+
*
|
|
140
|
+
* `_{srvServiceName}._tcp.{hostname}.{domainname}`
|
|
141
|
+
*
|
|
142
|
+
* Querying this DNS URI is expected to respond with SRV records
|
|
143
|
+
*/
|
|
144
|
+
srvServiceName?: string;
|
|
135
145
|
/** The maximum number of connections in the connection pool. */
|
|
136
146
|
maxPoolSize?: number;
|
|
137
147
|
/** The minimum number of connections in the connection pool. */
|
|
@@ -643,6 +653,8 @@ export interface MongoOptions
|
|
|
643
653
|
| 'retryWrites'
|
|
644
654
|
| 'serverSelectionTimeoutMS'
|
|
645
655
|
| 'socketTimeoutMS'
|
|
656
|
+
| 'srvMaxHosts'
|
|
657
|
+
| 'srvServiceName'
|
|
646
658
|
| 'tlsAllowInvalidCertificates'
|
|
647
659
|
| 'tlsAllowInvalidHostnames'
|
|
648
660
|
| 'tlsInsecure'
|
package/src/mongo_types.ts
CHANGED
|
@@ -38,9 +38,11 @@ export type WithId<TSchema> = EnhancedOmit<TSchema, '_id'> & { _id: InferIdType<
|
|
|
38
38
|
* `TSchema['_id'] extends ObjectId` which translated to "Is the _id property ObjectId?"
|
|
39
39
|
* we instead ask "Does ObjectId look like (have the same shape) as the _id?"
|
|
40
40
|
*/
|
|
41
|
-
export type OptionalId<TSchema
|
|
42
|
-
?
|
|
43
|
-
|
|
41
|
+
export type OptionalId<TSchema> = TSchema extends { _id?: any }
|
|
42
|
+
? ObjectId extends TSchema['_id'] // a Schema with ObjectId _id type or "any" or "indexed type" provided
|
|
43
|
+
? EnhancedOmit<TSchema, '_id'> & { _id?: InferIdType<TSchema> } // a Schema provided but _id type is not ObjectId
|
|
44
|
+
: WithId<TSchema>
|
|
45
|
+
: EnhancedOmit<TSchema, '_id'> & { _id?: InferIdType<TSchema> }; // TODO(NODE-3285): Improve type readability
|
|
44
46
|
|
|
45
47
|
/** TypeScript Omit (Exclude to be specific) does not work for objects with an "any" indexed type, and breaks discriminated unions @public */
|
|
46
48
|
export type EnhancedOmit<TRecordOrUnion, KeyUnion> = string extends keyof TRecordOrUnion
|
|
@@ -54,9 +56,8 @@ export type WithoutId<TSchema> = Omit<TSchema, '_id'>;
|
|
|
54
56
|
|
|
55
57
|
/** A MongoDB filter can be some portion of the schema or a set of operators @public */
|
|
56
58
|
export type Filter<TSchema> = {
|
|
57
|
-
[P in keyof TSchema]?: Condition<TSchema[P]>;
|
|
58
|
-
} &
|
|
59
|
-
RootFilterOperators<TSchema>;
|
|
59
|
+
[P in keyof WithId<TSchema>]?: Condition<WithId<TSchema>[P]>;
|
|
60
|
+
} & RootFilterOperators<WithId<TSchema>>;
|
|
60
61
|
|
|
61
62
|
/** @public */
|
|
62
63
|
export type Condition<T> = AlternativeType<T> | FilterOperators<AlternativeType<T>>;
|
|
@@ -255,8 +256,7 @@ export type SetFields<TSchema> = ({
|
|
|
255
256
|
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any> | undefined>]?:
|
|
256
257
|
| OptionalId<Flatten<TSchema[key]>>
|
|
257
258
|
| AddToSetOperators<Array<OptionalId<Flatten<TSchema[key]>>>>;
|
|
258
|
-
} &
|
|
259
|
-
NotAcceptedFields<TSchema, ReadonlyArray<any> | undefined>) & {
|
|
259
|
+
} & NotAcceptedFields<TSchema, ReadonlyArray<any> | undefined>) & {
|
|
260
260
|
readonly [key: string]: AddToSetOperators<any> | any;
|
|
261
261
|
};
|
|
262
262
|
|
|
@@ -265,8 +265,7 @@ export type PushOperator<TSchema> = ({
|
|
|
265
265
|
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any>>]?:
|
|
266
266
|
| Flatten<TSchema[key]>
|
|
267
267
|
| ArrayOperator<Array<Flatten<TSchema[key]>>>;
|
|
268
|
-
} &
|
|
269
|
-
NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
|
|
268
|
+
} & NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
|
|
270
269
|
readonly [key: string]: ArrayOperator<any> | any;
|
|
271
270
|
};
|
|
272
271
|
|
|
@@ -275,16 +274,14 @@ export type PullOperator<TSchema> = ({
|
|
|
275
274
|
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any>>]?:
|
|
276
275
|
| Partial<Flatten<TSchema[key]>>
|
|
277
276
|
| FilterOperations<Flatten<TSchema[key]>>;
|
|
278
|
-
} &
|
|
279
|
-
NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
|
|
277
|
+
} & NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
|
|
280
278
|
readonly [key: string]: FilterOperators<any> | any;
|
|
281
279
|
};
|
|
282
280
|
|
|
283
281
|
/** @public */
|
|
284
282
|
export type PullAllOperator<TSchema> = ({
|
|
285
283
|
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any>>]?: TSchema[key];
|
|
286
|
-
} &
|
|
287
|
-
NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
|
|
284
|
+
} & NotAcceptedFields<TSchema, ReadonlyArray<any>>) & {
|
|
288
285
|
readonly [key: string]: ReadonlyArray<any>;
|
|
289
286
|
};
|
|
290
287
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { CommandOperation, CommandOperationOptions, CollationOptions } from './command';
|
|
2
|
-
import { ReadPreference } from '../read_preference';
|
|
3
2
|
import { MongoInvalidArgumentError } from '../error';
|
|
4
3
|
import { maxWireVersion, MongoDBNamespace } from '../utils';
|
|
5
4
|
import { Aspect, defineAspects, Hint } from './operation';
|
|
@@ -65,7 +64,7 @@ export class AggregateOperation<T = Document> extends CommandOperation<T> {
|
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
if (this.hasWriteStage) {
|
|
68
|
-
this.
|
|
67
|
+
this.trySecondaryWrite = true;
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
if (this.explain && this.writeConcern) {
|
|
@@ -10,6 +10,7 @@ import type { Server } from '../sdam/server';
|
|
|
10
10
|
import type { BSONSerializeOptions, Document } from '../bson';
|
|
11
11
|
import type { ReadConcernLike } from './../read_concern';
|
|
12
12
|
import { Explain, ExplainOptions } from '../explain';
|
|
13
|
+
import { MIN_SECONDARY_WRITE_WIRE_VERSION } from '../sdam/server_selection';
|
|
13
14
|
|
|
14
15
|
const SUPPORTS_WRITE_CONCERN_AND_COLLATION = 5;
|
|
15
16
|
|
|
@@ -126,6 +127,10 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
|
|
|
126
127
|
Object.assign(cmd, { readConcern: this.readConcern });
|
|
127
128
|
}
|
|
128
129
|
|
|
130
|
+
if (this.trySecondaryWrite && serverWireVersion < MIN_SECONDARY_WRITE_WIRE_VERSION) {
|
|
131
|
+
options.omitReadPreference = true;
|
|
132
|
+
}
|
|
133
|
+
|
|
129
134
|
if (options.collation && serverWireVersion < SUPPORTS_WRITE_CONCERN_AND_COLLATION) {
|
|
130
135
|
callback(
|
|
131
136
|
new MongoCompatibilityError(
|
|
@@ -37,7 +37,7 @@ const ILLEGAL_COMMAND_FIELDS = new Set([
|
|
|
37
37
|
export interface TimeSeriesCollectionOptions extends Document {
|
|
38
38
|
timeField: string;
|
|
39
39
|
metaField?: string;
|
|
40
|
-
granularity?: string;
|
|
40
|
+
granularity?: 'seconds' | 'minutes' | 'hours' | string;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/** @public */
|
|
@@ -17,6 +17,11 @@ import type { Topology } from '../sdam/topology';
|
|
|
17
17
|
import type { ClientSession } from '../sessions';
|
|
18
18
|
import type { Document } from '../bson';
|
|
19
19
|
import { supportsRetryableWrites } from '../utils';
|
|
20
|
+
import {
|
|
21
|
+
sameServerSelector,
|
|
22
|
+
secondaryWritableServerSelector,
|
|
23
|
+
ServerSelector
|
|
24
|
+
} from '../sdam/server_selection';
|
|
20
25
|
|
|
21
26
|
const MMAPv1_RETRY_WRITES_ERROR_CODE = MONGODB_ERROR_CODES.IllegalOperation;
|
|
22
27
|
const MMAPv1_RETRY_WRITES_ERROR_MESSAGE =
|
|
@@ -150,6 +155,21 @@ function executeWithServerSelection(
|
|
|
150
155
|
session.unpin();
|
|
151
156
|
}
|
|
152
157
|
|
|
158
|
+
let selector: ReadPreference | ServerSelector;
|
|
159
|
+
|
|
160
|
+
if (operation.hasAspect(Aspect.CURSOR_ITERATING)) {
|
|
161
|
+
// Get more operations must always select the same server, but run through
|
|
162
|
+
// server selection to potentially force monitor checks if the server is
|
|
163
|
+
// in an unknown state.
|
|
164
|
+
selector = sameServerSelector(operation.server?.description);
|
|
165
|
+
} else if (operation.trySecondaryWrite) {
|
|
166
|
+
// If operation should try to write to secondary use the custom server selector
|
|
167
|
+
// otherwise provide the read preference.
|
|
168
|
+
selector = secondaryWritableServerSelector(topology.commonWireVersion, readPreference);
|
|
169
|
+
} else {
|
|
170
|
+
selector = readPreference;
|
|
171
|
+
}
|
|
172
|
+
|
|
153
173
|
const serverSelectionOptions = { session };
|
|
154
174
|
function callbackWithRetry(err?: any, result?: any) {
|
|
155
175
|
if (err == null) {
|
|
@@ -182,7 +202,7 @@ function executeWithServerSelection(
|
|
|
182
202
|
}
|
|
183
203
|
|
|
184
204
|
// select a new server, and attempt to retry the operation
|
|
185
|
-
topology.selectServer(
|
|
205
|
+
topology.selectServer(selector, serverSelectionOptions, (e?: any, server?: any) => {
|
|
186
206
|
if (
|
|
187
207
|
e ||
|
|
188
208
|
(operation.hasAspect(Aspect.READ_OPERATION) && !supportsRetryableReads(server)) ||
|
|
@@ -227,7 +247,7 @@ function executeWithServerSelection(
|
|
|
227
247
|
}
|
|
228
248
|
|
|
229
249
|
// select a server, and execute the operation against it
|
|
230
|
-
topology.selectServer(
|
|
250
|
+
topology.selectServer(selector, serverSelectionOptions, (err?: any, server?: any) => {
|
|
231
251
|
if (err) {
|
|
232
252
|
callback(err);
|
|
233
253
|
return;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Document, Long } from '../bson';
|
|
2
|
+
import { MongoRuntimeError } from '../error';
|
|
3
|
+
import type { Callback, MongoDBNamespace } from '../utils';
|
|
4
|
+
import type { Server } from '../sdam/server';
|
|
5
|
+
import { Aspect, AbstractOperation, OperationOptions, defineAspects } from './operation';
|
|
6
|
+
import type { ClientSession } from '../sessions';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
12
|
+
export interface GetMoreOptions extends OperationOptions {
|
|
13
|
+
/** Set the batchSize for the getMoreCommand when iterating over the query results. */
|
|
14
|
+
batchSize?: number;
|
|
15
|
+
/** You can put a $comment field on a query to make looking in the profiler logs simpler. */
|
|
16
|
+
comment?: string | Document;
|
|
17
|
+
/** Number of milliseconds to wait before aborting the query. */
|
|
18
|
+
maxTimeMS?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** @internal */
|
|
22
|
+
export class GetMoreOperation extends AbstractOperation {
|
|
23
|
+
cursorId: Long;
|
|
24
|
+
options: GetMoreOptions;
|
|
25
|
+
server: Server;
|
|
26
|
+
|
|
27
|
+
constructor(ns: MongoDBNamespace, cursorId: Long, server: Server, options: GetMoreOptions = {}) {
|
|
28
|
+
super(options);
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.ns = ns;
|
|
31
|
+
this.cursorId = cursorId;
|
|
32
|
+
this.server = server;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Although there is a server already associated with the get more operation, the signature
|
|
37
|
+
* for execute passes a server so we will just use that one.
|
|
38
|
+
*/
|
|
39
|
+
execute(server: Server, session: ClientSession, callback: Callback<Document>): void {
|
|
40
|
+
if (server !== this.server) {
|
|
41
|
+
return callback(
|
|
42
|
+
new MongoRuntimeError('Getmore must run on the same server operation began on')
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
server.getMore(this.ns, this.cursorId, this.options, callback);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
defineAspects(GetMoreOperation, [Aspect.READ_OPERATION, Aspect.CURSOR_ITERATING]);
|