@depup/mongodb 7.1.0-depup.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/LICENSE.md +201 -0
- package/README.md +33 -0
- package/etc/prepare.js +12 -0
- package/lib/admin.js +136 -0
- package/lib/admin.js.map +1 -0
- package/lib/bson.js +85 -0
- package/lib/bson.js.map +1 -0
- package/lib/bulk/common.js +835 -0
- package/lib/bulk/common.js.map +1 -0
- package/lib/bulk/ordered.js +67 -0
- package/lib/bulk/ordered.js.map +1 -0
- package/lib/bulk/unordered.js +92 -0
- package/lib/bulk/unordered.js.map +1 -0
- package/lib/change_stream.js +513 -0
- package/lib/change_stream.js.map +1 -0
- package/lib/client-side-encryption/auto_encrypter.js +272 -0
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -0
- package/lib/client-side-encryption/client_encryption.js +609 -0
- package/lib/client-side-encryption/client_encryption.js.map +1 -0
- package/lib/client-side-encryption/errors.js +138 -0
- package/lib/client-side-encryption/errors.js.map +1 -0
- package/lib/client-side-encryption/mongocryptd_manager.js +85 -0
- package/lib/client-side-encryption/mongocryptd_manager.js.map +1 -0
- package/lib/client-side-encryption/providers/aws.js +23 -0
- package/lib/client-side-encryption/providers/aws.js.map +1 -0
- package/lib/client-side-encryption/providers/azure.js +132 -0
- package/lib/client-side-encryption/providers/azure.js.map +1 -0
- package/lib/client-side-encryption/providers/gcp.js +16 -0
- package/lib/client-side-encryption/providers/gcp.js.map +1 -0
- package/lib/client-side-encryption/providers/index.js +43 -0
- package/lib/client-side-encryption/providers/index.js.map +1 -0
- package/lib/client-side-encryption/state_machine.js +427 -0
- package/lib/client-side-encryption/state_machine.js.map +1 -0
- package/lib/cmap/auth/auth_provider.js +51 -0
- package/lib/cmap/auth/auth_provider.js.map +1 -0
- package/lib/cmap/auth/aws4.js +161 -0
- package/lib/cmap/auth/aws4.js.map +1 -0
- package/lib/cmap/auth/aws_temporary_credentials.js +103 -0
- package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
- package/lib/cmap/auth/gssapi.js +155 -0
- package/lib/cmap/auth/gssapi.js.map +1 -0
- package/lib/cmap/auth/mongo_credentials.js +169 -0
- package/lib/cmap/auth/mongo_credentials.js.map +1 -0
- package/lib/cmap/auth/mongodb_aws.js +128 -0
- package/lib/cmap/auth/mongodb_aws.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js +84 -0
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js +62 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +141 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/command_builders.js +44 -0
- package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js +39 -0
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js +122 -0
- package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +32 -0
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_cache.js +52 -0
- package/lib/cmap/auth/mongodb_oidc/token_cache.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js +23 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc.js +73 -0
- package/lib/cmap/auth/mongodb_oidc.js.map +1 -0
- package/lib/cmap/auth/plain.js +26 -0
- package/lib/cmap/auth/plain.js.map +1 -0
- package/lib/cmap/auth/providers.js +22 -0
- package/lib/cmap/auth/providers.js.map +1 -0
- package/lib/cmap/auth/scram.js +254 -0
- package/lib/cmap/auth/scram.js.map +1 -0
- package/lib/cmap/auth/x509.js +36 -0
- package/lib/cmap/auth/x509.js.map +1 -0
- package/lib/cmap/command_monitoring_events.js +223 -0
- package/lib/cmap/command_monitoring_events.js.map +1 -0
- package/lib/cmap/commands.js +535 -0
- package/lib/cmap/commands.js.map +1 -0
- package/lib/cmap/connect.js +381 -0
- package/lib/cmap/connect.js.map +1 -0
- package/lib/cmap/connection.js +571 -0
- package/lib/cmap/connection.js.map +1 -0
- package/lib/cmap/connection_pool.js +558 -0
- package/lib/cmap/connection_pool.js.map +1 -0
- package/lib/cmap/connection_pool_events.js +190 -0
- package/lib/cmap/connection_pool_events.js.map +1 -0
- package/lib/cmap/errors.js +108 -0
- package/lib/cmap/errors.js.map +1 -0
- package/lib/cmap/handshake/client_metadata.js +242 -0
- package/lib/cmap/handshake/client_metadata.js.map +1 -0
- package/lib/cmap/metrics.js +62 -0
- package/lib/cmap/metrics.js.map +1 -0
- package/lib/cmap/stream_description.js +70 -0
- package/lib/cmap/stream_description.js.map +1 -0
- package/lib/cmap/wire_protocol/compression.js +178 -0
- package/lib/cmap/wire_protocol/compression.js.map +1 -0
- package/lib/cmap/wire_protocol/constants.js +21 -0
- package/lib/cmap/wire_protocol/constants.js.map +1 -0
- package/lib/cmap/wire_protocol/on_data.js +111 -0
- package/lib/cmap/wire_protocol/on_data.js.map +1 -0
- package/lib/cmap/wire_protocol/on_demand/document.js +222 -0
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
- package/lib/cmap/wire_protocol/responses.js +315 -0
- package/lib/cmap/wire_protocol/responses.js.map +1 -0
- package/lib/cmap/wire_protocol/shared.js +35 -0
- package/lib/cmap/wire_protocol/shared.js.map +1 -0
- package/lib/collection.js +751 -0
- package/lib/collection.js.map +1 -0
- package/lib/connection_string.js +1090 -0
- package/lib/connection_string.js.map +1 -0
- package/lib/constants.js +170 -0
- package/lib/constants.js.map +1 -0
- package/lib/cursor/abstract_cursor.js +924 -0
- package/lib/cursor/abstract_cursor.js.map +1 -0
- package/lib/cursor/aggregation_cursor.js +164 -0
- package/lib/cursor/aggregation_cursor.js.map +1 -0
- package/lib/cursor/change_stream_cursor.js +104 -0
- package/lib/cursor/change_stream_cursor.js.map +1 -0
- package/lib/cursor/client_bulk_write_cursor.js +52 -0
- package/lib/cursor/client_bulk_write_cursor.js.map +1 -0
- package/lib/cursor/explainable_cursor.js +36 -0
- package/lib/cursor/explainable_cursor.js.map +1 -0
- package/lib/cursor/find_cursor.js +399 -0
- package/lib/cursor/find_cursor.js.map +1 -0
- package/lib/cursor/list_collections_cursor.js +34 -0
- package/lib/cursor/list_collections_cursor.js.map +1 -0
- package/lib/cursor/list_indexes_cursor.js +32 -0
- package/lib/cursor/list_indexes_cursor.js.map +1 -0
- package/lib/cursor/list_search_indexes_cursor.js +14 -0
- package/lib/cursor/list_search_indexes_cursor.js.map +1 -0
- package/lib/cursor/run_command_cursor.js +94 -0
- package/lib/cursor/run_command_cursor.js.map +1 -0
- package/lib/db.js +419 -0
- package/lib/db.js.map +1 -0
- package/lib/deps.js +112 -0
- package/lib/deps.js.map +1 -0
- package/lib/encrypter.js +106 -0
- package/lib/encrypter.js.map +1 -0
- package/lib/error.js +1380 -0
- package/lib/error.js.map +1 -0
- package/lib/explain.js +59 -0
- package/lib/explain.js.map +1 -0
- package/lib/gridfs/download.js +305 -0
- package/lib/gridfs/download.js.map +1 -0
- package/lib/gridfs/index.js +164 -0
- package/lib/gridfs/index.js.map +1 -0
- package/lib/gridfs/upload.js +358 -0
- package/lib/gridfs/upload.js.map +1 -0
- package/lib/index.js +193 -0
- package/lib/index.js.map +1 -0
- package/lib/mongo_client.js +557 -0
- package/lib/mongo_client.js.map +1 -0
- package/lib/mongo_client_auth_providers.js +80 -0
- package/lib/mongo_client_auth_providers.js.map +1 -0
- package/lib/mongo_logger.js +655 -0
- package/lib/mongo_logger.js.map +1 -0
- package/lib/mongo_types.js +56 -0
- package/lib/mongo_types.js.map +1 -0
- package/lib/operations/aggregate.js +90 -0
- package/lib/operations/aggregate.js.map +1 -0
- package/lib/operations/client_bulk_write/client_bulk_write.js +51 -0
- package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -0
- package/lib/operations/client_bulk_write/command_builder.js +340 -0
- package/lib/operations/client_bulk_write/command_builder.js.map +1 -0
- package/lib/operations/client_bulk_write/common.js +3 -0
- package/lib/operations/client_bulk_write/common.js.map +1 -0
- package/lib/operations/client_bulk_write/executor.js +120 -0
- package/lib/operations/client_bulk_write/executor.js.map +1 -0
- package/lib/operations/client_bulk_write/results_merger.js +204 -0
- package/lib/operations/client_bulk_write/results_merger.js.map +1 -0
- package/lib/operations/command.js +83 -0
- package/lib/operations/command.js.map +1 -0
- package/lib/operations/count.js +45 -0
- package/lib/operations/count.js.map +1 -0
- package/lib/operations/create_collection.js +109 -0
- package/lib/operations/create_collection.js.map +1 -0
- package/lib/operations/delete.js +125 -0
- package/lib/operations/delete.js.map +1 -0
- package/lib/operations/distinct.js +61 -0
- package/lib/operations/distinct.js.map +1 -0
- package/lib/operations/drop.js +93 -0
- package/lib/operations/drop.js.map +1 -0
- package/lib/operations/end_sessions.js +34 -0
- package/lib/operations/end_sessions.js.map +1 -0
- package/lib/operations/estimated_document_count.js +41 -0
- package/lib/operations/estimated_document_count.js.map +1 -0
- package/lib/operations/execute_operation.js +239 -0
- package/lib/operations/execute_operation.js.map +1 -0
- package/lib/operations/find.js +148 -0
- package/lib/operations/find.js.map +1 -0
- package/lib/operations/find_and_modify.js +158 -0
- package/lib/operations/find_and_modify.js.map +1 -0
- package/lib/operations/get_more.js +62 -0
- package/lib/operations/get_more.js.map +1 -0
- package/lib/operations/indexes.js +186 -0
- package/lib/operations/indexes.js.map +1 -0
- package/lib/operations/insert.js +70 -0
- package/lib/operations/insert.js.map +1 -0
- package/lib/operations/kill_cursors.js +43 -0
- package/lib/operations/kill_cursors.js.map +1 -0
- package/lib/operations/list_collections.js +53 -0
- package/lib/operations/list_collections.js.map +1 -0
- package/lib/operations/list_databases.js +40 -0
- package/lib/operations/list_databases.js.map +1 -0
- package/lib/operations/operation.js +102 -0
- package/lib/operations/operation.js.map +1 -0
- package/lib/operations/profiling_level.js +43 -0
- package/lib/operations/profiling_level.js.map +1 -0
- package/lib/operations/remove_user.js +27 -0
- package/lib/operations/remove_user.js.map +1 -0
- package/lib/operations/rename.js +38 -0
- package/lib/operations/rename.js.map +1 -0
- package/lib/operations/run_command.js +47 -0
- package/lib/operations/run_command.js.map +1 -0
- package/lib/operations/search_indexes/create.js +33 -0
- package/lib/operations/search_indexes/create.js.map +1 -0
- package/lib/operations/search_indexes/drop.js +43 -0
- package/lib/operations/search_indexes/drop.js.map +1 -0
- package/lib/operations/search_indexes/update.js +35 -0
- package/lib/operations/search_indexes/update.js.map +1 -0
- package/lib/operations/set_profiling_level.js +53 -0
- package/lib/operations/set_profiling_level.js.map +1 -0
- package/lib/operations/stats.js +27 -0
- package/lib/operations/stats.js.map +1 -0
- package/lib/operations/update.js +188 -0
- package/lib/operations/update.js.map +1 -0
- package/lib/operations/validate_collection.js +37 -0
- package/lib/operations/validate_collection.js.map +1 -0
- package/lib/read_concern.js +73 -0
- package/lib/read_concern.js.map +1 -0
- package/lib/read_preference.js +191 -0
- package/lib/read_preference.js.map +1 -0
- package/lib/sdam/common.js +49 -0
- package/lib/sdam/common.js.map +1 -0
- package/lib/sdam/events.js +146 -0
- package/lib/sdam/events.js.map +1 -0
- package/lib/sdam/monitor.js +544 -0
- package/lib/sdam/monitor.js.map +1 -0
- package/lib/sdam/server.js +404 -0
- package/lib/sdam/server.js.map +1 -0
- package/lib/sdam/server_description.js +204 -0
- package/lib/sdam/server_description.js.map +1 -0
- package/lib/sdam/server_selection.js +294 -0
- package/lib/sdam/server_selection.js.map +1 -0
- package/lib/sdam/server_selection_events.js +85 -0
- package/lib/sdam/server_selection_events.js.map +1 -0
- package/lib/sdam/srv_polling.js +108 -0
- package/lib/sdam/srv_polling.js.map +1 -0
- package/lib/sdam/topology.js +652 -0
- package/lib/sdam/topology.js.map +1 -0
- package/lib/sdam/topology_description.js +383 -0
- package/lib/sdam/topology_description.js.map +1 -0
- package/lib/sessions.js +892 -0
- package/lib/sessions.js.map +1 -0
- package/lib/sort.js +103 -0
- package/lib/sort.js.map +1 -0
- package/lib/timeout.js +296 -0
- package/lib/timeout.js.map +1 -0
- package/lib/transactions.js +135 -0
- package/lib/transactions.js.map +1 -0
- package/lib/utils.js +1163 -0
- package/lib/utils.js.map +1 -0
- package/lib/write_concern.js +100 -0
- package/lib/write_concern.js.map +1 -0
- package/mongodb.d.ts +9018 -0
- package/package.json +197 -0
- package/src/admin.ts +173 -0
- package/src/bson.ts +149 -0
- package/src/bulk/common.ts +1251 -0
- package/src/bulk/ordered.ts +83 -0
- package/src/bulk/unordered.ts +115 -0
- package/src/change_stream.ts +1160 -0
- package/src/client-side-encryption/auto_encrypter.ts +469 -0
- package/src/client-side-encryption/client_encryption.ts +1150 -0
- package/src/client-side-encryption/errors.ts +144 -0
- package/src/client-side-encryption/mongocryptd_manager.ts +100 -0
- package/src/client-side-encryption/providers/aws.ts +33 -0
- package/src/client-side-encryption/providers/azure.ts +181 -0
- package/src/client-side-encryption/providers/gcp.ts +16 -0
- package/src/client-side-encryption/providers/index.ts +207 -0
- package/src/client-side-encryption/state_machine.ts +651 -0
- package/src/cmap/auth/auth_provider.ts +77 -0
- package/src/cmap/auth/aws4.ts +207 -0
- package/src/cmap/auth/aws_temporary_credentials.ts +129 -0
- package/src/cmap/auth/gssapi.ts +203 -0
- package/src/cmap/auth/mongo_credentials.ts +292 -0
- package/src/cmap/auth/mongodb_aws.ts +179 -0
- package/src/cmap/auth/mongodb_oidc/automated_callback_workflow.ts +88 -0
- package/src/cmap/auth/mongodb_oidc/azure_machine_workflow.ts +73 -0
- package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +188 -0
- package/src/cmap/auth/mongodb_oidc/command_builders.ts +53 -0
- package/src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts +46 -0
- package/src/cmap/auth/mongodb_oidc/human_callback_workflow.ts +141 -0
- package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +31 -0
- package/src/cmap/auth/mongodb_oidc/token_cache.ts +62 -0
- package/src/cmap/auth/mongodb_oidc/token_machine_workflow.ts +22 -0
- package/src/cmap/auth/mongodb_oidc.ts +185 -0
- package/src/cmap/auth/plain.ts +25 -0
- package/src/cmap/auth/providers.ts +22 -0
- package/src/cmap/auth/scram.ts +344 -0
- package/src/cmap/auth/x509.ts +43 -0
- package/src/cmap/command_monitoring_events.ts +316 -0
- package/src/cmap/commands.ts +788 -0
- package/src/cmap/connect.ts +518 -0
- package/src/cmap/connection.ts +931 -0
- package/src/cmap/connection_pool.ts +831 -0
- package/src/cmap/connection_pool_events.ts +300 -0
- package/src/cmap/errors.ts +119 -0
- package/src/cmap/handshake/client_metadata.ts +353 -0
- package/src/cmap/metrics.ts +58 -0
- package/src/cmap/stream_description.ts +96 -0
- package/src/cmap/wire_protocol/compression.ts +211 -0
- package/src/cmap/wire_protocol/constants.ts +17 -0
- package/src/cmap/wire_protocol/on_data.ts +139 -0
- package/src/cmap/wire_protocol/on_demand/document.ts +358 -0
- package/src/cmap/wire_protocol/responses.ts +393 -0
- package/src/cmap/wire_protocol/shared.ts +48 -0
- package/src/collection.ts +1314 -0
- package/src/connection_string.ts +1297 -0
- package/src/constants.ts +176 -0
- package/src/cursor/abstract_cursor.ts +1247 -0
- package/src/cursor/aggregation_cursor.ts +245 -0
- package/src/cursor/change_stream_cursor.ts +171 -0
- package/src/cursor/client_bulk_write_cursor.ts +83 -0
- package/src/cursor/explainable_cursor.ts +51 -0
- package/src/cursor/find_cursor.ts +497 -0
- package/src/cursor/list_collections_cursor.ts +50 -0
- package/src/cursor/list_indexes_cursor.ts +37 -0
- package/src/cursor/list_search_indexes_cursor.ts +20 -0
- package/src/cursor/run_command_cursor.ts +178 -0
- package/src/db.ts +621 -0
- package/src/deps.ts +227 -0
- package/src/encrypter.ts +127 -0
- package/src/error.ts +1567 -0
- package/src/explain.ts +124 -0
- package/src/gridfs/download.ts +483 -0
- package/src/gridfs/index.ts +264 -0
- package/src/gridfs/upload.ts +537 -0
- package/src/index.ts +633 -0
- package/src/mongo_client.ts +1155 -0
- package/src/mongo_client_auth_providers.ts +87 -0
- package/src/mongo_logger.ts +1081 -0
- package/src/mongo_types.ts +678 -0
- package/src/operations/aggregate.ts +153 -0
- package/src/operations/client_bulk_write/client_bulk_write.ts +72 -0
- package/src/operations/client_bulk_write/command_builder.ts +487 -0
- package/src/operations/client_bulk_write/common.ts +276 -0
- package/src/operations/client_bulk_write/executor.ts +149 -0
- package/src/operations/client_bulk_write/results_merger.ts +260 -0
- package/src/operations/command.ts +171 -0
- package/src/operations/count.ts +74 -0
- package/src/operations/create_collection.ts +218 -0
- package/src/operations/delete.ts +183 -0
- package/src/operations/distinct.ts +92 -0
- package/src/operations/drop.ts +130 -0
- package/src/operations/end_sessions.ts +44 -0
- package/src/operations/estimated_document_count.ts +61 -0
- package/src/operations/execute_operation.ts +319 -0
- package/src/operations/find.ts +254 -0
- package/src/operations/find_and_modify.ts +319 -0
- package/src/operations/get_more.ts +108 -0
- package/src/operations/indexes.ts +418 -0
- package/src/operations/insert.ts +108 -0
- package/src/operations/kill_cursors.ts +64 -0
- package/src/operations/list_collections.ts +108 -0
- package/src/operations/list_databases.ts +68 -0
- package/src/operations/operation.ts +181 -0
- package/src/operations/profiling_level.ts +46 -0
- package/src/operations/remove_user.ts +36 -0
- package/src/operations/rename.ts +60 -0
- package/src/operations/run_command.ts +79 -0
- package/src/operations/search_indexes/create.ts +56 -0
- package/src/operations/search_indexes/drop.ts +58 -0
- package/src/operations/search_indexes/update.ts +45 -0
- package/src/operations/set_profiling_level.ts +74 -0
- package/src/operations/stats.ts +37 -0
- package/src/operations/update.ts +318 -0
- package/src/operations/validate_collection.ts +50 -0
- package/src/read_concern.ts +88 -0
- package/src/read_preference.ts +256 -0
- package/src/sdam/common.ts +74 -0
- package/src/sdam/events.ts +219 -0
- package/src/sdam/monitor.ts +771 -0
- package/src/sdam/server.ts +595 -0
- package/src/sdam/server_description.ts +297 -0
- package/src/sdam/server_selection.ts +415 -0
- package/src/sdam/server_selection_events.ts +142 -0
- package/src/sdam/srv_polling.ts +146 -0
- package/src/sdam/topology.ts +1100 -0
- package/src/sdam/topology_description.ts +548 -0
- package/src/sessions.ts +1244 -0
- package/src/sort.ts +141 -0
- package/src/timeout.ts +405 -0
- package/src/transactions.ts +181 -0
- package/src/utils.ts +1434 -0
- package/src/write_concern.ts +183 -0
- package/tsconfig.json +46 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { type Document } from '../bson';
|
|
2
|
+
import { type Connection } from '../cmap/connection';
|
|
3
|
+
import { MongoDBResponse } from '../cmap/wire_protocol/responses';
|
|
4
|
+
import type { Collection } from '../collection';
|
|
5
|
+
import { CommandOperation, type CommandOperationOptions } from './command';
|
|
6
|
+
import { Aspect, defineAspects } from './operation';
|
|
7
|
+
|
|
8
|
+
/** @public */
|
|
9
|
+
export type DistinctOptions = CommandOperationOptions & {
|
|
10
|
+
/**
|
|
11
|
+
* @sinceServerVersion 7.1
|
|
12
|
+
*
|
|
13
|
+
* The index to use. Specify either the index name as a string or the index key pattern.
|
|
14
|
+
* If specified, then the query system will only consider plans using the hinted index.
|
|
15
|
+
*
|
|
16
|
+
* If provided as a string, `hint` must be index name for an index on the collection.
|
|
17
|
+
* If provided as an object, `hint` must be an index description for an index defined on the collection.
|
|
18
|
+
*
|
|
19
|
+
* See https://www.mongodb.com/docs/manual/reference/command/distinct/#command-fields.
|
|
20
|
+
*/
|
|
21
|
+
hint?: Document | string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Return a list of distinct values for the given key across a collection.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export class DistinctOperation extends CommandOperation<any[] | Document> {
|
|
29
|
+
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
|
|
30
|
+
override options: DistinctOptions;
|
|
31
|
+
collection: Collection;
|
|
32
|
+
/** Field of the document to find distinct values for. */
|
|
33
|
+
key: string;
|
|
34
|
+
/** The query for filtering the set of documents to which we apply the distinct filter. */
|
|
35
|
+
query: Document;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Construct a Distinct operation.
|
|
39
|
+
*
|
|
40
|
+
* @param collection - Collection instance.
|
|
41
|
+
* @param key - Field of the document to find distinct values for.
|
|
42
|
+
* @param query - The query for filtering the set of documents to which we apply the distinct filter.
|
|
43
|
+
* @param options - Optional settings. See Collection.prototype.distinct for a list of options.
|
|
44
|
+
*/
|
|
45
|
+
constructor(collection: Collection, key: string, query: Document, options?: DistinctOptions) {
|
|
46
|
+
super(collection, options);
|
|
47
|
+
|
|
48
|
+
this.options = options ?? {};
|
|
49
|
+
this.collection = collection;
|
|
50
|
+
this.key = key;
|
|
51
|
+
this.query = query;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
override get commandName() {
|
|
55
|
+
return 'distinct' as const;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override buildCommandDocument(_connection: Connection): Document {
|
|
59
|
+
const command: Document = {
|
|
60
|
+
distinct: this.collection.collectionName,
|
|
61
|
+
key: this.key,
|
|
62
|
+
query: this.query
|
|
63
|
+
};
|
|
64
|
+
// we check for undefined specifically here to allow falsy values
|
|
65
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
66
|
+
if (this.options.comment !== undefined) {
|
|
67
|
+
command.comment = this.options.comment;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (this.options.hint != null) {
|
|
71
|
+
command.hint = this.options.hint;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return command;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
override handleOk(
|
|
78
|
+
response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>
|
|
79
|
+
): any[] | Document {
|
|
80
|
+
if (this.explain) {
|
|
81
|
+
return response.toObject(this.bsonOptions);
|
|
82
|
+
}
|
|
83
|
+
return response.toObject(this.bsonOptions).values;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
defineAspects(DistinctOperation, [
|
|
88
|
+
Aspect.READ_OPERATION,
|
|
89
|
+
Aspect.RETRYABLE,
|
|
90
|
+
Aspect.EXPLAINABLE,
|
|
91
|
+
Aspect.SUPPORTS_RAW_DATA
|
|
92
|
+
]);
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type Connection, type MongoError, MongoServerError } from '..';
|
|
2
|
+
import type { Document } from '../bson';
|
|
3
|
+
import { MongoDBResponse } from '../cmap/wire_protocol/responses';
|
|
4
|
+
import { CursorTimeoutContext } from '../cursor/abstract_cursor';
|
|
5
|
+
import type { Db } from '../db';
|
|
6
|
+
import { MONGODB_ERROR_CODES } from '../error';
|
|
7
|
+
import type { ClientSession } from '../sessions';
|
|
8
|
+
import { TimeoutContext } from '../timeout';
|
|
9
|
+
import { CommandOperation, type CommandOperationOptions } from './command';
|
|
10
|
+
import { executeOperation } from './execute_operation';
|
|
11
|
+
import { Aspect, defineAspects } from './operation';
|
|
12
|
+
|
|
13
|
+
/** @public */
|
|
14
|
+
export interface DropCollectionOptions extends Omit<CommandOperationOptions, 'rawData'> {
|
|
15
|
+
/** @experimental */
|
|
16
|
+
encryptedFields?: Document;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @internal */
|
|
20
|
+
export class DropCollectionOperation extends CommandOperation<boolean> {
|
|
21
|
+
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
|
|
22
|
+
|
|
23
|
+
override options: DropCollectionOptions;
|
|
24
|
+
name: string;
|
|
25
|
+
|
|
26
|
+
constructor(db: Db, name: string, options: DropCollectionOptions = {}) {
|
|
27
|
+
super(db, options);
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.name = name;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override get commandName() {
|
|
33
|
+
return 'drop' as const;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
|
|
37
|
+
return { drop: this.name };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): boolean {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override handleError(error: MongoError): boolean {
|
|
45
|
+
if (!(error instanceof MongoServerError)) throw error;
|
|
46
|
+
if (Number(error.code) !== MONGODB_ERROR_CODES.NamespaceNotFound) throw error;
|
|
47
|
+
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function dropCollections(
|
|
53
|
+
db: Db,
|
|
54
|
+
name: string,
|
|
55
|
+
options: DropCollectionOptions
|
|
56
|
+
): Promise<boolean> {
|
|
57
|
+
const timeoutContext = TimeoutContext.create({
|
|
58
|
+
session: options.session,
|
|
59
|
+
serverSelectionTimeoutMS: db.client.s.options.serverSelectionTimeoutMS,
|
|
60
|
+
waitQueueTimeoutMS: db.client.s.options.waitQueueTimeoutMS,
|
|
61
|
+
timeoutMS: options.timeoutMS
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const encryptedFieldsMap = db.client.s.options.autoEncryption?.encryptedFieldsMap;
|
|
65
|
+
let encryptedFields: Document | undefined =
|
|
66
|
+
options.encryptedFields ?? encryptedFieldsMap?.[`${db.databaseName}.${name}`];
|
|
67
|
+
|
|
68
|
+
if (!encryptedFields && encryptedFieldsMap) {
|
|
69
|
+
// If the MongoClient was configured with an encryptedFieldsMap,
|
|
70
|
+
// and no encryptedFields config was available in it or explicitly
|
|
71
|
+
// passed as an argument, the spec tells us to look one up using
|
|
72
|
+
// listCollections().
|
|
73
|
+
const listCollectionsResult = await db
|
|
74
|
+
.listCollections(
|
|
75
|
+
{ name },
|
|
76
|
+
{
|
|
77
|
+
nameOnly: false,
|
|
78
|
+
session: options.session,
|
|
79
|
+
timeoutContext: new CursorTimeoutContext(timeoutContext, Symbol())
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
.toArray();
|
|
83
|
+
encryptedFields = listCollectionsResult?.[0]?.options?.encryptedFields;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (encryptedFields) {
|
|
87
|
+
const escCollection = encryptedFields.escCollection || `enxcol_.${name}.esc`;
|
|
88
|
+
const ecocCollection = encryptedFields.ecocCollection || `enxcol_.${name}.ecoc`;
|
|
89
|
+
|
|
90
|
+
for (const collectionName of [escCollection, ecocCollection]) {
|
|
91
|
+
// Drop auxilliary collections, ignoring potential NamespaceNotFound errors.
|
|
92
|
+
const dropOp = new DropCollectionOperation(db, collectionName, options);
|
|
93
|
+
await executeOperation(db.client, dropOp, timeoutContext);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return await executeOperation(
|
|
98
|
+
db.client,
|
|
99
|
+
new DropCollectionOperation(db, name, options),
|
|
100
|
+
timeoutContext
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** @public */
|
|
105
|
+
export type DropDatabaseOptions = CommandOperationOptions;
|
|
106
|
+
|
|
107
|
+
/** @internal */
|
|
108
|
+
export class DropDatabaseOperation extends CommandOperation<boolean> {
|
|
109
|
+
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
|
|
110
|
+
override options: DropDatabaseOptions;
|
|
111
|
+
|
|
112
|
+
constructor(db: Db, options: DropDatabaseOptions) {
|
|
113
|
+
super(db, options);
|
|
114
|
+
this.options = options;
|
|
115
|
+
}
|
|
116
|
+
override get commandName() {
|
|
117
|
+
return 'dropDatabase' as const;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
|
|
121
|
+
return { dropDatabase: 1 };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): boolean {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
defineAspects(DropCollectionOperation, [Aspect.WRITE_OPERATION]);
|
|
130
|
+
defineAspects(DropDatabaseOperation, [Aspect.WRITE_OPERATION]);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ClientSession,
|
|
3
|
+
type Connection,
|
|
4
|
+
type ServerCommandOptions,
|
|
5
|
+
type ServerSessionId,
|
|
6
|
+
type TimeoutContext,
|
|
7
|
+
type WriteConcern
|
|
8
|
+
} from '..';
|
|
9
|
+
import { type Document } from '../bson';
|
|
10
|
+
import { MongoDBResponse } from '../cmap/wire_protocol/responses';
|
|
11
|
+
import { CommandOperation } from '../operations/command';
|
|
12
|
+
import { ReadPreference } from '../read_preference';
|
|
13
|
+
import { MongoDBNamespace } from '../utils';
|
|
14
|
+
import { Aspect, defineAspects } from './operation';
|
|
15
|
+
|
|
16
|
+
export class EndSessionsOperation extends CommandOperation<void> {
|
|
17
|
+
override writeConcern: WriteConcern = { w: 0 };
|
|
18
|
+
override ns = MongoDBNamespace.fromString('admin.$cmd');
|
|
19
|
+
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
|
|
20
|
+
|
|
21
|
+
private sessions: Array<ServerSessionId>;
|
|
22
|
+
|
|
23
|
+
constructor(sessions: Array<ServerSessionId>) {
|
|
24
|
+
super();
|
|
25
|
+
this.sessions = sessions;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
|
|
29
|
+
return {
|
|
30
|
+
endSessions: this.sessions
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
|
|
34
|
+
return {
|
|
35
|
+
timeoutContext,
|
|
36
|
+
readPreference: ReadPreference.primaryPreferred
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
override get commandName(): string {
|
|
40
|
+
return 'endSessions';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
defineAspects(EndSessionsOperation, Aspect.WRITE_OPERATION);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type Connection } from '..';
|
|
2
|
+
import type { Document } from '../bson';
|
|
3
|
+
import { MongoDBResponse } from '../cmap/wire_protocol/responses';
|
|
4
|
+
import type { Collection } from '../collection';
|
|
5
|
+
import type { ClientSession } from '../sessions';
|
|
6
|
+
import { CommandOperation, type CommandOperationOptions } from './command';
|
|
7
|
+
import { Aspect, defineAspects } from './operation';
|
|
8
|
+
|
|
9
|
+
/** @public */
|
|
10
|
+
export interface EstimatedDocumentCountOptions extends CommandOperationOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The maximum amount of time to allow the operation to run.
|
|
13
|
+
*
|
|
14
|
+
* This option is sent only if the caller explicitly provides a value. The default is to not send a value.
|
|
15
|
+
*/
|
|
16
|
+
maxTimeMS?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @internal */
|
|
20
|
+
export class EstimatedDocumentCountOperation extends CommandOperation<number> {
|
|
21
|
+
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
|
|
22
|
+
override options: EstimatedDocumentCountOptions;
|
|
23
|
+
collectionName: string;
|
|
24
|
+
|
|
25
|
+
constructor(collection: Collection, options: EstimatedDocumentCountOptions = {}) {
|
|
26
|
+
super(collection, options);
|
|
27
|
+
this.options = options;
|
|
28
|
+
this.collectionName = collection.collectionName;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override get commandName() {
|
|
32
|
+
return 'count' as const;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
|
|
36
|
+
const cmd: Document = { count: this.collectionName };
|
|
37
|
+
|
|
38
|
+
if (typeof this.options.maxTimeMS === 'number') {
|
|
39
|
+
cmd.maxTimeMS = this.options.maxTimeMS;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// we check for undefined specifically here to allow falsy values
|
|
43
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
44
|
+
if (this.options.comment !== undefined) {
|
|
45
|
+
cmd.comment = this.options.comment;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return cmd;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): number {
|
|
52
|
+
return response.getNumber('n') ?? 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
defineAspects(EstimatedDocumentCountOperation, [
|
|
57
|
+
Aspect.READ_OPERATION,
|
|
58
|
+
Aspect.RETRYABLE,
|
|
59
|
+
Aspect.CURSOR_CREATING,
|
|
60
|
+
Aspect.SUPPORTS_RAW_DATA
|
|
61
|
+
]);
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { MIN_SUPPORTED_SNAPSHOT_READS_WIRE_VERSION } from '../cmap/wire_protocol/constants';
|
|
2
|
+
import {
|
|
3
|
+
isRetryableReadError,
|
|
4
|
+
isRetryableWriteError,
|
|
5
|
+
MongoCompatibilityError,
|
|
6
|
+
MONGODB_ERROR_CODES,
|
|
7
|
+
MongoError,
|
|
8
|
+
MongoErrorLabel,
|
|
9
|
+
MongoExpiredSessionError,
|
|
10
|
+
MongoInvalidArgumentError,
|
|
11
|
+
MongoNetworkError,
|
|
12
|
+
MongoNotConnectedError,
|
|
13
|
+
MongoRuntimeError,
|
|
14
|
+
MongoServerError,
|
|
15
|
+
MongoTransactionError,
|
|
16
|
+
MongoUnexpectedServerResponseError
|
|
17
|
+
} from '../error';
|
|
18
|
+
import type { MongoClient } from '../mongo_client';
|
|
19
|
+
import { ReadPreference } from '../read_preference';
|
|
20
|
+
import {
|
|
21
|
+
DeprioritizedServers,
|
|
22
|
+
sameServerSelector,
|
|
23
|
+
secondaryWritableServerSelector,
|
|
24
|
+
type ServerSelector
|
|
25
|
+
} from '../sdam/server_selection';
|
|
26
|
+
import type { Topology } from '../sdam/topology';
|
|
27
|
+
import type { ClientSession } from '../sessions';
|
|
28
|
+
import { TimeoutContext } from '../timeout';
|
|
29
|
+
import { abortable, maxWireVersion, supportsRetryableWrites } from '../utils';
|
|
30
|
+
import { AggregateOperation } from './aggregate';
|
|
31
|
+
import { AbstractOperation, Aspect } from './operation';
|
|
32
|
+
|
|
33
|
+
const MMAPv1_RETRY_WRITES_ERROR_CODE = MONGODB_ERROR_CODES.IllegalOperation;
|
|
34
|
+
const MMAPv1_RETRY_WRITES_ERROR_MESSAGE =
|
|
35
|
+
'This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.';
|
|
36
|
+
|
|
37
|
+
type ResultTypeFromOperation<TOperation extends AbstractOperation> = ReturnType<
|
|
38
|
+
TOperation['handleOk']
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Executes the given operation with provided arguments.
|
|
43
|
+
* @internal
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* Allows for a single point of entry to provide features such as implicit sessions, which
|
|
47
|
+
* are required by the Driver Sessions specification in the event that a ClientSession is
|
|
48
|
+
* not provided.
|
|
49
|
+
*
|
|
50
|
+
* The expectation is that this function:
|
|
51
|
+
* - Connects the MongoClient if it has not already been connected, see {@link autoConnect}
|
|
52
|
+
* - Creates a session if none is provided and cleans up the session it creates
|
|
53
|
+
* - Tries an operation and retries under certain conditions, see {@link tryOperation}
|
|
54
|
+
*
|
|
55
|
+
* @typeParam T - The operation's type
|
|
56
|
+
* @typeParam TResult - The type of the operation's result, calculated from T
|
|
57
|
+
*
|
|
58
|
+
* @param client - The MongoClient to execute this operation with
|
|
59
|
+
* @param operation - The operation to execute
|
|
60
|
+
*/
|
|
61
|
+
export async function executeOperation<
|
|
62
|
+
T extends AbstractOperation,
|
|
63
|
+
TResult = ResultTypeFromOperation<T>
|
|
64
|
+
>(client: MongoClient, operation: T, timeoutContext?: TimeoutContext | null): Promise<TResult> {
|
|
65
|
+
if (!(operation instanceof AbstractOperation)) {
|
|
66
|
+
// TODO(NODE-3483): Extend MongoRuntimeError
|
|
67
|
+
throw new MongoRuntimeError('This method requires a valid operation instance');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const topology =
|
|
71
|
+
client.topology == null
|
|
72
|
+
? await abortable(autoConnect(client), operation.options)
|
|
73
|
+
: client.topology;
|
|
74
|
+
|
|
75
|
+
// The driver sessions spec mandates that we implicitly create sessions for operations
|
|
76
|
+
// that are not explicitly provided with a session.
|
|
77
|
+
let session = operation.session;
|
|
78
|
+
let owner: symbol | undefined;
|
|
79
|
+
|
|
80
|
+
if (session == null) {
|
|
81
|
+
owner = Symbol();
|
|
82
|
+
session = client.startSession({ owner, explicit: false });
|
|
83
|
+
} else if (session.hasEnded) {
|
|
84
|
+
throw new MongoExpiredSessionError('Use of expired sessions is not permitted');
|
|
85
|
+
} else if (
|
|
86
|
+
session.snapshotEnabled &&
|
|
87
|
+
maxWireVersion(topology) < MIN_SUPPORTED_SNAPSHOT_READS_WIRE_VERSION
|
|
88
|
+
) {
|
|
89
|
+
throw new MongoCompatibilityError('Snapshot reads require MongoDB 5.0 or later');
|
|
90
|
+
} else if (session.client !== client) {
|
|
91
|
+
throw new MongoInvalidArgumentError('ClientSession must be from the same MongoClient');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
operation.session ??= session;
|
|
95
|
+
|
|
96
|
+
const readPreference = operation.readPreference ?? ReadPreference.primary;
|
|
97
|
+
const inTransaction = !!session?.inTransaction();
|
|
98
|
+
|
|
99
|
+
const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
inTransaction &&
|
|
103
|
+
!readPreference.equals(ReadPreference.primary) &&
|
|
104
|
+
(hasReadAspect || operation.commandName === 'runCommand')
|
|
105
|
+
) {
|
|
106
|
+
throw new MongoTransactionError(
|
|
107
|
+
`Read preference in a transaction must be primary, not: ${readPreference.mode}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (session?.isPinned && session.transaction.isCommitted && !operation.bypassPinningCheck) {
|
|
112
|
+
session.unpin();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
timeoutContext ??= TimeoutContext.create({
|
|
116
|
+
session,
|
|
117
|
+
serverSelectionTimeoutMS: client.s.options.serverSelectionTimeoutMS,
|
|
118
|
+
waitQueueTimeoutMS: client.s.options.waitQueueTimeoutMS,
|
|
119
|
+
timeoutMS: operation.options.timeoutMS
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
return await tryOperation(operation, {
|
|
124
|
+
topology,
|
|
125
|
+
timeoutContext,
|
|
126
|
+
session,
|
|
127
|
+
readPreference
|
|
128
|
+
});
|
|
129
|
+
} finally {
|
|
130
|
+
if (session?.owner != null && session.owner === owner) {
|
|
131
|
+
await session.endSession();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Connects a client if it has not yet been connected
|
|
138
|
+
* @internal
|
|
139
|
+
*/
|
|
140
|
+
export async function autoConnect(client: MongoClient): Promise<Topology> {
|
|
141
|
+
if (client.topology == null) {
|
|
142
|
+
if (client.s.hasBeenClosed) {
|
|
143
|
+
throw new MongoNotConnectedError('Client must be connected before running operations');
|
|
144
|
+
}
|
|
145
|
+
client.s.options.__skipPingOnConnect = true;
|
|
146
|
+
try {
|
|
147
|
+
await client.connect();
|
|
148
|
+
if (client.topology == null) {
|
|
149
|
+
throw new MongoRuntimeError(
|
|
150
|
+
'client.connect did not create a topology but also did not throw'
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
return client.topology;
|
|
154
|
+
} finally {
|
|
155
|
+
delete client.s.options.__skipPingOnConnect;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return client.topology;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** @internal */
|
|
162
|
+
type RetryOptions = {
|
|
163
|
+
session: ClientSession | undefined;
|
|
164
|
+
readPreference: ReadPreference;
|
|
165
|
+
topology: Topology;
|
|
166
|
+
timeoutContext: TimeoutContext;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Executes an operation and retries as appropriate
|
|
171
|
+
* @internal
|
|
172
|
+
*
|
|
173
|
+
* @remarks
|
|
174
|
+
* Implements behaviour described in [Retryable Reads](https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.md) and [Retryable
|
|
175
|
+
* Writes](https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.md) specification
|
|
176
|
+
*
|
|
177
|
+
* This function:
|
|
178
|
+
* - performs initial server selection
|
|
179
|
+
* - attempts to execute an operation
|
|
180
|
+
* - retries the operation if it meets the criteria for a retryable read or a retryable write
|
|
181
|
+
*
|
|
182
|
+
* @typeParam T - The operation's type
|
|
183
|
+
* @typeParam TResult - The type of the operation's result, calculated from T
|
|
184
|
+
*
|
|
185
|
+
* @param operation - The operation to execute
|
|
186
|
+
* */
|
|
187
|
+
async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFromOperation<T>>(
|
|
188
|
+
operation: T,
|
|
189
|
+
{ topology, timeoutContext, session, readPreference }: RetryOptions
|
|
190
|
+
): Promise<TResult> {
|
|
191
|
+
let selector: ReadPreference | ServerSelector;
|
|
192
|
+
|
|
193
|
+
if (operation.hasAspect(Aspect.MUST_SELECT_SAME_SERVER)) {
|
|
194
|
+
// GetMore and KillCursor operations must always select the same server, but run through
|
|
195
|
+
// server selection to potentially force monitor checks if the server is
|
|
196
|
+
// in an unknown state.
|
|
197
|
+
selector = sameServerSelector(operation.server?.description);
|
|
198
|
+
} else if (operation instanceof AggregateOperation && operation.hasWriteStage) {
|
|
199
|
+
// If operation should try to write to secondary use the custom server selector
|
|
200
|
+
// otherwise provide the read preference.
|
|
201
|
+
selector = secondaryWritableServerSelector(topology.commonWireVersion, readPreference);
|
|
202
|
+
} else {
|
|
203
|
+
selector = readPreference;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let server = await topology.selectServer(selector, {
|
|
207
|
+
session,
|
|
208
|
+
operationName: operation.commandName,
|
|
209
|
+
timeoutContext,
|
|
210
|
+
signal: operation.options.signal,
|
|
211
|
+
deprioritizedServers: new DeprioritizedServers()
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);
|
|
215
|
+
const hasWriteAspect = operation.hasAspect(Aspect.WRITE_OPERATION);
|
|
216
|
+
const inTransaction = session?.inTransaction() ?? false;
|
|
217
|
+
|
|
218
|
+
const willRetryRead = topology.s.options.retryReads && !inTransaction && operation.canRetryRead;
|
|
219
|
+
|
|
220
|
+
const willRetryWrite =
|
|
221
|
+
topology.s.options.retryWrites &&
|
|
222
|
+
!inTransaction &&
|
|
223
|
+
supportsRetryableWrites(server) &&
|
|
224
|
+
operation.canRetryWrite;
|
|
225
|
+
|
|
226
|
+
const willRetry =
|
|
227
|
+
operation.hasAspect(Aspect.RETRYABLE) &&
|
|
228
|
+
session != null &&
|
|
229
|
+
((hasReadAspect && willRetryRead) || (hasWriteAspect && willRetryWrite));
|
|
230
|
+
|
|
231
|
+
if (hasWriteAspect && willRetryWrite && session != null) {
|
|
232
|
+
operation.options.willRetryWrite = true;
|
|
233
|
+
session.incrementTransactionNumber();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const maxTries = willRetry ? (timeoutContext.csotEnabled() ? Infinity : 2) : 1;
|
|
237
|
+
let previousOperationError: MongoError | undefined;
|
|
238
|
+
const deprioritizedServers = new DeprioritizedServers();
|
|
239
|
+
|
|
240
|
+
for (let tries = 0; tries < maxTries; tries++) {
|
|
241
|
+
if (previousOperationError) {
|
|
242
|
+
if (hasWriteAspect && previousOperationError.code === MMAPv1_RETRY_WRITES_ERROR_CODE) {
|
|
243
|
+
throw new MongoServerError({
|
|
244
|
+
message: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
|
|
245
|
+
errmsg: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
|
|
246
|
+
originalError: previousOperationError
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (operation.hasAspect(Aspect.COMMAND_BATCHING) && !operation.canRetryWrite) {
|
|
251
|
+
throw previousOperationError;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (hasWriteAspect && !isRetryableWriteError(previousOperationError))
|
|
255
|
+
throw previousOperationError;
|
|
256
|
+
|
|
257
|
+
if (hasReadAspect && !isRetryableReadError(previousOperationError)) {
|
|
258
|
+
throw previousOperationError;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (
|
|
262
|
+
previousOperationError instanceof MongoNetworkError &&
|
|
263
|
+
operation.hasAspect(Aspect.CURSOR_CREATING) &&
|
|
264
|
+
session != null &&
|
|
265
|
+
session.isPinned &&
|
|
266
|
+
!session.inTransaction()
|
|
267
|
+
) {
|
|
268
|
+
session.unpin({ force: true, forceClear: true });
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
server = await topology.selectServer(selector, {
|
|
272
|
+
session,
|
|
273
|
+
operationName: operation.commandName,
|
|
274
|
+
deprioritizedServers,
|
|
275
|
+
signal: operation.options.signal
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
if (hasWriteAspect && !supportsRetryableWrites(server)) {
|
|
279
|
+
throw new MongoUnexpectedServerResponseError(
|
|
280
|
+
'Selected server does not support retryable writes'
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
operation.server = server;
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
// If tries > 0 and we are command batching we need to reset the batch.
|
|
289
|
+
if (tries > 0 && operation.hasAspect(Aspect.COMMAND_BATCHING)) {
|
|
290
|
+
operation.resetBatch();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
const result = await server.command(operation, timeoutContext);
|
|
295
|
+
return operation.handleOk(result);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
return operation.handleError(error);
|
|
298
|
+
}
|
|
299
|
+
} catch (operationError) {
|
|
300
|
+
if (!(operationError instanceof MongoError)) throw operationError;
|
|
301
|
+
if (
|
|
302
|
+
previousOperationError != null &&
|
|
303
|
+
operationError.hasErrorLabel(MongoErrorLabel.NoWritesPerformed)
|
|
304
|
+
) {
|
|
305
|
+
throw previousOperationError;
|
|
306
|
+
}
|
|
307
|
+
deprioritizedServers.add(server.description);
|
|
308
|
+
previousOperationError = operationError;
|
|
309
|
+
|
|
310
|
+
// Reset timeouts
|
|
311
|
+
timeoutContext.clear();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
throw (
|
|
316
|
+
previousOperationError ??
|
|
317
|
+
new MongoRuntimeError('Tried to propagate retryability error, but no error was found.')
|
|
318
|
+
);
|
|
319
|
+
}
|