mongodb 4.0.0 → 4.1.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 +62 -30
- package/lib/bson.js +1 -0
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +53 -30
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/ordered.js +3 -2
- package/lib/bulk/ordered.js.map +1 -1
- package/lib/bulk/unordered.js +3 -2
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +23 -13
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/auth_provider.js +2 -1
- package/lib/cmap/auth/auth_provider.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +5 -4
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +9 -5
- package/lib/cmap/auth/mongo_credentials.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 +32 -32
- 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 +15 -12
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +2 -2
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +26 -10
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +9 -5
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +23 -9
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +43 -46
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +113 -15
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/connection_pool_events.js +3 -1
- package/lib/cmap/connection_pool_events.js.map +1 -1
- package/lib/cmap/errors.js +3 -3
- package/lib/cmap/errors.js.map +1 -1
- package/lib/cmap/message_stream.js +1 -1
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/metrics.js +62 -0
- package/lib/cmap/metrics.js.map +1 -0
- package/lib/cmap/stream_description.js +3 -1
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +22 -9
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/shared.js +1 -1
- package/lib/cmap/wire_protocol/shared.js.map +1 -1
- package/lib/collection.js +23 -18
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +76 -30
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +75 -68
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +47 -9
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +53 -13
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +21 -14
- package/lib/db.js.map +1 -1
- package/lib/deps.js +16 -5
- package/lib/deps.js.map +1 -1
- package/lib/encrypter.js +5 -8
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +230 -34
- package/lib/error.js.map +1 -1
- package/lib/explain.js +2 -2
- package/lib/explain.js.map +1 -1
- package/lib/gridfs/download.js +22 -47
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +4 -3
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +13 -21
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +27 -2
- package/lib/index.js.map +1 -1
- package/lib/logger.js +3 -2
- package/lib/logger.js.map +1 -1
- package/lib/mongo_client.js +5 -8
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/add_user.js +2 -3
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/aggregate.js +12 -9
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/command.js +5 -7
- 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 +3 -2
- 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/count_documents.js +1 -1
- package/lib/operations/count_documents.js.map +1 -1
- package/lib/operations/delete.js +5 -5
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js +2 -2
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/estimated_document_count.js +5 -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 +31 -17
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +13 -9
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +9 -9
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/indexes.js +8 -3
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +5 -3
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js +2 -1
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/list_collections.js +6 -3
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/map_reduce.js +1 -1
- package/lib/operations/map_reduce.js.map +1 -1
- package/lib/operations/operation.js +3 -1
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js +2 -1
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js +4 -2
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/set_profiling_level.js +4 -2
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/update.js +12 -12
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js +6 -5
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/promise_provider.js +1 -1
- package/lib/promise_provider.js.map +1 -1
- package/lib/read_preference.js +8 -8
- package/lib/read_preference.js.map +1 -1
- package/lib/sdam/common.js +12 -10
- package/lib/sdam/common.js.map +1 -1
- package/lib/sdam/server.js +90 -25
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +9 -4
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +10 -4
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +1 -1
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +42 -21
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +7 -3
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +132 -31
- package/lib/sessions.js.map +1 -1
- package/lib/sort.js +3 -3
- package/lib/sort.js.map +1 -1
- package/lib/transactions.js +15 -7
- package/lib/transactions.js.map +1 -1
- package/lib/utils.js +60 -20
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +523 -138
- package/mongodb.ts34.d.ts +480 -141
- package/package.json +44 -48
- package/src/bson.ts +1 -0
- package/src/bulk/common.ts +83 -43
- package/src/bulk/ordered.ts +4 -3
- package/src/bulk/unordered.ts +4 -3
- package/src/change_stream.ts +46 -29
- package/src/cmap/auth/auth_provider.ts +3 -2
- package/src/cmap/auth/gssapi.ts +15 -5
- package/src/cmap/auth/mongo_credentials.ts +22 -8
- package/src/cmap/auth/mongocr.ts +3 -3
- package/src/cmap/auth/mongodb_aws.ts +52 -39
- package/src/cmap/auth/plain.ts +2 -2
- package/src/cmap/auth/scram.ts +23 -13
- package/src/cmap/auth/x509.ts +3 -3
- package/src/cmap/command_monitoring_events.ts +36 -14
- package/src/cmap/commands.ts +12 -6
- package/src/cmap/connect.ts +42 -12
- package/src/cmap/connection.ts +54 -62
- package/src/cmap/connection_pool.ts +141 -20
- package/src/cmap/connection_pool_events.ts +8 -1
- package/src/cmap/errors.ts +3 -4
- package/src/cmap/message_stream.ts +2 -4
- package/src/cmap/metrics.ts +58 -0
- package/src/cmap/stream_description.ts +6 -1
- package/src/cmap/wire_protocol/compression.ts +26 -13
- package/src/cmap/wire_protocol/shared.ts +4 -2
- package/src/collection.ts +75 -70
- package/src/connection_string.ts +97 -34
- package/src/cursor/abstract_cursor.ts +141 -104
- package/src/cursor/aggregation_cursor.ts +34 -20
- package/src/cursor/find_cursor.ts +41 -21
- package/src/db.ts +19 -18
- package/src/deps.ts +110 -22
- package/src/encrypter.ts +6 -12
- package/src/error.ts +264 -48
- package/src/explain.ts +3 -3
- package/src/gridfs/download.ts +48 -53
- package/src/gridfs/index.ts +5 -4
- package/src/gridfs/upload.ts +32 -33
- package/src/index.ts +42 -4
- package/src/logger.ts +6 -3
- package/src/mongo_client.ts +20 -23
- package/src/mongo_types.ts +19 -20
- package/src/operations/add_user.ts +4 -5
- package/src/operations/aggregate.ts +18 -17
- package/src/operations/command.ts +7 -10
- package/src/operations/common_functions.ts +2 -3
- package/src/operations/connect.ts +4 -3
- package/src/operations/count.ts +2 -2
- package/src/operations/count_documents.ts +2 -2
- package/src/operations/delete.ts +8 -6
- package/src/operations/distinct.ts +5 -3
- package/src/operations/estimated_document_count.ts +5 -1
- package/src/operations/eval.ts +1 -1
- package/src/operations/execute_operation.ts +41 -20
- package/src/operations/find.ts +25 -16
- package/src/operations/find_and_modify.ts +12 -10
- package/src/operations/indexes.ts +39 -8
- package/src/operations/insert.ts +7 -4
- package/src/operations/is_capped.ts +3 -2
- package/src/operations/list_collections.ts +9 -6
- package/src/operations/map_reduce.ts +4 -2
- package/src/operations/operation.ts +7 -2
- package/src/operations/options_operation.ts +3 -2
- package/src/operations/profiling_level.ts +5 -3
- package/src/operations/set_profiling_level.ts +9 -3
- package/src/operations/update.ts +17 -13
- package/src/operations/validate_collection.ts +7 -6
- package/src/promise_provider.ts +2 -2
- package/src/read_preference.ts +11 -9
- package/src/sdam/common.ts +11 -9
- package/src/sdam/server.ts +168 -69
- package/src/sdam/server_description.ts +16 -4
- package/src/sdam/server_selection.ts +15 -7
- package/src/sdam/srv_polling.ts +2 -2
- package/src/sdam/topology.ts +67 -36
- package/src/sdam/topology_description.ts +11 -4
- package/src/sessions.ts +194 -37
- package/src/sort.ts +6 -4
- package/src/transactions.ts +18 -9
- package/src/utils.ts +73 -20
- package/HISTORY.md +0 -2993
- package/lib/operations/find_one.js +0 -34
- package/lib/operations/find_one.js.map +0 -1
- package/src/operations/find_one.ts +0 -43
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { Callback, maybePromise, MongoDBNamespace, ns } from '../utils';
|
|
2
2
|
import { Long, Document, BSONSerializeOptions, pluckBSONSerializeOptions } from '../bson';
|
|
3
|
-
import { ClientSession } from '../sessions';
|
|
4
|
-
import {
|
|
3
|
+
import { ClientSession, maybeClearPinnedConnection } from '../sessions';
|
|
4
|
+
import {
|
|
5
|
+
AnyError,
|
|
6
|
+
MongoRuntimeError,
|
|
7
|
+
MongoNetworkError,
|
|
8
|
+
MongoInvalidArgumentError,
|
|
9
|
+
MongoCursorExhaustedError,
|
|
10
|
+
MongoTailableCursorError,
|
|
11
|
+
MongoCursorInUseError
|
|
12
|
+
} from '../error';
|
|
5
13
|
import { ReadPreference, ReadPreferenceLike } from '../read_preference';
|
|
6
14
|
import type { Server } from '../sdam/server';
|
|
7
15
|
import type { Topology } from '../sdam/topology';
|
|
@@ -43,9 +51,11 @@ export const CURSOR_FLAGS = [
|
|
|
43
51
|
'partial'
|
|
44
52
|
] as const;
|
|
45
53
|
|
|
46
|
-
/** @public
|
|
54
|
+
/** @public
|
|
55
|
+
* @deprecated This interface is deprecated */
|
|
47
56
|
export interface CursorCloseOptions {
|
|
48
57
|
/** Bypass calling killCursors when closing the cursor. */
|
|
58
|
+
/** @deprecated the skipKillCursors option is deprecated */
|
|
49
59
|
skipKillCursors?: boolean;
|
|
50
60
|
}
|
|
51
61
|
|
|
@@ -150,7 +160,7 @@ export abstract class AbstractCursor<
|
|
|
150
160
|
this[kOptions].batchSize = options.batchSize;
|
|
151
161
|
}
|
|
152
162
|
|
|
153
|
-
if (
|
|
163
|
+
if (options.comment != null) {
|
|
154
164
|
this[kOptions].comment = options.comment;
|
|
155
165
|
}
|
|
156
166
|
|
|
@@ -211,6 +221,10 @@ export abstract class AbstractCursor<
|
|
|
211
221
|
return this[kKilled];
|
|
212
222
|
}
|
|
213
223
|
|
|
224
|
+
get loadBalanced(): boolean {
|
|
225
|
+
return this[kTopology].loadBalanced;
|
|
226
|
+
}
|
|
227
|
+
|
|
214
228
|
/** Returns current buffered documents length */
|
|
215
229
|
bufferedCount(): number {
|
|
216
230
|
return this[kDocuments].length;
|
|
@@ -221,9 +235,12 @@ export abstract class AbstractCursor<
|
|
|
221
235
|
return this[kDocuments].splice(0, number ?? this[kDocuments].length);
|
|
222
236
|
}
|
|
223
237
|
|
|
224
|
-
[Symbol.asyncIterator](): AsyncIterator<TSchema
|
|
238
|
+
[Symbol.asyncIterator](): AsyncIterator<TSchema, void> {
|
|
225
239
|
return {
|
|
226
|
-
next: () =>
|
|
240
|
+
next: () =>
|
|
241
|
+
this.next().then(value =>
|
|
242
|
+
value != null ? { value, done: false } : { value: undefined, done: true }
|
|
243
|
+
)
|
|
227
244
|
};
|
|
228
245
|
}
|
|
229
246
|
|
|
@@ -263,8 +280,7 @@ export abstract class AbstractCursor<
|
|
|
263
280
|
return done(undefined, true);
|
|
264
281
|
}
|
|
265
282
|
|
|
266
|
-
next<
|
|
267
|
-
// FIXME(NODE):
|
|
283
|
+
next<TSchema>(this, true, (err, doc) => {
|
|
268
284
|
if (err) return done(err);
|
|
269
285
|
|
|
270
286
|
if (doc) {
|
|
@@ -279,12 +295,13 @@ export abstract class AbstractCursor<
|
|
|
279
295
|
}
|
|
280
296
|
|
|
281
297
|
/** Get the next available document from the cursor, returns null if no more documents are available. */
|
|
282
|
-
next
|
|
283
|
-
next
|
|
284
|
-
next
|
|
298
|
+
next(): Promise<TSchema | null>;
|
|
299
|
+
next(callback: Callback<TSchema | null>): void;
|
|
300
|
+
next(callback?: Callback<TSchema | null>): Promise<TSchema | null> | void;
|
|
301
|
+
next(callback?: Callback<TSchema | null>): Promise<TSchema | null> | void {
|
|
285
302
|
return maybePromise(callback, done => {
|
|
286
303
|
if (this[kId] === Long.ZERO) {
|
|
287
|
-
return done(new
|
|
304
|
+
return done(new MongoCursorExhaustedError());
|
|
288
305
|
}
|
|
289
306
|
|
|
290
307
|
next(this, true, done);
|
|
@@ -294,12 +311,12 @@ export abstract class AbstractCursor<
|
|
|
294
311
|
/**
|
|
295
312
|
* Try to get the next available document from the cursor or `null` if an empty batch is returned
|
|
296
313
|
*/
|
|
297
|
-
tryNext
|
|
298
|
-
tryNext
|
|
299
|
-
tryNext
|
|
314
|
+
tryNext(): Promise<TSchema | null>;
|
|
315
|
+
tryNext(callback: Callback<TSchema | null>): void;
|
|
316
|
+
tryNext(callback?: Callback<TSchema | null>): Promise<TSchema | null> | void {
|
|
300
317
|
return maybePromise(callback, done => {
|
|
301
318
|
if (this[kId] === Long.ZERO) {
|
|
302
|
-
return done(new
|
|
319
|
+
return done(new MongoCursorExhaustedError());
|
|
303
320
|
}
|
|
304
321
|
|
|
305
322
|
next(this, false, done);
|
|
@@ -312,19 +329,19 @@ export abstract class AbstractCursor<
|
|
|
312
329
|
* @param iterator - The iteration callback.
|
|
313
330
|
* @param callback - The end callback.
|
|
314
331
|
*/
|
|
315
|
-
forEach
|
|
316
|
-
forEach
|
|
317
|
-
forEach
|
|
318
|
-
iterator: (doc:
|
|
332
|
+
forEach(iterator: (doc: TSchema) => boolean | void): Promise<void>;
|
|
333
|
+
forEach(iterator: (doc: TSchema) => boolean | void, callback: Callback<void>): void;
|
|
334
|
+
forEach(
|
|
335
|
+
iterator: (doc: TSchema) => boolean | void,
|
|
319
336
|
callback?: Callback<void>
|
|
320
337
|
): Promise<void> | void {
|
|
321
338
|
if (typeof iterator !== 'function') {
|
|
322
|
-
throw new
|
|
339
|
+
throw new MongoInvalidArgumentError('Argument "iterator" must be a function');
|
|
323
340
|
}
|
|
324
341
|
return maybePromise(callback, done => {
|
|
325
342
|
const transform = this[kTransform];
|
|
326
343
|
const fetchDocs = () => {
|
|
327
|
-
next<
|
|
344
|
+
next<TSchema>(this, true, (err, doc) => {
|
|
328
345
|
if (err || doc == null) return done(err);
|
|
329
346
|
let result;
|
|
330
347
|
// NOTE: no need to transform because `next` will do this automatically
|
|
@@ -341,7 +358,7 @@ export abstract class AbstractCursor<
|
|
|
341
358
|
for (let i = 0; i < internalDocs.length; ++i) {
|
|
342
359
|
try {
|
|
343
360
|
result = iterator(
|
|
344
|
-
(transform ? transform(internalDocs[i]) : internalDocs[i]) as
|
|
361
|
+
(transform ? transform(internalDocs[i]) : internalDocs[i]) as TSchema // TODO(NODE-3283): Improve transform typing
|
|
345
362
|
);
|
|
346
363
|
} catch (error) {
|
|
347
364
|
return done(error);
|
|
@@ -359,7 +376,13 @@ export abstract class AbstractCursor<
|
|
|
359
376
|
|
|
360
377
|
close(): void;
|
|
361
378
|
close(callback: Callback): void;
|
|
379
|
+
/**
|
|
380
|
+
* @deprecated options argument is deprecated
|
|
381
|
+
*/
|
|
362
382
|
close(options: CursorCloseOptions): Promise<void>;
|
|
383
|
+
/**
|
|
384
|
+
* @deprecated options argument is deprecated
|
|
385
|
+
*/
|
|
363
386
|
close(options: CursorCloseOptions, callback: Callback): void;
|
|
364
387
|
close(options?: CursorCloseOptions | Callback, callback?: Callback): Promise<void> | void {
|
|
365
388
|
if (typeof options === 'function') (callback = options), (options = {});
|
|
@@ -368,49 +391,7 @@ export abstract class AbstractCursor<
|
|
|
368
391
|
const needsToEmitClosed = !this[kClosed];
|
|
369
392
|
this[kClosed] = true;
|
|
370
393
|
|
|
371
|
-
return maybePromise(callback, done => {
|
|
372
|
-
const cursorId = this[kId];
|
|
373
|
-
const cursorNs = this[kNamespace];
|
|
374
|
-
const server = this[kServer];
|
|
375
|
-
const session = this[kSession];
|
|
376
|
-
|
|
377
|
-
if (cursorId == null || server == null || cursorId.isZero() || cursorNs == null) {
|
|
378
|
-
if (needsToEmitClosed) {
|
|
379
|
-
this[kId] = Long.ZERO;
|
|
380
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
381
|
-
// @ts-expect-error
|
|
382
|
-
this.emit(AbstractCursor.CLOSE);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
if (session && session.owner === this) {
|
|
386
|
-
return session.endSession(done);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return done();
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
this[kKilled] = true;
|
|
393
|
-
server.killCursors(
|
|
394
|
-
cursorNs,
|
|
395
|
-
[cursorId],
|
|
396
|
-
{ ...pluckBSONSerializeOptions(this[kOptions]), session },
|
|
397
|
-
() => {
|
|
398
|
-
if (session && session.owner === this) {
|
|
399
|
-
return session.endSession(() => {
|
|
400
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
401
|
-
// @ts-expect-error
|
|
402
|
-
this.emit(AbstractCursor.CLOSE);
|
|
403
|
-
done();
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
408
|
-
// @ts-expect-error
|
|
409
|
-
this.emit(AbstractCursor.CLOSE);
|
|
410
|
-
done();
|
|
411
|
-
}
|
|
412
|
-
);
|
|
413
|
-
});
|
|
394
|
+
return maybePromise(callback, done => cleanupCursor(this, { needsToEmitClosed }, done));
|
|
414
395
|
}
|
|
415
396
|
|
|
416
397
|
/**
|
|
@@ -421,15 +402,15 @@ export abstract class AbstractCursor<
|
|
|
421
402
|
*
|
|
422
403
|
* @param callback - The result callback.
|
|
423
404
|
*/
|
|
424
|
-
toArray
|
|
425
|
-
toArray
|
|
426
|
-
toArray
|
|
405
|
+
toArray(): Promise<TSchema[]>;
|
|
406
|
+
toArray(callback: Callback<TSchema[]>): void;
|
|
407
|
+
toArray(callback?: Callback<TSchema[]>): Promise<TSchema[]> | void {
|
|
427
408
|
return maybePromise(callback, done => {
|
|
428
|
-
const docs:
|
|
409
|
+
const docs: TSchema[] = [];
|
|
429
410
|
const transform = this[kTransform];
|
|
430
411
|
const fetchDocs = () => {
|
|
431
412
|
// NOTE: if we add a `nextBatch` then we should use it here
|
|
432
|
-
next<
|
|
413
|
+
next<TSchema>(this, true, (err, doc) => {
|
|
433
414
|
if (err) return done(err);
|
|
434
415
|
if (doc == null) return done(undefined, docs);
|
|
435
416
|
|
|
@@ -437,9 +418,11 @@ export abstract class AbstractCursor<
|
|
|
437
418
|
docs.push(doc);
|
|
438
419
|
|
|
439
420
|
// these do need to be transformed since they are copying the rest of the batch
|
|
440
|
-
const internalDocs = (
|
|
441
|
-
|
|
442
|
-
|
|
421
|
+
const internalDocs = (
|
|
422
|
+
transform
|
|
423
|
+
? this[kDocuments].splice(0, this[kDocuments].length).map(transform)
|
|
424
|
+
: this[kDocuments].splice(0, this[kDocuments].length)
|
|
425
|
+
) as TSchema[]; // TODO(NODE-3283): Improve transform typing
|
|
443
426
|
|
|
444
427
|
if (internalDocs) {
|
|
445
428
|
docs.push(...internalDocs);
|
|
@@ -462,11 +445,11 @@ export abstract class AbstractCursor<
|
|
|
462
445
|
addCursorFlag(flag: CursorFlag, value: boolean): this {
|
|
463
446
|
assertUninitialized(this);
|
|
464
447
|
if (!CURSOR_FLAGS.includes(flag)) {
|
|
465
|
-
throw new
|
|
448
|
+
throw new MongoInvalidArgumentError(`Flag ${flag} is not one of ${CURSOR_FLAGS}`);
|
|
466
449
|
}
|
|
467
450
|
|
|
468
451
|
if (typeof value !== 'boolean') {
|
|
469
|
-
throw new
|
|
452
|
+
throw new MongoInvalidArgumentError(`Flag ${flag} must be a boolean value`);
|
|
470
453
|
}
|
|
471
454
|
|
|
472
455
|
this[kOptions][flag] = value;
|
|
@@ -477,11 +460,12 @@ export abstract class AbstractCursor<
|
|
|
477
460
|
* Map all documents using the provided function
|
|
478
461
|
* If there is a transform set on the cursor, that will be called first and the result passed to
|
|
479
462
|
* this function's transform.
|
|
480
|
-
* @remarks
|
|
481
463
|
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
464
|
+
* @remarks
|
|
465
|
+
* **Note for Typescript Users:** adding a transform changes the return type of the iteration of this cursor,
|
|
466
|
+
* it **does not** return a new instance of a cursor. This means when calling map,
|
|
467
|
+
* you should always assign the result to a new variable in order to get a correctly typed cursor variable.
|
|
468
|
+
* Take note of the following example:
|
|
485
469
|
*
|
|
486
470
|
* @example
|
|
487
471
|
* ```typescript
|
|
@@ -502,7 +486,7 @@ export abstract class AbstractCursor<
|
|
|
502
486
|
this[kTransform] = transform;
|
|
503
487
|
}
|
|
504
488
|
|
|
505
|
-
return
|
|
489
|
+
return this as unknown as AbstractCursor<T>;
|
|
506
490
|
}
|
|
507
491
|
|
|
508
492
|
/**
|
|
@@ -517,7 +501,7 @@ export abstract class AbstractCursor<
|
|
|
517
501
|
} else if (typeof readPreference === 'string') {
|
|
518
502
|
this[kOptions].readPreference = ReadPreference.fromString(readPreference);
|
|
519
503
|
} else {
|
|
520
|
-
throw new
|
|
504
|
+
throw new MongoInvalidArgumentError(`Invalid read preference: ${readPreference}`);
|
|
521
505
|
}
|
|
522
506
|
|
|
523
507
|
return this;
|
|
@@ -546,7 +530,7 @@ export abstract class AbstractCursor<
|
|
|
546
530
|
maxTimeMS(value: number): this {
|
|
547
531
|
assertUninitialized(this);
|
|
548
532
|
if (typeof value !== 'number') {
|
|
549
|
-
throw new
|
|
533
|
+
throw new MongoInvalidArgumentError('Argument for maxTimeMS must be a number');
|
|
550
534
|
}
|
|
551
535
|
|
|
552
536
|
this[kOptions].maxTimeMS = value;
|
|
@@ -561,11 +545,11 @@ export abstract class AbstractCursor<
|
|
|
561
545
|
batchSize(value: number): this {
|
|
562
546
|
assertUninitialized(this);
|
|
563
547
|
if (this[kOptions].tailable) {
|
|
564
|
-
throw new
|
|
548
|
+
throw new MongoTailableCursorError('Tailable cursor does not support batchSize');
|
|
565
549
|
}
|
|
566
550
|
|
|
567
551
|
if (typeof value !== 'number') {
|
|
568
|
-
throw new
|
|
552
|
+
throw new MongoInvalidArgumentError('Operation "batchSize" requires an integer');
|
|
569
553
|
}
|
|
570
554
|
|
|
571
555
|
this[kOptions].batchSize = value;
|
|
@@ -617,12 +601,12 @@ export abstract class AbstractCursor<
|
|
|
617
601
|
const server = this[kServer];
|
|
618
602
|
|
|
619
603
|
if (cursorId == null) {
|
|
620
|
-
callback(new
|
|
604
|
+
callback(new MongoRuntimeError('Unable to iterate cursor with no id'));
|
|
621
605
|
return;
|
|
622
606
|
}
|
|
623
607
|
|
|
624
608
|
if (server == null) {
|
|
625
|
-
callback(new
|
|
609
|
+
callback(new MongoRuntimeError('Unable to iterate cursor without selected server'));
|
|
626
610
|
return;
|
|
627
611
|
}
|
|
628
612
|
|
|
@@ -714,7 +698,7 @@ function next<T>(cursor: AbstractCursor, blocking: boolean, callback: Callback<T
|
|
|
714
698
|
cursor[kInitialized] = true;
|
|
715
699
|
|
|
716
700
|
if (err || cursorIsDead(cursor)) {
|
|
717
|
-
return cleanupCursor(cursor, () => callback(err, nextDocument(cursor)));
|
|
701
|
+
return cleanupCursor(cursor, { error: err }, () => callback(err, nextDocument(cursor)));
|
|
718
702
|
}
|
|
719
703
|
|
|
720
704
|
next(cursor, blocking, callback);
|
|
@@ -724,7 +708,7 @@ function next<T>(cursor: AbstractCursor, blocking: boolean, callback: Callback<T
|
|
|
724
708
|
}
|
|
725
709
|
|
|
726
710
|
if (cursorIsDead(cursor)) {
|
|
727
|
-
return cleanupCursor(cursor, () => callback(undefined, null));
|
|
711
|
+
return cleanupCursor(cursor, undefined, () => callback(undefined, null));
|
|
728
712
|
}
|
|
729
713
|
|
|
730
714
|
// otherwise need to call getMore
|
|
@@ -741,7 +725,7 @@ function next<T>(cursor: AbstractCursor, blocking: boolean, callback: Callback<T
|
|
|
741
725
|
}
|
|
742
726
|
|
|
743
727
|
if (err || cursorIsDead(cursor)) {
|
|
744
|
-
return cleanupCursor(cursor, () => callback(err, nextDocument(cursor)));
|
|
728
|
+
return cleanupCursor(cursor, { error: err }, () => callback(err, nextDocument(cursor)));
|
|
745
729
|
}
|
|
746
730
|
|
|
747
731
|
if (cursor[kDocuments].length === 0 && blocking === false) {
|
|
@@ -757,24 +741,75 @@ function cursorIsDead(cursor: AbstractCursor): boolean {
|
|
|
757
741
|
return !!cursorId && cursorId.isZero();
|
|
758
742
|
}
|
|
759
743
|
|
|
760
|
-
function cleanupCursor(
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
744
|
+
function cleanupCursor(
|
|
745
|
+
cursor: AbstractCursor,
|
|
746
|
+
options: { error?: AnyError | undefined; needsToEmitClosed?: boolean } | undefined,
|
|
747
|
+
callback: Callback
|
|
748
|
+
): void {
|
|
749
|
+
const cursorId = cursor[kId];
|
|
750
|
+
const cursorNs = cursor[kNamespace];
|
|
751
|
+
const server = cursor[kServer];
|
|
752
|
+
const session = cursor[kSession];
|
|
753
|
+
const error = options?.error;
|
|
754
|
+
const needsToEmitClosed = options?.needsToEmitClosed ?? cursor[kDocuments].length === 0;
|
|
755
|
+
|
|
756
|
+
if (error) {
|
|
757
|
+
if (cursor.loadBalanced && error instanceof MongoNetworkError) {
|
|
758
|
+
return completeCleanup();
|
|
759
|
+
}
|
|
764
760
|
}
|
|
765
761
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
762
|
+
if (cursorId == null || server == null || cursorId.isZero() || cursorNs == null) {
|
|
763
|
+
if (needsToEmitClosed) {
|
|
764
|
+
cursor[kClosed] = true;
|
|
765
|
+
cursor[kId] = Long.ZERO;
|
|
766
|
+
cursor.emit(AbstractCursor.CLOSE);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (session) {
|
|
770
|
+
if (session.owner === cursor) {
|
|
771
|
+
return session.endSession({ error }, callback);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
if (!session.inTransaction()) {
|
|
775
|
+
maybeClearPinnedConnection(session, { error });
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
return callback();
|
|
771
780
|
}
|
|
781
|
+
|
|
782
|
+
function completeCleanup() {
|
|
783
|
+
if (session) {
|
|
784
|
+
if (session.owner === cursor) {
|
|
785
|
+
return session.endSession({ error }, () => {
|
|
786
|
+
cursor.emit(AbstractCursor.CLOSE);
|
|
787
|
+
callback();
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
if (!session.inTransaction()) {
|
|
792
|
+
maybeClearPinnedConnection(session, { error });
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
cursor.emit(AbstractCursor.CLOSE);
|
|
797
|
+
return callback();
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
cursor[kKilled] = true;
|
|
801
|
+
server.killCursors(
|
|
802
|
+
cursorNs,
|
|
803
|
+
[cursorId],
|
|
804
|
+
{ ...pluckBSONSerializeOptions(cursor[kOptions]), session },
|
|
805
|
+
() => completeCleanup()
|
|
806
|
+
);
|
|
772
807
|
}
|
|
773
808
|
|
|
774
809
|
/** @internal */
|
|
775
810
|
export function assertUninitialized(cursor: AbstractCursor): void {
|
|
776
811
|
if (cursor[kInitialized]) {
|
|
777
|
-
throw new
|
|
812
|
+
throw new MongoCursorInUseError();
|
|
778
813
|
}
|
|
779
814
|
}
|
|
780
815
|
|
|
@@ -812,7 +847,7 @@ function makeCursorStream<TSchema extends Document>(cursor: AbstractCursor<TSche
|
|
|
812
847
|
function readNext() {
|
|
813
848
|
needToClose = false;
|
|
814
849
|
next(cursor, true, (err, result) => {
|
|
815
|
-
needToClose = err ? !cursor.closed : result
|
|
850
|
+
needToClose = err ? !cursor.closed : result != null;
|
|
816
851
|
|
|
817
852
|
if (err) {
|
|
818
853
|
// NOTE: This is questionable, but we have a test backing the behavior. It seems the
|
|
@@ -826,15 +861,17 @@ function makeCursorStream<TSchema extends Document>(cursor: AbstractCursor<TSche
|
|
|
826
861
|
|
|
827
862
|
// NOTE: This is also perhaps questionable. The rationale here is that these errors tend
|
|
828
863
|
// to be "operation interrupted", where a cursor has been closed but there is an
|
|
829
|
-
// active getMore in-flight.
|
|
830
|
-
|
|
864
|
+
// active getMore in-flight. This used to check if the cursor was killed but once
|
|
865
|
+
// that changed to happen in cleanup legitimate errors would not destroy the
|
|
866
|
+
// stream. There are change streams test specifically test these cases.
|
|
867
|
+
if (err.message.match(/interrupted/)) {
|
|
831
868
|
return readable.push(null);
|
|
832
869
|
}
|
|
833
870
|
|
|
834
871
|
return readable.destroy(err);
|
|
835
872
|
}
|
|
836
873
|
|
|
837
|
-
if (result
|
|
874
|
+
if (result == null) {
|
|
838
875
|
readable.push(null);
|
|
839
876
|
} else if (readable.destroyed) {
|
|
840
877
|
cursor.close();
|
|
@@ -7,16 +7,12 @@ import type { Sort } from '../sort';
|
|
|
7
7
|
import type { Topology } from '../sdam/topology';
|
|
8
8
|
import type { Callback, MongoDBNamespace } from '../utils';
|
|
9
9
|
import type { ClientSession } from '../sessions';
|
|
10
|
-
import type { OperationParent } from '../operations/command';
|
|
11
10
|
import type { AbstractCursorOptions } from './abstract_cursor';
|
|
12
11
|
import type { ExplainVerbosityLike } from '../explain';
|
|
13
|
-
import type { Projection } from '../mongo_types';
|
|
14
12
|
|
|
15
13
|
/** @public */
|
|
16
14
|
export interface AggregationCursorOptions extends AbstractCursorOptions, AggregateOptions {}
|
|
17
15
|
|
|
18
|
-
/** @internal */
|
|
19
|
-
const kParent = Symbol('parent');
|
|
20
16
|
/** @internal */
|
|
21
17
|
const kPipeline = Symbol('pipeline');
|
|
22
18
|
/** @internal */
|
|
@@ -30,8 +26,6 @@ const kOptions = Symbol('options');
|
|
|
30
26
|
* @public
|
|
31
27
|
*/
|
|
32
28
|
export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchema> {
|
|
33
|
-
/** @internal */
|
|
34
|
-
[kParent]: OperationParent; // TODO: NODE-2883
|
|
35
29
|
/** @internal */
|
|
36
30
|
[kPipeline]: Document[];
|
|
37
31
|
/** @internal */
|
|
@@ -39,7 +33,6 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
|
|
|
39
33
|
|
|
40
34
|
/** @internal */
|
|
41
35
|
constructor(
|
|
42
|
-
parent: OperationParent,
|
|
43
36
|
topology: Topology,
|
|
44
37
|
namespace: MongoDBNamespace,
|
|
45
38
|
pipeline: Document[] = [],
|
|
@@ -47,7 +40,6 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
|
|
|
47
40
|
) {
|
|
48
41
|
super(topology, namespace, options);
|
|
49
42
|
|
|
50
|
-
this[kParent] = parent;
|
|
51
43
|
this[kPipeline] = pipeline;
|
|
52
44
|
this[kOptions] = options;
|
|
53
45
|
}
|
|
@@ -59,7 +51,7 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
|
|
|
59
51
|
clone(): AggregationCursor<TSchema> {
|
|
60
52
|
const clonedOptions = mergeOptions({}, this[kOptions]);
|
|
61
53
|
delete clonedOptions.session;
|
|
62
|
-
return new AggregationCursor(this
|
|
54
|
+
return new AggregationCursor(this.topology, this.namespace, this[kPipeline], {
|
|
63
55
|
...clonedOptions
|
|
64
56
|
});
|
|
65
57
|
}
|
|
@@ -70,7 +62,7 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
|
|
|
70
62
|
|
|
71
63
|
/** @internal */
|
|
72
64
|
_initialize(session: ClientSession | undefined, callback: Callback<ExecutionResult>): void {
|
|
73
|
-
const aggregateOperation = new AggregateOperation(this
|
|
65
|
+
const aggregateOperation = new AggregateOperation(this.namespace, this[kPipeline], {
|
|
74
66
|
...this[kOptions],
|
|
75
67
|
...this.cursorOptions,
|
|
76
68
|
session
|
|
@@ -93,11 +85,11 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
|
|
|
93
85
|
callback?: Callback<Document>
|
|
94
86
|
): Promise<Document> | void {
|
|
95
87
|
if (typeof verbosity === 'function') (callback = verbosity), (verbosity = true);
|
|
96
|
-
if (verbosity
|
|
88
|
+
if (verbosity == null) verbosity = true;
|
|
97
89
|
|
|
98
90
|
return executeOperation(
|
|
99
91
|
this.topology,
|
|
100
|
-
new AggregateOperation(this
|
|
92
|
+
new AggregateOperation(this.namespace, this[kPipeline], {
|
|
101
93
|
...this[kOptions], // NOTE: order matters here, we may need to refine this
|
|
102
94
|
...this.cursorOptions,
|
|
103
95
|
explain: verbosity
|
|
@@ -128,8 +120,8 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
|
|
|
128
120
|
return this;
|
|
129
121
|
}
|
|
130
122
|
|
|
131
|
-
/** Add
|
|
132
|
-
out($out:
|
|
123
|
+
/** Add an out stage to the aggregation pipeline */
|
|
124
|
+
out($out: { db: string; coll: string } | string): this {
|
|
133
125
|
assertUninitialized(this);
|
|
134
126
|
this[kPipeline].push({ $out });
|
|
135
127
|
return this;
|
|
@@ -142,22 +134,44 @@ export class AggregationCursor<TSchema = Document> extends AbstractCursor<TSchem
|
|
|
142
134
|
* In order to strictly type this function you must provide an interface
|
|
143
135
|
* that represents the effect of your projection on the result documents.
|
|
144
136
|
*
|
|
145
|
-
*
|
|
137
|
+
* By default chaining a projection to your cursor changes the returned type to the generic {@link Document} type.
|
|
138
|
+
* You should specify a parameterized type to have assertions on your final results.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* // Best way
|
|
143
|
+
* const docs: AggregationCursor<{ a: number }> = cursor.project<{ a: number }>({ _id: 0, a: true });
|
|
144
|
+
* // Flexible way
|
|
145
|
+
* const docs: AggregationCursor<Document> = cursor.project({ _id: 0, a: true });
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @remarks
|
|
149
|
+
* In order to strictly type this function you must provide an interface
|
|
150
|
+
* that represents the effect of your projection on the result documents.
|
|
151
|
+
*
|
|
152
|
+
* **Note for Typescript Users:** adding a transform changes the return type of the iteration of this cursor,
|
|
146
153
|
* it **does not** return a new instance of a cursor. This means when calling project,
|
|
147
|
-
* you should always assign the result to a new variable
|
|
154
|
+
* you should always assign the result to a new variable in order to get a correctly typed cursor variable.
|
|
155
|
+
* Take note of the following example:
|
|
148
156
|
*
|
|
149
157
|
* @example
|
|
150
158
|
* ```typescript
|
|
151
159
|
* const cursor: AggregationCursor<{ a: number; b: string }> = coll.aggregate([]);
|
|
152
|
-
* const projectCursor = cursor.project<{ a: number }>({ a: true });
|
|
160
|
+
* const projectCursor = cursor.project<{ a: number }>({ _id: 0, a: true });
|
|
153
161
|
* const aPropOnlyArray: {a: number}[] = await projectCursor.toArray();
|
|
162
|
+
*
|
|
163
|
+
* // or always use chaining and save the final cursor
|
|
164
|
+
*
|
|
165
|
+
* const cursor = coll.aggregate().project<{ a: string }>({
|
|
166
|
+
* _id: 0,
|
|
167
|
+
* a: { $convert: { input: '$a', to: 'string' }
|
|
168
|
+
* }});
|
|
154
169
|
* ```
|
|
155
170
|
*/
|
|
156
|
-
project<T =
|
|
157
|
-
project($project: Document): this {
|
|
171
|
+
project<T extends Document = Document>($project: Document): AggregationCursor<T> {
|
|
158
172
|
assertUninitialized(this);
|
|
159
173
|
this[kPipeline].push({ $project });
|
|
160
|
-
return this
|
|
174
|
+
return this as unknown as AggregationCursor<T>;
|
|
161
175
|
}
|
|
162
176
|
|
|
163
177
|
/** Add a lookup stage to the aggregation pipeline */
|