mongo 2.19.1 → 2.21.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.
- checksums.yaml +4 -4
- data/README.md +40 -1
- data/Rakefile +83 -174
- data/lib/mongo/address.rb +22 -3
- data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
- data/lib/mongo/auth/base.rb +1 -1
- data/lib/mongo/bulk_write.rb +35 -2
- data/lib/mongo/client.rb +38 -6
- data/lib/mongo/client_encryption.rb +6 -3
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
- data/lib/mongo/cluster/sdam_flow.rb +20 -7
- data/lib/mongo/cluster/topology/base.rb +16 -0
- data/lib/mongo/cluster.rb +41 -5
- data/lib/mongo/collection/helpers.rb +1 -1
- data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
- data/lib/mongo/collection/view/aggregation.rb +33 -99
- data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
- data/lib/mongo/collection/view/change_stream.rb +80 -27
- data/lib/mongo/collection/view/iterable.rb +92 -60
- data/lib/mongo/collection/view/map_reduce.rb +25 -8
- data/lib/mongo/collection/view/readable.rb +79 -30
- data/lib/mongo/collection/view/writable.rb +109 -48
- data/lib/mongo/collection/view.rb +44 -3
- data/lib/mongo/collection.rb +185 -26
- data/lib/mongo/config.rb +2 -2
- data/lib/mongo/crypt/auto_encrypter.rb +4 -6
- data/lib/mongo/crypt/binding.rb +4 -4
- data/lib/mongo/crypt/context.rb +20 -14
- data/lib/mongo/crypt/encryption_io.rb +56 -26
- data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
- data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
- data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
- data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
- data/lib/mongo/csot_timeout_holder.rb +119 -0
- data/lib/mongo/cursor/kill_spec.rb +5 -2
- data/lib/mongo/cursor/nontailable.rb +27 -0
- data/lib/mongo/cursor.rb +86 -24
- data/lib/mongo/cursor_host.rb +82 -0
- data/lib/mongo/database/view.rb +81 -14
- data/lib/mongo/database.rb +88 -18
- data/lib/mongo/error/operation_failure.rb +209 -204
- data/lib/mongo/error/server_timeout_error.rb +12 -0
- data/lib/mongo/error/socket_timeout_error.rb +3 -1
- data/lib/mongo/error/timeout_error.rb +23 -0
- data/lib/mongo/error/transactions_not_supported.rb +34 -0
- data/lib/mongo/error.rb +3 -0
- data/lib/mongo/grid/fs_bucket.rb +48 -9
- data/lib/mongo/grid/stream/read.rb +15 -1
- data/lib/mongo/grid/stream/write.rb +21 -4
- data/lib/mongo/index/view.rb +77 -16
- data/lib/mongo/monitoring/event/secure.rb +1 -1
- data/lib/mongo/operation/context.rb +40 -2
- data/lib/mongo/operation/create_search_indexes/op_msg.rb +31 -0
- data/lib/mongo/operation/create_search_indexes.rb +15 -0
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/drop_search_index/op_msg.rb +33 -0
- data/lib/mongo/operation/drop_search_index.rb +15 -0
- data/lib/mongo/operation/find/op_msg.rb +45 -0
- data/lib/mongo/operation/get_more/op_msg.rb +33 -0
- data/lib/mongo/operation/insert/op_msg.rb +3 -2
- data/lib/mongo/operation/insert/result.rb +4 -2
- data/lib/mongo/operation/list_collections/result.rb +1 -1
- data/lib/mongo/operation/map_reduce/result.rb +1 -1
- data/lib/mongo/operation/op_msg_base.rb +3 -1
- data/lib/mongo/operation/result.rb +26 -5
- data/lib/mongo/operation/shared/executable.rb +55 -28
- data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
- data/lib/mongo/operation/shared/response_handling.rb +25 -27
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
- data/lib/mongo/operation/shared/specifiable.rb +7 -0
- data/lib/mongo/operation/shared/timed.rb +52 -0
- data/lib/mongo/operation/shared/write.rb +4 -1
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/operation/update_search_index/op_msg.rb +34 -0
- data/lib/mongo/operation/update_search_index.rb +15 -0
- data/lib/mongo/operation.rb +4 -0
- data/lib/mongo/protocol/message.rb +1 -4
- data/lib/mongo/protocol/msg.rb +2 -2
- data/lib/mongo/retryable/base_worker.rb +28 -3
- data/lib/mongo/retryable/read_worker.rb +78 -36
- data/lib/mongo/retryable/write_worker.rb +59 -25
- data/lib/mongo/retryable.rb +8 -2
- data/lib/mongo/search_index/view.rb +232 -0
- data/lib/mongo/server/app_metadata/environment.rb +64 -9
- data/lib/mongo/server/app_metadata.rb +5 -4
- data/lib/mongo/server/connection.rb +11 -5
- data/lib/mongo/server/connection_base.rb +22 -2
- data/lib/mongo/server/connection_pool.rb +32 -14
- data/lib/mongo/server/description/features.rb +2 -1
- data/lib/mongo/server/description.rb +18 -5
- data/lib/mongo/server/monitor.rb +7 -4
- data/lib/mongo/server/pending_connection.rb +25 -8
- data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
- data/lib/mongo/server.rb +11 -6
- data/lib/mongo/server_selector/base.rb +54 -12
- data/lib/mongo/session/server_session/dirtyable.rb +52 -0
- data/lib/mongo/session/server_session.rb +3 -0
- data/lib/mongo/session/session_pool.rb +12 -18
- data/lib/mongo/session.rb +110 -9
- data/lib/mongo/socket/ssl.rb +131 -18
- data/lib/mongo/socket/tcp.rb +40 -6
- data/lib/mongo/socket.rb +154 -25
- data/lib/mongo/uri/options_mapper.rb +1 -0
- data/lib/mongo/uri.rb +0 -4
- data/lib/mongo/version.rb +1 -5
- data/lib/mongo.rb +2 -0
- data/mongo.gemspec +9 -18
- data/spec/atlas/atlas_connectivity_spec.rb +9 -9
- data/spec/atlas/operations_spec.rb +5 -5
- data/spec/faas/ruby-sam-app/Gemfile +9 -0
- data/spec/faas/ruby-sam-app/mongodb/Gemfile +4 -0
- data/spec/faas/ruby-sam-app/mongodb/app.rb +149 -0
- data/spec/faas/ruby-sam-app/template.yaml +48 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
- data/spec/integration/client_side_encryption/corpus_spec.rb +10 -2
- data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
- data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +67 -20
- data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
- data/spec/integration/connection_pool_populator_spec.rb +2 -0
- data/spec/integration/cursor_pinning_spec.rb +15 -60
- data/spec/integration/cursor_reaping_spec.rb +1 -1
- data/spec/integration/docs_examples_spec.rb +1 -1
- data/spec/integration/find_options_spec.rb +227 -0
- data/spec/integration/operation_failure_code_spec.rb +1 -1
- data/spec/integration/operation_failure_message_spec.rb +3 -3
- data/spec/integration/retryable_errors_spec.rb +2 -2
- data/spec/integration/retryable_reads_errors_spec.rb +196 -31
- data/spec/integration/retryable_writes_errors_spec.rb +156 -0
- data/spec/integration/sdam_error_handling_spec.rb +4 -1
- data/spec/integration/search_indexes_prose_spec.rb +172 -0
- data/spec/integration/server_spec.rb +4 -3
- data/spec/integration/transactions_api_examples_spec.rb +2 -0
- data/spec/kerberos/kerberos_spec.rb +4 -0
- data/spec/lite_spec_helper.rb +34 -20
- data/spec/mongo/auth/user/view_spec.rb +1 -1
- data/spec/mongo/caching_cursor_spec.rb +1 -1
- data/spec/mongo/client_encryption_spec.rb +1 -0
- data/spec/mongo/client_spec.rb +158 -4
- data/spec/mongo/cluster_spec.rb +36 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +20 -40
- data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
- data/spec/mongo/collection/view/explainable_spec.rb +2 -0
- data/spec/mongo/collection_crud_spec.rb +2 -1
- data/spec/mongo/collection_spec.rb +5 -6
- data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
- data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
- data/spec/mongo/crypt/handle_spec.rb +1 -1
- data/spec/mongo/cursor_spec.rb +26 -9
- data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
- data/spec/mongo/operation/context_spec.rb +79 -0
- data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
- data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
- data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
- data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
- data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
- data/spec/mongo/operation/insert_spec.rb +1 -1
- data/spec/mongo/operation/shared/csot/examples.rb +113 -0
- data/spec/mongo/query_cache_spec.rb +243 -225
- data/spec/mongo/retryable/write_worker_spec.rb +39 -0
- data/spec/mongo/retryable_spec.rb +1 -0
- data/spec/mongo/server/app_metadata/environment_spec.rb +135 -0
- data/spec/mongo/server/app_metadata_spec.rb +12 -2
- data/spec/mongo/server/connection_spec.rb +26 -0
- data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
- data/spec/mongo/session/session_pool_spec.rb +1 -16
- data/spec/mongo/session_transaction_spec.rb +15 -0
- data/spec/mongo/socket/ssl_spec.rb +0 -10
- data/spec/mongo/uri_spec.rb +0 -9
- data/spec/runners/change_streams/test.rb +2 -2
- data/spec/runners/crud/operation.rb +1 -1
- data/spec/runners/crud/test.rb +0 -8
- data/spec/runners/crud/verifier.rb +3 -1
- data/spec/runners/crud.rb +1 -1
- data/spec/runners/transactions/operation.rb +4 -6
- data/spec/runners/transactions/test.rb +12 -3
- data/spec/runners/unified/ambiguous_operations.rb +13 -0
- data/spec/runners/unified/assertions.rb +20 -3
- data/spec/runners/unified/change_stream_operations.rb +14 -24
- data/spec/runners/unified/crud_operations.rb +82 -47
- data/spec/runners/unified/ddl_operations.rb +38 -7
- data/spec/runners/unified/grid_fs_operations.rb +37 -2
- data/spec/runners/unified/search_index_operations.rb +63 -0
- data/spec/runners/unified/support_operations.rb +46 -9
- data/spec/runners/unified/test.rb +33 -12
- data/spec/runners/unified.rb +1 -1
- data/spec/solo/clean_exit_spec.rb +2 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
- data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
- data/spec/spec_tests/data/client_side_encryption/explain.yml +2 -2
- data/spec/spec_tests/data/client_side_encryption/fle2v2-BypassQueryAnalysis.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.yml +2 -1
- data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
- data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
- data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
- data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
- data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
- data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
- data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
- data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
- data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
- data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
- data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
- data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
- data/spec/spec_tests/data/connection_string/invalid-uris.yml +0 -10
- data/spec/spec_tests/data/connection_string/valid-options.yml +13 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +6 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -0
- data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +377 -0
- data/spec/spec_tests/data/index_management/createSearchIndex.yml +64 -0
- data/spec/spec_tests/data/index_management/createSearchIndexes.yml +86 -0
- data/spec/spec_tests/data/index_management/dropSearchIndex.yml +43 -0
- data/spec/spec_tests/data/index_management/listSearchIndexes.yml +91 -0
- data/spec/spec_tests/data/index_management/updateSearchIndex.yml +46 -0
- data/spec/spec_tests/data/retryable_writes/unified/bulkWrite-serverErrors.yml +3 -6
- data/spec/spec_tests/data/retryable_writes/unified/insertOne-serverErrors.yml +3 -6
- data/spec/spec_tests/data/run_command_unified/runCommand.yml +319 -0
- data/spec/spec_tests/data/sessions_unified/driver-sessions-dirty-session-errors.yml +351 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +1 -1
- data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +7 -7
- data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +3 -4
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +1 -1
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +1 -1
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +3 -3
- data/spec/spec_tests/index_management_unified_spec.rb +13 -0
- data/spec/spec_tests/run_command_unified_spec.rb +13 -0
- data/spec/spec_tests/sdam_unified_spec.rb +2 -0
- data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
- data/spec/spec_tests/transactions_unified_spec.rb +2 -1
- data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
- data/spec/support/certificates/atlas-ocsp.crt +117 -122
- data/spec/support/certificates/retrieve-atlas-cert +1 -1
- data/spec/support/cluster_tools.rb +3 -3
- data/spec/support/common_shortcuts.rb +2 -2
- data/spec/support/constraints.rb +6 -0
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
- data/spec/support/ocsp +1 -1
- data/spec/support/recording_logger.rb +27 -0
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_config.rb +5 -0
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/utils.rb +3 -1
- metadata +1329 -1368
- checksums.yaml.gz.sig +0 -0
- data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -378
- data/spec/shared/lib/mrss/docker_runner.rb +0 -295
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
- data/spec/shared/lib/mrss/session_registry.rb +0 -69
- data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -37
- data/spec/shared/share/Dockerfile.erb +0 -330
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/config.sh +0 -27
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -416
- data/spec/shared/shlib/set_env.sh +0 -169
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
- data/spec/spec_tests/data/cmap/pool-clear-interrupt-immediately.yml +0 -49
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -2
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
# See the License for the specific language governing permissions and
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
|
+
require 'mongo/collection/view/aggregation/behavior'
|
|
19
|
+
|
|
18
20
|
module Mongo
|
|
19
21
|
class Collection
|
|
20
22
|
class View
|
|
@@ -23,46 +25,11 @@ module Mongo
|
|
|
23
25
|
#
|
|
24
26
|
# @since 2.0.0
|
|
25
27
|
class Aggregation
|
|
26
|
-
|
|
27
|
-
include Enumerable
|
|
28
|
-
include Immutable
|
|
29
|
-
include Iterable
|
|
30
|
-
include Explainable
|
|
31
|
-
include Loggable
|
|
32
|
-
include Retryable
|
|
28
|
+
include Behavior
|
|
33
29
|
|
|
34
|
-
# @return [ View ] view The collection view.
|
|
35
|
-
attr_reader :view
|
|
36
30
|
# @return [ Array<Hash> ] pipeline The aggregation pipeline.
|
|
37
31
|
attr_reader :pipeline
|
|
38
32
|
|
|
39
|
-
# Delegate necessary operations to the view.
|
|
40
|
-
def_delegators :view, :collection, :read, :cluster
|
|
41
|
-
|
|
42
|
-
# Delegate necessary operations to the collection.
|
|
43
|
-
def_delegators :collection, :database, :client
|
|
44
|
-
|
|
45
|
-
# The reroute message.
|
|
46
|
-
#
|
|
47
|
-
# @since 2.1.0
|
|
48
|
-
# @deprecated
|
|
49
|
-
REROUTE = 'Rerouting the Aggregation operation to the primary server.'.freeze
|
|
50
|
-
|
|
51
|
-
# Set to true if disk usage is allowed during the aggregation.
|
|
52
|
-
#
|
|
53
|
-
# @example Set disk usage flag.
|
|
54
|
-
# aggregation.allow_disk_use(true)
|
|
55
|
-
#
|
|
56
|
-
# @param [ true, false ] value The flag value.
|
|
57
|
-
#
|
|
58
|
-
# @return [ true, false, Aggregation ] The aggregation if a value was
|
|
59
|
-
# set or the value if used as a getter.
|
|
60
|
-
#
|
|
61
|
-
# @since 2.0.0
|
|
62
|
-
def allow_disk_use(value = nil)
|
|
63
|
-
configure(:allow_disk_use, value)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
33
|
# Initialize the aggregation for the provided collection view, pipeline
|
|
67
34
|
# and options.
|
|
68
35
|
#
|
|
@@ -86,59 +53,29 @@ module Mongo
|
|
|
86
53
|
# @option options [ Hash ] :let Mapping of variables to use in the pipeline.
|
|
87
54
|
# See the server documentation for details.
|
|
88
55
|
# @option options [ Integer ] :max_time_ms The maximum amount of time in
|
|
89
|
-
# milliseconds to allow the aggregation to run.
|
|
90
|
-
#
|
|
91
|
-
# will request that the server provide results using a cursor. Note that
|
|
92
|
-
# as of server version 3.6, aggregations always provide results using a
|
|
93
|
-
# cursor and this option is therefore not valid.
|
|
56
|
+
# milliseconds to allow the aggregation to run. This option is deprecated, use
|
|
57
|
+
# :timeout_ms instead.
|
|
94
58
|
# @option options [ Session ] :session The session to use.
|
|
59
|
+
# @option options [ :cursor_lifetime | :iteration ] :timeout_mode How to interpret
|
|
60
|
+
# :timeout_ms (whether it applies to the lifetime of the cursor, or per
|
|
61
|
+
# iteration).
|
|
62
|
+
# @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
|
63
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
|
64
|
+
# The default value is unset which means the value is inherited from
|
|
65
|
+
# the collection or the database or the client.
|
|
95
66
|
#
|
|
96
67
|
# @since 2.0.0
|
|
97
68
|
def initialize(view, pipeline, options = {})
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
69
|
+
perform_setup(view, options) do
|
|
70
|
+
@pipeline = pipeline.dup
|
|
71
|
+
unless Mongo.broken_view_aggregate || view.filter.empty?
|
|
72
|
+
@pipeline.unshift(:$match => view.filter)
|
|
73
|
+
end
|
|
102
74
|
end
|
|
103
|
-
@options = BSON::Document.new(options).freeze
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Get the explain plan for the aggregation.
|
|
107
|
-
#
|
|
108
|
-
# @example Get the explain plan for the aggregation.
|
|
109
|
-
# aggregation.explain
|
|
110
|
-
#
|
|
111
|
-
# @return [ Hash ] The explain plan.
|
|
112
|
-
#
|
|
113
|
-
# @since 2.0.0
|
|
114
|
-
def explain
|
|
115
|
-
self.class.new(view, pipeline, options.merge(explain: true)).first
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Whether this aggregation will write its result to a database collection.
|
|
119
|
-
#
|
|
120
|
-
# @return [ Boolean ] Whether the aggregation will write its result
|
|
121
|
-
# to a collection.
|
|
122
|
-
#
|
|
123
|
-
# @api private
|
|
124
|
-
def write?
|
|
125
|
-
pipeline.any? { |op| op.key?('$out') || op.key?(:$out) || op.key?('$merge') || op.key?(:$merge) }
|
|
126
75
|
end
|
|
127
76
|
|
|
128
77
|
private
|
|
129
78
|
|
|
130
|
-
def server_selector
|
|
131
|
-
@view.send(:server_selector)
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def aggregate_spec(session, read_preference)
|
|
135
|
-
Builder::Aggregation.new(
|
|
136
|
-
pipeline,
|
|
137
|
-
view,
|
|
138
|
-
options.merge(session: session, read_preference: read_preference)
|
|
139
|
-
).specification
|
|
140
|
-
end
|
|
141
|
-
|
|
142
79
|
def new(options)
|
|
143
80
|
Aggregation.new(view, pipeline, options)
|
|
144
81
|
end
|
|
@@ -180,32 +117,29 @@ module Mongo
|
|
|
180
117
|
|
|
181
118
|
end
|
|
182
119
|
|
|
183
|
-
def send_initial_query(server,
|
|
184
|
-
server.
|
|
120
|
+
def send_initial_query(server, context)
|
|
121
|
+
if server.load_balancer?
|
|
122
|
+
# Connection will be checked in when cursor is drained.
|
|
123
|
+
connection = server.pool.check_out(context: context)
|
|
185
124
|
initial_query_op(
|
|
186
|
-
session,
|
|
125
|
+
context.session,
|
|
187
126
|
effective_read_preference(connection)
|
|
188
127
|
).execute_with_connection(
|
|
189
128
|
connection,
|
|
190
|
-
context:
|
|
129
|
+
context: context
|
|
191
130
|
)
|
|
131
|
+
else
|
|
132
|
+
server.with_connection do |connection|
|
|
133
|
+
initial_query_op(
|
|
134
|
+
context.session,
|
|
135
|
+
effective_read_preference(connection)
|
|
136
|
+
).execute_with_connection(
|
|
137
|
+
connection,
|
|
138
|
+
context: context
|
|
139
|
+
)
|
|
140
|
+
end
|
|
192
141
|
end
|
|
193
142
|
end
|
|
194
|
-
|
|
195
|
-
# Skip, sort, limit, projection are specified as pipeline stages
|
|
196
|
-
# rather than as options.
|
|
197
|
-
def cache_options
|
|
198
|
-
{
|
|
199
|
-
namespace: collection.namespace,
|
|
200
|
-
selector: pipeline,
|
|
201
|
-
read_concern: view.read_concern,
|
|
202
|
-
read_preference: view.read_preference,
|
|
203
|
-
collation: options[:collation],
|
|
204
|
-
# Aggregations can read documents from more than one collection,
|
|
205
|
-
# so they will be cleared on every write operation.
|
|
206
|
-
multi_collection: true,
|
|
207
|
-
}
|
|
208
|
-
end
|
|
209
143
|
end
|
|
210
144
|
end
|
|
211
145
|
end
|
|
@@ -113,17 +113,11 @@ module Mongo
|
|
|
113
113
|
command[:readConcern] = Options::Mapper.transform_values_to_strings(
|
|
114
114
|
read_concern)
|
|
115
115
|
end
|
|
116
|
-
command[:cursor] =
|
|
116
|
+
command[:cursor] = batch_size_doc
|
|
117
117
|
command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
|
|
118
118
|
command
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
def cursor
|
|
122
|
-
if options[:use_cursor] == true || options[:use_cursor].nil?
|
|
123
|
-
batch_size_doc
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
121
|
def batch_size_doc
|
|
128
122
|
value = options[:batch_size] || view.batch_size
|
|
129
123
|
if value == 0 && write?
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
# See the License for the specific language governing permissions and
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
|
+
require 'mongo/collection/view/aggregation/behavior'
|
|
18
19
|
require 'mongo/collection/view/change_stream/retryable'
|
|
19
20
|
|
|
20
21
|
module Mongo
|
|
@@ -35,7 +36,8 @@ module Mongo
|
|
|
35
36
|
#
|
|
36
37
|
#
|
|
37
38
|
# @since 2.5.0
|
|
38
|
-
class ChangeStream
|
|
39
|
+
class ChangeStream
|
|
40
|
+
include Aggregation::Behavior
|
|
39
41
|
include Retryable
|
|
40
42
|
|
|
41
43
|
# @return [ String ] The fullDocument option default value.
|
|
@@ -60,6 +62,10 @@ module Mongo
|
|
|
60
62
|
# @since 2.5.0
|
|
61
63
|
attr_reader :options
|
|
62
64
|
|
|
65
|
+
# @return [ Cursor ] the underlying cursor for this operation
|
|
66
|
+
# @api private
|
|
67
|
+
attr_reader :cursor
|
|
68
|
+
|
|
63
69
|
# Initialize the change stream for the provided collection view, pipeline
|
|
64
70
|
# and options.
|
|
65
71
|
#
|
|
@@ -125,11 +131,13 @@ module Mongo
|
|
|
125
131
|
#
|
|
126
132
|
# @since 2.5.0
|
|
127
133
|
def initialize(view, pipeline, changes_for, options = {})
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
# change stream cursors can only be :iterable, so we don't allow
|
|
135
|
+
# timeout_mode to be specified.
|
|
136
|
+
perform_setup(view, options, forbid: %i[ timeout_mode ]) do
|
|
137
|
+
@changes_for = changes_for
|
|
138
|
+
@change_stream_filters = pipeline && pipeline.dup
|
|
139
|
+
@start_after = @options[:start_after]
|
|
140
|
+
end
|
|
133
141
|
|
|
134
142
|
# The resume token tracked by the change stream, used only
|
|
135
143
|
# when there is no cursor, or no cursor resume token
|
|
@@ -181,24 +189,30 @@ module Mongo
|
|
|
181
189
|
# @return [ BSON::Document | nil ] A change stream document.
|
|
182
190
|
# @since 2.6.0
|
|
183
191
|
def try_next
|
|
192
|
+
recreate_cursor! if @timed_out
|
|
193
|
+
|
|
184
194
|
raise StopIteration.new if closed?
|
|
195
|
+
|
|
185
196
|
begin
|
|
186
197
|
doc = @cursor.try_next
|
|
187
198
|
rescue Mongo::Error => e
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
#
|
|
193
|
-
#
|
|
194
|
-
#
|
|
199
|
+
# "If a next call fails with a timeout error, drivers MUST NOT
|
|
200
|
+
# invalidate the change stream. The subsequent next call MUST
|
|
201
|
+
# perform a resume attempt to establish a new change stream on the
|
|
202
|
+
# server..."
|
|
203
|
+
#
|
|
204
|
+
# However, SocketTimeoutErrors are TimeoutErrors, but are also
|
|
205
|
+
# change-stream-resumable. To preserve existing (specified) behavior,
|
|
206
|
+
# We only count timeouts when the error is not also
|
|
207
|
+
# change-stream-resumable.
|
|
208
|
+
@timed_out = e.is_a?(Mongo::Error::TimeoutError) && !e.change_stream_resumable?
|
|
209
|
+
|
|
210
|
+
raise unless @timed_out || e.change_stream_resumable?
|
|
195
211
|
|
|
196
|
-
# Save cursor's resume token so we can use it
|
|
197
|
-
# to create a new cursor
|
|
198
212
|
@resume_token = @cursor.resume_token
|
|
213
|
+
raise e if @timed_out
|
|
199
214
|
|
|
200
|
-
|
|
201
|
-
create_cursor!
|
|
215
|
+
recreate_cursor!(@cursor.context)
|
|
202
216
|
retry
|
|
203
217
|
end
|
|
204
218
|
|
|
@@ -231,14 +245,17 @@ module Mongo
|
|
|
231
245
|
# This method ignores any errors that occur when closing the
|
|
232
246
|
# server-side cursor.
|
|
233
247
|
#
|
|
248
|
+
# @params [ Hash ] opts Options to be passed to the cursor close
|
|
249
|
+
# command.
|
|
250
|
+
#
|
|
234
251
|
# @return [ nil ] Always nil.
|
|
235
252
|
#
|
|
236
253
|
# @since 2.5.0
|
|
237
|
-
def close
|
|
254
|
+
def close(opts = {})
|
|
238
255
|
unless closed?
|
|
239
256
|
begin
|
|
240
|
-
@cursor.close
|
|
241
|
-
rescue Error::OperationFailure, Error::SocketError, Error::SocketTimeoutError, Error::MissingConnection
|
|
257
|
+
@cursor.close(opts)
|
|
258
|
+
rescue Error::OperationFailure::Family, Error::SocketError, Error::SocketTimeoutError, Error::MissingConnection
|
|
242
259
|
# ignore
|
|
243
260
|
end
|
|
244
261
|
@cursor = nil
|
|
@@ -284,6 +301,28 @@ module Mongo
|
|
|
284
301
|
cursor_resume_token || @resume_token
|
|
285
302
|
end
|
|
286
303
|
|
|
304
|
+
# "change streams are an abstraction around tailable-awaitData cursors..."
|
|
305
|
+
#
|
|
306
|
+
# @return :tailable_await
|
|
307
|
+
def cursor_type
|
|
308
|
+
:tailable_await
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# "change streams...implicitly use ITERATION mode"
|
|
312
|
+
#
|
|
313
|
+
# @return :iteration
|
|
314
|
+
def timeout_mode
|
|
315
|
+
:iteration
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Returns the value of the max_await_time_ms option that was
|
|
319
|
+
# passed to this change stream.
|
|
320
|
+
#
|
|
321
|
+
# @return [ Integer | nil ] the max_await_time_ms value
|
|
322
|
+
def max_await_time_ms
|
|
323
|
+
options[:max_await_time_ms]
|
|
324
|
+
end
|
|
325
|
+
|
|
287
326
|
private
|
|
288
327
|
|
|
289
328
|
def for_cluster?
|
|
@@ -298,19 +337,23 @@ module Mongo
|
|
|
298
337
|
!for_cluster? && !for_database?
|
|
299
338
|
end
|
|
300
339
|
|
|
301
|
-
def create_cursor!
|
|
340
|
+
def create_cursor!(timeout_ms = nil)
|
|
302
341
|
# clear the cache because we may get a newer or an older server
|
|
303
342
|
# (rolling upgrades)
|
|
304
343
|
@start_at_operation_time_supported = nil
|
|
305
344
|
|
|
306
|
-
session = client.
|
|
345
|
+
session = client.get_session(@options)
|
|
346
|
+
context = Operation::Context.new(client: client, session: session, view: self, operation_timeouts: timeout_ms ? { operation_timeout_ms: timeout_ms } : operation_timeouts)
|
|
347
|
+
|
|
307
348
|
start_at_operation_time = nil
|
|
308
349
|
start_at_operation_time_supported = nil
|
|
309
|
-
|
|
350
|
+
|
|
351
|
+
@cursor = read_with_retry_cursor(session, server_selector, self, context: context) do |server|
|
|
310
352
|
server.with_connection do |connection|
|
|
311
353
|
start_at_operation_time_supported = connection.description.server_version_gte?('4.0')
|
|
312
354
|
|
|
313
|
-
result = send_initial_query(connection,
|
|
355
|
+
result = send_initial_query(connection, context)
|
|
356
|
+
|
|
314
357
|
if doc = result.replies.first && result.replies.first.documents.first
|
|
315
358
|
start_at_operation_time = doc['operationTime']
|
|
316
359
|
else
|
|
@@ -324,6 +367,7 @@ module Mongo
|
|
|
324
367
|
result
|
|
325
368
|
end
|
|
326
369
|
end
|
|
370
|
+
|
|
327
371
|
@start_at_operation_time = start_at_operation_time
|
|
328
372
|
@start_at_operation_time_supported = start_at_operation_time_supported
|
|
329
373
|
end
|
|
@@ -390,11 +434,11 @@ module Mongo
|
|
|
390
434
|
end
|
|
391
435
|
end
|
|
392
436
|
|
|
393
|
-
def send_initial_query(connection,
|
|
394
|
-
initial_query_op(session, view.read_preference)
|
|
437
|
+
def send_initial_query(connection, context)
|
|
438
|
+
initial_query_op(context.session, view.read_preference)
|
|
395
439
|
.execute_with_connection(
|
|
396
440
|
connection,
|
|
397
|
-
context:
|
|
441
|
+
context: context,
|
|
398
442
|
)
|
|
399
443
|
end
|
|
400
444
|
|
|
@@ -412,6 +456,15 @@ module Mongo
|
|
|
412
456
|
def resuming?
|
|
413
457
|
!!@resuming
|
|
414
458
|
end
|
|
459
|
+
|
|
460
|
+
# Recreates the current cursor (typically as a consequence of attempting
|
|
461
|
+
# to resume the change stream)
|
|
462
|
+
def recreate_cursor!(context = nil)
|
|
463
|
+
@timed_out = false
|
|
464
|
+
|
|
465
|
+
close
|
|
466
|
+
create_cursor!(context&.remaining_timeout_ms)
|
|
467
|
+
end
|
|
415
468
|
end
|
|
416
469
|
end
|
|
417
470
|
end
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
# See the License for the specific language governing permissions and
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
|
+
require 'mongo/cursor_host'
|
|
19
|
+
|
|
18
20
|
module Mongo
|
|
19
21
|
class Collection
|
|
20
22
|
class View
|
|
@@ -24,13 +26,7 @@ module Mongo
|
|
|
24
26
|
#
|
|
25
27
|
# @since 2.0.0
|
|
26
28
|
module Iterable
|
|
27
|
-
|
|
28
|
-
# Returns the cursor associated with this view, if any.
|
|
29
|
-
#
|
|
30
|
-
# @return [ nil | Cursor ] The cursor, if any.
|
|
31
|
-
#
|
|
32
|
-
# @api private
|
|
33
|
-
attr_reader :cursor
|
|
29
|
+
include Mongo::CursorHost
|
|
34
30
|
|
|
35
31
|
# Iterate through documents returned by a query with this +View+.
|
|
36
32
|
#
|
|
@@ -45,48 +41,21 @@ module Mongo
|
|
|
45
41
|
#
|
|
46
42
|
# @yieldparam [ Hash ] Each matching document.
|
|
47
43
|
def each
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# we have no way of completing that iteration.
|
|
51
|
-
# Therefore, discard that cursor and start iteration again.
|
|
52
|
-
# The case of the caching cursor not being closed and not having
|
|
53
|
-
# been fully iterated isn't tested - see RUBY-2773.
|
|
54
|
-
@cursor = if use_query_cache? && cached_cursor && (
|
|
55
|
-
cached_cursor.fully_iterated? || !cached_cursor.closed?
|
|
56
|
-
)
|
|
57
|
-
cached_cursor
|
|
58
|
-
else
|
|
59
|
-
session = client.send(:get_session, @options)
|
|
60
|
-
select_cursor(session).tap do |cursor|
|
|
61
|
-
if use_query_cache?
|
|
62
|
-
# No need to store the cursor in the query cache if there is
|
|
63
|
-
# already a cached cursor stored at this key.
|
|
64
|
-
QueryCache.set(cursor, **cache_options)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
44
|
+
@cursor = prefer_cached_cursor? ? cached_cursor : new_cursor_for_iteration
|
|
45
|
+
return @cursor.to_enum unless block_given?
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
# If a query with a limit is performed, the query cache will
|
|
71
|
-
# re-use results from an earlier query with the same or larger
|
|
72
|
-
# limit, and then impose the lower limit during iteration.
|
|
73
|
-
limit_for_cached_query = respond_to?(:limit) ? QueryCache.normalized_limit(limit) : nil
|
|
74
|
-
end
|
|
47
|
+
limit_for_cached_query = compute_limit_for_cached_query
|
|
75
48
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
@cursor.to_a[0...limit_for_cached_query]
|
|
81
|
-
else
|
|
82
|
-
@cursor
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
cursor_to_iterate.each do |doc|
|
|
86
|
-
yield doc
|
|
87
|
-
end
|
|
49
|
+
# Ruby versions 2.5 and older do not support arr[0..nil] syntax, so
|
|
50
|
+
# this must be a separate conditional.
|
|
51
|
+
cursor_to_iterate = if limit_for_cached_query
|
|
52
|
+
@cursor.to_a[0...limit_for_cached_query]
|
|
88
53
|
else
|
|
89
|
-
@cursor
|
|
54
|
+
@cursor
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
cursor_to_iterate.each do |doc|
|
|
58
|
+
yield doc
|
|
90
59
|
end
|
|
91
60
|
end
|
|
92
61
|
|
|
@@ -100,7 +69,7 @@ module Mongo
|
|
|
100
69
|
#
|
|
101
70
|
# @return [ nil ] Always nil.
|
|
102
71
|
#
|
|
103
|
-
# @raise [ Error::OperationFailure ] If the server cursor close fails.
|
|
72
|
+
# @raise [ Error::OperationFailure::Family ] If the server cursor close fails.
|
|
104
73
|
#
|
|
105
74
|
# @since 2.1.0
|
|
106
75
|
def close_query
|
|
@@ -113,18 +82,25 @@ module Mongo
|
|
|
113
82
|
private
|
|
114
83
|
|
|
115
84
|
def select_cursor(session)
|
|
85
|
+
context = Operation::Context.new(
|
|
86
|
+
client: client,
|
|
87
|
+
session: session,
|
|
88
|
+
operation_timeouts: operation_timeouts,
|
|
89
|
+
view: self
|
|
90
|
+
)
|
|
91
|
+
|
|
116
92
|
if respond_to?(:write?, true) && write?
|
|
117
93
|
server = server_selector.select_server(cluster, nil, session, write_aggregation: true)
|
|
118
|
-
result = send_initial_query(server,
|
|
94
|
+
result = send_initial_query(server, context)
|
|
119
95
|
|
|
120
96
|
if use_query_cache?
|
|
121
|
-
CachingCursor.new(view, result, server, session: session)
|
|
97
|
+
CachingCursor.new(view, result, server, session: session, context: context)
|
|
122
98
|
else
|
|
123
|
-
Cursor.new(view, result, server, session: session)
|
|
99
|
+
Cursor.new(view, result, server, session: session, context: context)
|
|
124
100
|
end
|
|
125
101
|
else
|
|
126
|
-
read_with_retry_cursor(session, server_selector, view) do |server|
|
|
127
|
-
send_initial_query(server,
|
|
102
|
+
read_with_retry_cursor(session, server_selector, view, context: context) do |server|
|
|
103
|
+
send_initial_query(server, context)
|
|
128
104
|
end
|
|
129
105
|
end
|
|
130
106
|
end
|
|
@@ -162,29 +138,27 @@ module Mongo
|
|
|
162
138
|
let: options[:let],
|
|
163
139
|
limit: limit,
|
|
164
140
|
allow_disk_use: options[:allow_disk_use],
|
|
141
|
+
allow_partial_results: options[:allow_partial_results],
|
|
165
142
|
read: read,
|
|
166
143
|
read_concern: options[:read_concern] || read_concern,
|
|
167
144
|
batch_size: batch_size,
|
|
168
145
|
hint: options[:hint],
|
|
169
146
|
max_scan: options[:max_scan],
|
|
170
|
-
max_time_ms: options[:max_time_ms],
|
|
171
147
|
max_value: options[:max_value],
|
|
172
148
|
min_value: options[:min_value],
|
|
173
149
|
no_cursor_timeout: options[:no_cursor_timeout],
|
|
174
150
|
return_key: options[:return_key],
|
|
175
151
|
show_disk_loc: options[:show_disk_loc],
|
|
176
152
|
comment: options[:comment],
|
|
177
|
-
oplog_replay:
|
|
178
|
-
collection.options[:oplog_replay]
|
|
179
|
-
else
|
|
180
|
-
v
|
|
181
|
-
end,
|
|
153
|
+
oplog_replay: oplog_replay
|
|
182
154
|
}
|
|
183
155
|
|
|
184
156
|
if spec[:oplog_replay]
|
|
185
157
|
collection.client.log_warn("The :oplog_replay option is deprecated and ignored by MongoDB 4.4 and later")
|
|
186
158
|
end
|
|
187
159
|
|
|
160
|
+
maybe_set_tailable_options(spec)
|
|
161
|
+
|
|
188
162
|
if explained?
|
|
189
163
|
spec[:explain] = options[:explain]
|
|
190
164
|
Operation::Explain.new(spec)
|
|
@@ -193,13 +167,71 @@ module Mongo
|
|
|
193
167
|
end
|
|
194
168
|
end
|
|
195
169
|
|
|
196
|
-
def send_initial_query(server,
|
|
197
|
-
initial_query_op(
|
|
170
|
+
def send_initial_query(server, context)
|
|
171
|
+
operation = initial_query_op(context.session)
|
|
172
|
+
if server.load_balancer?
|
|
173
|
+
# Connection will be checked in when cursor is drained.
|
|
174
|
+
connection = server.pool.check_out(context: context)
|
|
175
|
+
operation.execute_with_connection(connection, context: context)
|
|
176
|
+
else
|
|
177
|
+
operation.execute(server, context: context)
|
|
178
|
+
end
|
|
198
179
|
end
|
|
199
180
|
|
|
200
181
|
def use_query_cache?
|
|
201
182
|
QueryCache.enabled? && !collection.system_collection?
|
|
202
183
|
end
|
|
184
|
+
|
|
185
|
+
# If the caching cursor is closed and was not fully iterated,
|
|
186
|
+
# the documents we have in it are not the complete result set and
|
|
187
|
+
# we have no way of completing that iteration.
|
|
188
|
+
# Therefore, discard that cursor and start iteration again.
|
|
189
|
+
def prefer_cached_cursor?
|
|
190
|
+
use_query_cache? &&
|
|
191
|
+
cached_cursor &&
|
|
192
|
+
(cached_cursor.fully_iterated? || !cached_cursor.closed?)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Start a new cursor for use when iterating (via #each).
|
|
196
|
+
def new_cursor_for_iteration
|
|
197
|
+
session = client.get_session(@options)
|
|
198
|
+
select_cursor(session).tap do |cursor|
|
|
199
|
+
if use_query_cache?
|
|
200
|
+
# No need to store the cursor in the query cache if there is
|
|
201
|
+
# already a cached cursor stored at this key.
|
|
202
|
+
QueryCache.set(cursor, **cache_options)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def compute_limit_for_cached_query
|
|
208
|
+
return nil unless use_query_cache? && respond_to?(:limit)
|
|
209
|
+
|
|
210
|
+
# If a query with a limit is performed, the query cache will
|
|
211
|
+
# re-use results from an earlier query with the same or larger
|
|
212
|
+
# limit, and then impose the lower limit during iteration.
|
|
213
|
+
return QueryCache.normalized_limit(limit)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Add tailable cusror options to the command specifiction if needed.
|
|
217
|
+
#
|
|
218
|
+
# @param [ Hash ] spec The command specification.
|
|
219
|
+
def maybe_set_tailable_options(spec)
|
|
220
|
+
case cursor_type
|
|
221
|
+
when :tailable
|
|
222
|
+
spec[:tailable] = true
|
|
223
|
+
when :tailable_await
|
|
224
|
+
spec[:tailable] = true
|
|
225
|
+
spec[:await_data] = true
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# @return [ true | false | nil ] options[:oplog_replay], if
|
|
230
|
+
# set, otherwise the same option from the collection.
|
|
231
|
+
def oplog_replay
|
|
232
|
+
v = options[:oplog_replay]
|
|
233
|
+
v.nil? ? collection.options[:oplog_replay] : v
|
|
234
|
+
end
|
|
203
235
|
end
|
|
204
236
|
end
|
|
205
237
|
end
|