mongodb 4.4.1 → 4.5.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 +3 -2
- package/lib/admin.js +5 -6
- package/lib/admin.js.map +1 -1
- package/lib/bulk/common.js +31 -7
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +29 -20
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/scram.js +1 -0
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +111 -86
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/errors.js.map +1 -1
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/stream_description.js +3 -0
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/collection.js +28 -28
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +3 -0
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +64 -51
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +2 -2
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +3 -3
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +13 -13
- package/lib/db.js.map +1 -1
- package/lib/encrypter.js +17 -9
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +97 -48
- package/lib/error.js.map +1 -1
- package/lib/gridfs/download.js +2 -0
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +42 -51
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +6 -3
- package/lib/index.js.map +1 -1
- package/lib/mongo_client.js +14 -27
- package/lib/mongo_client.js.map +1 -1
- package/lib/operations/add_user.js +8 -1
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/aggregate.js +5 -0
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/collections.js.map +1 -1
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/common_functions.js +8 -1
- package/lib/operations/common_functions.js.map +1 -1
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/count_documents.js.map +1 -1
- package/lib/operations/create_collection.js.map +1 -1
- package/lib/operations/delete.js +5 -3
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/drop.js.map +1 -1
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/eval.js.map +1 -1
- package/lib/operations/execute_operation.js +70 -79
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +3 -1
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +5 -0
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/get_more.js +5 -0
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js +8 -9
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +3 -1
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/list_collections.js +10 -42
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js +5 -0
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/map_reduce.js +1 -2
- package/lib/operations/map_reduce.js.map +1 -1
- package/lib/operations/operation.js +1 -3
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/remove_user.js.map +1 -1
- package/lib/operations/rename.js +1 -1
- package/lib/operations/rename.js.map +1 -1
- package/lib/operations/run_command.js.map +1 -1
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/stats.js.map +1 -1
- package/lib/operations/update.js +5 -0
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/read_concern.js +1 -0
- package/lib/read_concern.js.map +1 -1
- package/lib/sdam/common.js +1 -7
- package/lib/sdam/common.js.map +1 -1
- package/lib/sdam/events.js +1 -1
- package/lib/sdam/events.js.map +1 -1
- package/lib/sdam/monitor.js +1 -2
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +79 -57
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/topology.js +16 -33
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +1 -3
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +93 -68
- package/lib/sessions.js.map +1 -1
- package/lib/utils.js +21 -97
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +110 -26
- package/package.json +24 -28
- package/src/admin.ts +6 -10
- package/src/bulk/common.ts +42 -14
- package/src/bulk/unordered.ts +1 -1
- package/src/change_stream.ts +57 -41
- package/src/cmap/auth/gssapi.ts +1 -1
- package/src/cmap/auth/mongocr.ts +1 -1
- package/src/cmap/auth/mongodb_aws.ts +1 -1
- package/src/cmap/auth/plain.ts +1 -1
- package/src/cmap/auth/scram.ts +3 -2
- package/src/cmap/auth/x509.ts +6 -2
- package/src/cmap/commands.ts +3 -0
- package/src/cmap/connect.ts +2 -12
- package/src/cmap/connection.ts +162 -111
- package/src/cmap/errors.ts +2 -2
- package/src/cmap/message_stream.ts +2 -2
- package/src/cmap/stream_description.ts +4 -1
- package/src/collection.ts +31 -31
- package/src/connection_string.ts +7 -4
- package/src/cursor/abstract_cursor.ts +85 -63
- package/src/cursor/aggregation_cursor.ts +4 -4
- package/src/cursor/find_cursor.ts +7 -7
- package/src/db.ts +15 -19
- package/src/deps.ts +11 -0
- package/src/encrypter.ts +18 -10
- package/src/error.ts +143 -76
- package/src/gridfs/download.ts +3 -1
- package/src/gridfs/index.ts +51 -68
- package/src/gridfs/upload.ts +12 -12
- package/src/index.ts +7 -0
- package/src/mongo_client.ts +19 -41
- package/src/operations/add_user.ts +14 -3
- package/src/operations/aggregate.ts +15 -5
- package/src/operations/bulk_write.ts +6 -2
- package/src/operations/collections.ts +6 -2
- package/src/operations/command.ts +23 -8
- package/src/operations/common_functions.ts +8 -1
- package/src/operations/count.ts +6 -2
- package/src/operations/count_documents.ts +5 -1
- package/src/operations/create_collection.ts +6 -2
- package/src/operations/delete.ts +19 -13
- package/src/operations/distinct.ts +6 -2
- package/src/operations/drop.ts +12 -4
- package/src/operations/estimated_document_count.ts +11 -3
- package/src/operations/eval.ts +6 -2
- package/src/operations/execute_operation.ts +102 -101
- package/src/operations/find.ts +9 -5
- package/src/operations/find_and_modify.ts +21 -2
- package/src/operations/get_more.ts +20 -6
- package/src/operations/indexes.ts +54 -36
- package/src/operations/insert.ts +20 -6
- package/src/operations/is_capped.ts +6 -2
- package/src/operations/list_collections.ts +24 -59
- package/src/operations/list_databases.ts +13 -3
- package/src/operations/map_reduce.ts +7 -6
- package/src/operations/operation.ts +10 -9
- package/src/operations/options_operation.ts +6 -2
- package/src/operations/profiling_level.ts +6 -2
- package/src/operations/remove_user.ts +6 -2
- package/src/operations/rename.ts +7 -3
- package/src/operations/run_command.ts +6 -2
- package/src/operations/set_profiling_level.ts +6 -2
- package/src/operations/stats.ts +12 -4
- package/src/operations/update.ts +19 -9
- package/src/operations/validate_collection.ts +6 -2
- package/src/read_concern.ts +1 -0
- package/src/sdam/common.ts +0 -6
- package/src/sdam/events.ts +2 -2
- package/src/sdam/monitor.ts +4 -5
- package/src/sdam/server.ts +95 -90
- package/src/sdam/topology.ts +9 -53
- package/src/sdam/topology_description.ts +1 -3
- package/src/sessions.ts +108 -78
- package/src/utils.ts +38 -118
- package/tsconfig.json +40 -0
- package/mongodb.ts34.d.ts +0 -5720
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import type { Document } from '../bson';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
isRetryableReadError,
|
|
4
4
|
MongoCompatibilityError,
|
|
5
5
|
MONGODB_ERROR_CODES,
|
|
6
6
|
MongoError,
|
|
7
|
+
MongoErrorLabel,
|
|
7
8
|
MongoExpiredSessionError,
|
|
8
9
|
MongoNetworkError,
|
|
9
10
|
MongoRuntimeError,
|
|
10
11
|
MongoServerError,
|
|
11
|
-
MongoTransactionError
|
|
12
|
+
MongoTransactionError,
|
|
13
|
+
MongoUnexpectedServerResponseError
|
|
12
14
|
} from '../error';
|
|
13
15
|
import { ReadPreference } from '../read_preference';
|
|
14
16
|
import type { Server } from '../sdam/server';
|
|
@@ -19,7 +21,13 @@ import {
|
|
|
19
21
|
} from '../sdam/server_selection';
|
|
20
22
|
import type { Topology } from '../sdam/topology';
|
|
21
23
|
import type { ClientSession } from '../sessions';
|
|
22
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
Callback,
|
|
26
|
+
getTopology,
|
|
27
|
+
maybePromise,
|
|
28
|
+
supportsRetryableWrites,
|
|
29
|
+
TopologyProvider
|
|
30
|
+
} from '../utils';
|
|
23
31
|
import { AbstractOperation, Aspect } from './operation';
|
|
24
32
|
|
|
25
33
|
const MMAPv1_RETRY_WRITES_ERROR_CODE = MONGODB_ERROR_CODES.IllegalOperation;
|
|
@@ -58,99 +66,101 @@ export interface ExecutionResult {
|
|
|
58
66
|
export function executeOperation<
|
|
59
67
|
T extends AbstractOperation<TResult>,
|
|
60
68
|
TResult = ResultTypeFromOperation<T>
|
|
61
|
-
>(
|
|
69
|
+
>(topologyProvider: TopologyProvider, operation: T): Promise<TResult>;
|
|
62
70
|
export function executeOperation<
|
|
63
71
|
T extends AbstractOperation<TResult>,
|
|
64
72
|
TResult = ResultTypeFromOperation<T>
|
|
65
|
-
>(
|
|
73
|
+
>(topologyProvider: TopologyProvider, operation: T, callback: Callback<TResult>): void;
|
|
66
74
|
export function executeOperation<
|
|
67
75
|
T extends AbstractOperation<TResult>,
|
|
68
76
|
TResult = ResultTypeFromOperation<T>
|
|
69
|
-
>(
|
|
77
|
+
>(
|
|
78
|
+
topologyProvider: TopologyProvider,
|
|
79
|
+
operation: T,
|
|
80
|
+
callback?: Callback<TResult>
|
|
81
|
+
): Promise<TResult> | void;
|
|
70
82
|
export function executeOperation<
|
|
71
83
|
T extends AbstractOperation<TResult>,
|
|
72
84
|
TResult = ResultTypeFromOperation<T>
|
|
73
|
-
>(
|
|
85
|
+
>(
|
|
86
|
+
topologyProvider: TopologyProvider,
|
|
87
|
+
operation: T,
|
|
88
|
+
callback?: Callback<TResult>
|
|
89
|
+
): Promise<TResult> | void {
|
|
74
90
|
if (!(operation instanceof AbstractOperation)) {
|
|
75
|
-
// TODO(NODE-3483)
|
|
91
|
+
// TODO(NODE-3483): Extend MongoRuntimeError
|
|
76
92
|
throw new MongoRuntimeError('This method requires a valid operation instance');
|
|
77
93
|
}
|
|
78
94
|
|
|
79
|
-
return maybePromise(callback,
|
|
95
|
+
return maybePromise(callback, callback => {
|
|
96
|
+
let topology: Topology;
|
|
97
|
+
try {
|
|
98
|
+
topology = getTopology(topologyProvider);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
return callback(error);
|
|
101
|
+
}
|
|
80
102
|
if (topology.shouldCheckForSessionSupport()) {
|
|
81
|
-
return topology.selectServer(ReadPreference.primaryPreferred, err => {
|
|
82
|
-
if (err) return
|
|
103
|
+
return topology.selectServer(ReadPreference.primaryPreferred, {}, err => {
|
|
104
|
+
if (err) return callback(err);
|
|
83
105
|
|
|
84
|
-
executeOperation<T, TResult>(
|
|
106
|
+
executeOperation<T, TResult>(topologyProvider, operation, callback);
|
|
85
107
|
});
|
|
86
108
|
}
|
|
87
109
|
|
|
88
110
|
// The driver sessions spec mandates that we implicitly create sessions for operations
|
|
89
111
|
// that are not explicitly provided with a session.
|
|
90
|
-
let session
|
|
112
|
+
let session = operation.session;
|
|
91
113
|
let owner: symbol | undefined;
|
|
92
114
|
if (topology.hasSessionSupport()) {
|
|
93
115
|
if (session == null) {
|
|
94
116
|
owner = Symbol();
|
|
95
117
|
session = topology.startSession({ owner, explicit: false });
|
|
96
118
|
} else if (session.hasEnded) {
|
|
97
|
-
return
|
|
119
|
+
return callback(new MongoExpiredSessionError('Use of expired sessions is not permitted'));
|
|
98
120
|
} else if (session.snapshotEnabled && !topology.capabilities.supportsSnapshotReads) {
|
|
99
|
-
return
|
|
121
|
+
return callback(new MongoCompatibilityError('Snapshot reads require MongoDB 5.0 or later'));
|
|
100
122
|
}
|
|
101
123
|
} else if (session) {
|
|
102
124
|
// If the user passed an explicit session and we are still, after server selection,
|
|
103
125
|
// trying to run against a topology that doesn't support sessions we error out.
|
|
104
|
-
return
|
|
126
|
+
return callback(new MongoCompatibilityError('Current topology does not support sessions'));
|
|
105
127
|
}
|
|
106
128
|
|
|
107
129
|
try {
|
|
108
|
-
executeWithServerSelection(topology, session, operation, (
|
|
109
|
-
if (session
|
|
110
|
-
return session.endSession(
|
|
130
|
+
executeWithServerSelection<TResult>(topology, session, operation, (error, result) => {
|
|
131
|
+
if (session?.owner != null && session.owner === owner) {
|
|
132
|
+
return session.endSession(endSessionError => callback(endSessionError ?? error, result));
|
|
111
133
|
}
|
|
112
134
|
|
|
113
|
-
|
|
135
|
+
callback(error, result);
|
|
114
136
|
});
|
|
115
|
-
} catch (
|
|
116
|
-
if (session
|
|
137
|
+
} catch (error) {
|
|
138
|
+
if (session?.owner != null && session.owner === owner) {
|
|
117
139
|
session.endSession();
|
|
118
140
|
}
|
|
119
|
-
|
|
120
|
-
throw e;
|
|
141
|
+
throw error;
|
|
121
142
|
}
|
|
122
143
|
});
|
|
123
144
|
}
|
|
124
145
|
|
|
125
|
-
function
|
|
126
|
-
return maxWireVersion(server) >= 6;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function executeWithServerSelection(
|
|
146
|
+
function executeWithServerSelection<TResult>(
|
|
130
147
|
topology: Topology,
|
|
131
|
-
session: ClientSession,
|
|
148
|
+
session: ClientSession | undefined,
|
|
132
149
|
operation: AbstractOperation,
|
|
133
|
-
callback: Callback
|
|
150
|
+
callback: Callback<TResult>
|
|
134
151
|
) {
|
|
135
|
-
const readPreference = operation.readPreference
|
|
136
|
-
const inTransaction = session
|
|
152
|
+
const readPreference = operation.readPreference ?? ReadPreference.primary;
|
|
153
|
+
const inTransaction = !!session?.inTransaction();
|
|
137
154
|
|
|
138
155
|
if (inTransaction && !readPreference.equals(ReadPreference.primary)) {
|
|
139
|
-
callback(
|
|
156
|
+
return callback(
|
|
140
157
|
new MongoTransactionError(
|
|
141
158
|
`Read preference in a transaction must be primary, not: ${readPreference.mode}`
|
|
142
159
|
)
|
|
143
160
|
);
|
|
144
|
-
|
|
145
|
-
return;
|
|
146
161
|
}
|
|
147
162
|
|
|
148
|
-
if (
|
|
149
|
-
session &&
|
|
150
|
-
session.isPinned &&
|
|
151
|
-
session.transaction.isCommitted &&
|
|
152
|
-
!operation.bypassPinningCheck
|
|
153
|
-
) {
|
|
163
|
+
if (session?.isPinned && session.transaction.isCommitted && !operation.bypassPinningCheck) {
|
|
154
164
|
session.unpin();
|
|
155
165
|
}
|
|
156
166
|
|
|
@@ -170,60 +180,54 @@ function executeWithServerSelection(
|
|
|
170
180
|
}
|
|
171
181
|
|
|
172
182
|
const serverSelectionOptions = { session };
|
|
173
|
-
function
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
183
|
+
function retryOperation(originalError: MongoError) {
|
|
184
|
+
const isWriteOperation = operation.hasAspect(Aspect.WRITE_OPERATION);
|
|
185
|
+
const isReadOperation = operation.hasAspect(Aspect.READ_OPERATION);
|
|
177
186
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const itShouldRetryWrite = shouldRetryWrite(err);
|
|
181
|
-
|
|
182
|
-
if ((hasReadAspect && !isRetryableError(err)) || (hasWriteAspect && !itShouldRetryWrite)) {
|
|
183
|
-
return callback(err);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (
|
|
187
|
-
hasWriteAspect &&
|
|
188
|
-
itShouldRetryWrite &&
|
|
189
|
-
err.code === MMAPv1_RETRY_WRITES_ERROR_CODE &&
|
|
190
|
-
err.errmsg.match(/Transaction numbers/)
|
|
191
|
-
) {
|
|
192
|
-
callback(
|
|
187
|
+
if (isWriteOperation && originalError.code === MMAPv1_RETRY_WRITES_ERROR_CODE) {
|
|
188
|
+
return callback(
|
|
193
189
|
new MongoServerError({
|
|
194
190
|
message: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
|
|
195
191
|
errmsg: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
|
|
196
|
-
originalError
|
|
192
|
+
originalError
|
|
197
193
|
})
|
|
198
194
|
);
|
|
195
|
+
}
|
|
199
196
|
|
|
200
|
-
|
|
197
|
+
if (isWriteOperation && !originalError.hasErrorLabel(MongoErrorLabel.RetryableWriteError)) {
|
|
198
|
+
return callback(originalError);
|
|
201
199
|
}
|
|
202
200
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
e ||
|
|
207
|
-
(operation.hasAspect(Aspect.READ_OPERATION) && !supportsRetryableReads(server)) ||
|
|
208
|
-
(operation.hasAspect(Aspect.WRITE_OPERATION) && !supportsRetryableWrites(server))
|
|
209
|
-
) {
|
|
210
|
-
callback(e);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
201
|
+
if (isReadOperation && !isRetryableReadError(originalError)) {
|
|
202
|
+
return callback(originalError);
|
|
203
|
+
}
|
|
213
204
|
|
|
205
|
+
if (
|
|
206
|
+
originalError instanceof MongoNetworkError &&
|
|
207
|
+
session?.isPinned &&
|
|
208
|
+
!session.inTransaction() &&
|
|
209
|
+
operation.hasAspect(Aspect.CURSOR_CREATING)
|
|
210
|
+
) {
|
|
214
211
|
// If we have a cursor and the initial command fails with a network error,
|
|
215
212
|
// we can retry it on another connection. So we need to check it back in, clear the
|
|
216
213
|
// pool for the service id, and retry again.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
214
|
+
session.unpin({ force: true, forceClear: true });
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// select a new server, and attempt to retry the operation
|
|
218
|
+
topology.selectServer(selector, serverSelectionOptions, (error?: Error, server?: Server) => {
|
|
219
|
+
if (!error && isWriteOperation && !supportsRetryableWrites(server)) {
|
|
220
|
+
return callback(
|
|
221
|
+
new MongoUnexpectedServerResponseError(
|
|
222
|
+
'Selected server does not support retryable writes'
|
|
223
|
+
)
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (error || !server) {
|
|
228
|
+
return callback(
|
|
229
|
+
error ?? new MongoUnexpectedServerResponseError('Server selection failed without error')
|
|
230
|
+
);
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
operation.execute(server, session, callback);
|
|
@@ -233,8 +237,7 @@ function executeWithServerSelection(
|
|
|
233
237
|
if (
|
|
234
238
|
readPreference &&
|
|
235
239
|
!readPreference.equals(ReadPreference.primary) &&
|
|
236
|
-
session
|
|
237
|
-
session.inTransaction()
|
|
240
|
+
session?.inTransaction()
|
|
238
241
|
) {
|
|
239
242
|
callback(
|
|
240
243
|
new MongoTransactionError(
|
|
@@ -246,21 +249,17 @@ function executeWithServerSelection(
|
|
|
246
249
|
}
|
|
247
250
|
|
|
248
251
|
// select a server, and execute the operation against it
|
|
249
|
-
topology.selectServer(selector, serverSelectionOptions, (
|
|
250
|
-
if (
|
|
251
|
-
callback(
|
|
252
|
-
return;
|
|
252
|
+
topology.selectServer(selector, serverSelectionOptions, (error, server) => {
|
|
253
|
+
if (error || !server) {
|
|
254
|
+
return callback(error);
|
|
253
255
|
}
|
|
254
256
|
|
|
255
257
|
if (session && operation.hasAspect(Aspect.RETRYABLE)) {
|
|
256
258
|
const willRetryRead =
|
|
257
|
-
topology.s.options.retryReads
|
|
258
|
-
!inTransaction &&
|
|
259
|
-
supportsRetryableReads(server) &&
|
|
260
|
-
operation.canRetryRead;
|
|
259
|
+
topology.s.options.retryReads && !inTransaction && operation.canRetryRead;
|
|
261
260
|
|
|
262
261
|
const willRetryWrite =
|
|
263
|
-
topology.s.options.retryWrites
|
|
262
|
+
topology.s.options.retryWrites &&
|
|
264
263
|
!inTransaction &&
|
|
265
264
|
supportsRetryableWrites(server) &&
|
|
266
265
|
operation.canRetryWrite;
|
|
@@ -274,15 +273,17 @@ function executeWithServerSelection(
|
|
|
274
273
|
session.incrementTransactionNumber();
|
|
275
274
|
}
|
|
276
275
|
|
|
277
|
-
operation.execute(server, session,
|
|
278
|
-
|
|
276
|
+
return operation.execute(server, session, (error, result) => {
|
|
277
|
+
if (error instanceof MongoError) {
|
|
278
|
+
return retryOperation(error);
|
|
279
|
+
} else if (error) {
|
|
280
|
+
return callback(error);
|
|
281
|
+
}
|
|
282
|
+
callback(undefined, result);
|
|
283
|
+
});
|
|
279
284
|
}
|
|
280
285
|
}
|
|
281
286
|
|
|
282
|
-
operation.execute(server, session, callback);
|
|
287
|
+
return operation.execute(server, session, callback);
|
|
283
288
|
});
|
|
284
289
|
}
|
|
285
|
-
|
|
286
|
-
function shouldRetryWrite(err: any) {
|
|
287
|
-
return err instanceof MongoError && err.hasErrorLabel('RetryableWriteError');
|
|
288
|
-
}
|
package/src/operations/find.ts
CHANGED
|
@@ -46,8 +46,6 @@ export interface FindOptions<TSchema extends Document = Document> extends Comman
|
|
|
46
46
|
min?: Document;
|
|
47
47
|
/** The exclusive upper bound for a specific index */
|
|
48
48
|
max?: Document;
|
|
49
|
-
/** You can put a $comment field on a query to make looking in the profiler logs simpler. */
|
|
50
|
-
comment?: string | Document;
|
|
51
49
|
/** Number of milliseconds to wait before aborting the query. */
|
|
52
50
|
maxTimeMS?: number;
|
|
53
51
|
/** The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Requires `tailable` and `awaitData` to be true */
|
|
@@ -72,7 +70,7 @@ const SUPPORTS_WRITE_CONCERN_AND_COLLATION = 5;
|
|
|
72
70
|
|
|
73
71
|
/** @internal */
|
|
74
72
|
export class FindOperation extends CommandOperation<Document> {
|
|
75
|
-
options: FindOptions;
|
|
73
|
+
override options: FindOptions;
|
|
76
74
|
filter: Document;
|
|
77
75
|
|
|
78
76
|
constructor(
|
|
@@ -104,7 +102,11 @@ export class FindOperation extends CommandOperation<Document> {
|
|
|
104
102
|
this.filter = filter != null && filter._bsontype === 'ObjectID' ? { _id: filter } : filter;
|
|
105
103
|
}
|
|
106
104
|
|
|
107
|
-
execute(
|
|
105
|
+
override execute(
|
|
106
|
+
server: Server,
|
|
107
|
+
session: ClientSession | undefined,
|
|
108
|
+
callback: Callback<Document>
|
|
109
|
+
): void {
|
|
108
110
|
this.server = server;
|
|
109
111
|
|
|
110
112
|
const serverWireVersion = maxWireVersion(server);
|
|
@@ -237,7 +239,9 @@ function makeFindCommand(ns: MongoDBNamespace, filter: Document, options: FindOp
|
|
|
237
239
|
findCommand.singleBatch = options.singleBatch;
|
|
238
240
|
}
|
|
239
241
|
|
|
240
|
-
|
|
242
|
+
// we check for undefined specifically here to allow falsy values
|
|
243
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
244
|
+
if (options.comment !== undefined) {
|
|
241
245
|
findCommand.comment = options.comment;
|
|
242
246
|
}
|
|
243
247
|
|
|
@@ -82,6 +82,15 @@ interface FindAndModifyCmdBase {
|
|
|
82
82
|
maxTimeMS?: number;
|
|
83
83
|
let?: Document;
|
|
84
84
|
writeConcern?: WriteConcern | WriteConcernSettings;
|
|
85
|
+
/**
|
|
86
|
+
* Comment to apply to the operation.
|
|
87
|
+
*
|
|
88
|
+
* In server versions pre-4.4, 'comment' must be string. A server
|
|
89
|
+
* error will be thrown if any other type is provided.
|
|
90
|
+
*
|
|
91
|
+
* In server versions 4.4 and above, 'comment' can be any valid BSON type.
|
|
92
|
+
*/
|
|
93
|
+
comment?: unknown;
|
|
85
94
|
}
|
|
86
95
|
|
|
87
96
|
function configureFindAndModifyCmdBaseUpdateOpts(
|
|
@@ -99,7 +108,7 @@ function configureFindAndModifyCmdBaseUpdateOpts(
|
|
|
99
108
|
|
|
100
109
|
/** @internal */
|
|
101
110
|
class FindAndModifyOperation extends CommandOperation<Document> {
|
|
102
|
-
options: FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions;
|
|
111
|
+
override options: FindOneAndReplaceOptions | FindOneAndUpdateOptions | FindOneAndDeleteOptions;
|
|
103
112
|
cmdBase: FindAndModifyCmdBase;
|
|
104
113
|
collection: Collection;
|
|
105
114
|
query: Document;
|
|
@@ -140,6 +149,12 @@ class FindAndModifyOperation extends CommandOperation<Document> {
|
|
|
140
149
|
this.cmdBase.let = options.let;
|
|
141
150
|
}
|
|
142
151
|
|
|
152
|
+
// we check for undefined specifically here to allow falsy values
|
|
153
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
154
|
+
if (options.comment !== undefined) {
|
|
155
|
+
this.cmdBase.comment = options.comment;
|
|
156
|
+
}
|
|
157
|
+
|
|
143
158
|
// force primary read preference
|
|
144
159
|
this.readPreference = ReadPreference.primary;
|
|
145
160
|
|
|
@@ -147,7 +162,11 @@ class FindAndModifyOperation extends CommandOperation<Document> {
|
|
|
147
162
|
this.query = query;
|
|
148
163
|
}
|
|
149
164
|
|
|
150
|
-
execute(
|
|
165
|
+
override execute(
|
|
166
|
+
server: Server,
|
|
167
|
+
session: ClientSession | undefined,
|
|
168
|
+
callback: Callback<Document>
|
|
169
|
+
): void {
|
|
151
170
|
const coll = this.collection;
|
|
152
171
|
const query = this.query;
|
|
153
172
|
const options = { ...this.options, ...this.bsonOptions };
|
|
@@ -2,7 +2,7 @@ import type { Document, Long } from '../bson';
|
|
|
2
2
|
import { MongoRuntimeError } from '../error';
|
|
3
3
|
import type { Server } from '../sdam/server';
|
|
4
4
|
import type { ClientSession } from '../sessions';
|
|
5
|
-
import
|
|
5
|
+
import { Callback, maxWireVersion, MongoDBNamespace } from '../utils';
|
|
6
6
|
import { AbstractOperation, Aspect, defineAspects, OperationOptions } from './operation';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -12,8 +12,12 @@ import { AbstractOperation, Aspect, defineAspects, OperationOptions } from './op
|
|
|
12
12
|
export interface GetMoreOptions extends OperationOptions {
|
|
13
13
|
/** Set the batchSize for the getMoreCommand when iterating over the query results. */
|
|
14
14
|
batchSize?: number;
|
|
15
|
-
/**
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Comment to apply to the operation.
|
|
17
|
+
*
|
|
18
|
+
* getMore only supports 'comment' in server versions 4.4 and above.
|
|
19
|
+
*/
|
|
20
|
+
comment?: unknown;
|
|
17
21
|
/** Number of milliseconds to wait before aborting the query. */
|
|
18
22
|
maxTimeMS?: number;
|
|
19
23
|
}
|
|
@@ -21,12 +25,18 @@ export interface GetMoreOptions extends OperationOptions {
|
|
|
21
25
|
/** @internal */
|
|
22
26
|
export class GetMoreOperation extends AbstractOperation {
|
|
23
27
|
cursorId: Long;
|
|
24
|
-
options: GetMoreOptions;
|
|
25
|
-
server: Server;
|
|
28
|
+
override options: GetMoreOptions;
|
|
26
29
|
|
|
27
30
|
constructor(ns: MongoDBNamespace, cursorId: Long, server: Server, options: GetMoreOptions = {}) {
|
|
28
31
|
super(options);
|
|
32
|
+
|
|
29
33
|
this.options = options;
|
|
34
|
+
|
|
35
|
+
// comment on getMore is only supported for server versions 4.4 and above
|
|
36
|
+
if (maxWireVersion(server) < 9) {
|
|
37
|
+
delete this.options.comment;
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
this.ns = ns;
|
|
31
41
|
this.cursorId = cursorId;
|
|
32
42
|
this.server = server;
|
|
@@ -36,7 +46,11 @@ export class GetMoreOperation extends AbstractOperation {
|
|
|
36
46
|
* Although there is a server already associated with the get more operation, the signature
|
|
37
47
|
* for execute passes a server so we will just use that one.
|
|
38
48
|
*/
|
|
39
|
-
execute(
|
|
49
|
+
override execute(
|
|
50
|
+
server: Server,
|
|
51
|
+
session: ClientSession | undefined,
|
|
52
|
+
callback: Callback<Document>
|
|
53
|
+
): void {
|
|
40
54
|
if (server !== this.server) {
|
|
41
55
|
return callback(
|
|
42
56
|
new MongoRuntimeError('Getmore must run on the same server operation began on')
|