mongo 2.15.0 → 2.17.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
- checksums.yaml.gz.sig +0 -0
- data/README.md +1 -1
- data/lib/mongo/auth/aws/request.rb +0 -1
- data/lib/mongo/bulk_write.rb +2 -2
- data/lib/mongo/client.rb +49 -5
- data/lib/mongo/cluster/periodic_executor.rb +4 -3
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +76 -43
- data/lib/mongo/cluster/sdam_flow.rb +9 -3
- data/lib/mongo/cluster/topology/base.rb +13 -9
- data/lib/mongo/cluster/topology/load_balanced.rb +102 -0
- data/lib/mongo/cluster/topology.rb +28 -8
- data/lib/mongo/cluster.rb +136 -51
- data/lib/mongo/collection/view/aggregation.rb +63 -23
- data/lib/mongo/collection/view/builder/aggregation.rb +16 -17
- data/lib/mongo/collection/view/builder/map_reduce.rb +12 -49
- data/lib/mongo/collection/view/builder.rb +0 -4
- data/lib/mongo/collection/view/change_stream.rb +7 -3
- data/lib/mongo/collection/view/iterable.rb +60 -27
- data/lib/mongo/collection/view/map_reduce.rb +41 -15
- data/lib/mongo/collection/view/readable.rb +84 -52
- data/lib/mongo/collection/view/writable.rb +201 -175
- data/lib/mongo/collection/view.rb +15 -21
- data/lib/mongo/collection.rb +34 -14
- data/lib/mongo/cursor/kill_spec.rb +38 -0
- data/lib/mongo/cursor.rb +72 -31
- data/lib/mongo/database/view.rb +5 -3
- data/lib/mongo/database.rb +6 -6
- data/lib/mongo/error/bad_load_balancer_target.rb +26 -0
- data/lib/mongo/error/missing_service_id.rb +26 -0
- data/lib/mongo/error/no_service_connection_available.rb +49 -0
- data/lib/mongo/error/notable.rb +7 -0
- data/lib/mongo/error/snapshot_session_invalid_server_version.rb +31 -0
- data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +30 -0
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/grid/fs_bucket.rb +21 -2
- data/lib/mongo/id.rb +7 -5
- data/lib/mongo/index/view.rb +22 -41
- data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +7 -4
- data/lib/mongo/monitoring/event/command_failed.rb +1 -1
- data/lib/mongo/monitoring/event/command_started.rb +2 -0
- data/lib/mongo/monitoring/publishable.rb +2 -2
- data/lib/mongo/operation/aggregate/command.rb +8 -0
- data/lib/mongo/operation/context.rb +19 -1
- data/lib/mongo/operation/count/command.rb +6 -0
- data/lib/mongo/operation/count/op_msg.rb +6 -0
- data/lib/mongo/operation/create/command.rb +7 -1
- data/lib/mongo/operation/create/op_msg.rb +7 -0
- data/lib/mongo/operation/create_index/command.rb +17 -1
- data/lib/mongo/operation/create_index/op_msg.rb +17 -4
- data/lib/mongo/operation/delete/command.rb +6 -3
- data/lib/mongo/operation/delete/legacy.rb +9 -2
- data/lib/mongo/operation/delete/op_msg.rb +9 -1
- data/lib/mongo/operation/distinct/command.rb +6 -0
- data/lib/mongo/operation/distinct/op_msg.rb +7 -0
- data/lib/mongo/operation/explain/command.rb +13 -1
- data/lib/mongo/operation/explain/legacy.rb +12 -5
- data/lib/mongo/operation/explain/op_msg.rb +9 -1
- data/lib/mongo/operation/find/builder/command.rb +111 -0
- data/lib/mongo/{collection/view → operation/find}/builder/flags.rb +10 -14
- data/lib/mongo/operation/find/builder/legacy.rb +123 -0
- data/lib/mongo/{collection/view → operation/find}/builder/modifiers.rb +31 -25
- data/lib/mongo/{cursor → operation/find}/builder.rb +4 -4
- data/lib/mongo/operation/find/command.rb +9 -0
- data/lib/mongo/operation/find/legacy.rb +10 -1
- data/lib/mongo/operation/find/op_msg.rb +12 -0
- data/lib/mongo/operation/find.rb +1 -0
- data/lib/mongo/operation/get_more/command.rb +1 -0
- data/lib/mongo/operation/get_more/command_builder.rb +38 -0
- data/lib/mongo/operation/get_more/op_msg.rb +1 -0
- data/lib/mongo/operation/get_more.rb +1 -0
- data/lib/mongo/operation/kill_cursors/command.rb +8 -0
- data/lib/mongo/operation/kill_cursors/command_builder.rb +35 -0
- data/lib/mongo/operation/kill_cursors/legacy.rb +2 -1
- data/lib/mongo/operation/kill_cursors/op_msg.rb +10 -0
- data/lib/mongo/operation/kill_cursors.rb +1 -0
- data/lib/mongo/operation/map_reduce/command.rb +8 -0
- data/lib/mongo/operation/map_reduce/op_msg.rb +1 -1
- data/lib/mongo/operation/result.rb +6 -0
- data/lib/mongo/operation/shared/executable.rb +19 -1
- data/lib/mongo/operation/shared/polymorphic_operation.rb +1 -1
- data/lib/mongo/operation/shared/read_preference_supported.rb +3 -1
- data/lib/mongo/operation/shared/response_handling.rb +1 -0
- data/lib/mongo/operation/shared/sessions_supported.rb +28 -12
- data/lib/mongo/operation/shared/specifiable.rb +11 -29
- data/lib/mongo/operation/shared/validatable.rb +87 -0
- data/lib/mongo/operation/shared/write.rb +1 -1
- data/lib/mongo/operation/update/command.rb +6 -3
- data/lib/mongo/operation/update/legacy.rb +19 -11
- data/lib/mongo/operation/update/op_msg.rb +8 -4
- data/lib/mongo/operation/write_command/command.rb +51 -0
- data/lib/mongo/operation/write_command/op_msg.rb +43 -0
- data/lib/mongo/operation/write_command.rb +32 -0
- data/lib/mongo/operation.rb +10 -0
- data/lib/mongo/protocol/query.rb +35 -18
- data/lib/mongo/server/connection.rb +25 -3
- data/lib/mongo/server/connection_base.rb +12 -1
- data/lib/mongo/server/connection_common.rb +38 -1
- data/lib/mongo/server/connection_pool/generation_manager.rb +71 -0
- data/lib/mongo/server/connection_pool.rb +100 -27
- data/lib/mongo/server/description/features.rb +20 -17
- data/lib/mongo/server/description/load_balancer.rb +33 -0
- data/lib/mongo/server/description.rb +85 -6
- data/lib/mongo/server/monitor/connection.rb +5 -6
- data/lib/mongo/server/monitor.rb +2 -1
- data/lib/mongo/server/pending_connection.rb +47 -31
- data/lib/mongo/server/push_monitor.rb +10 -1
- data/lib/mongo/server.rb +73 -26
- data/lib/mongo/server_selector/base.rb +31 -5
- data/lib/mongo/session/session_pool.rb +11 -0
- data/lib/mongo/session.rb +40 -1
- data/lib/mongo/socket/ocsp_cache.rb +2 -3
- data/lib/mongo/socket/ocsp_verifier.rb +6 -37
- data/lib/mongo/socket.rb +1 -5
- data/lib/mongo/uri/options_mapper.rb +1 -0
- data/lib/mongo/uri/srv_protocol.rb +6 -8
- data/lib/mongo/uri.rb +18 -0
- data/lib/mongo/utils.rb +0 -13
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/integration/auth_spec.rb +31 -1
- data/spec/integration/awaited_ismaster_spec.rb +1 -1
- data/spec/integration/bulk_write_spec.rb +1 -1
- data/spec/integration/change_stream_spec.rb +3 -3
- data/spec/integration/client_construction_spec.rb +54 -0
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +1 -1
- data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +1 -1
- data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +1 -1
- data/spec/integration/client_side_encryption/data_key_spec.rb +1 -1
- data/spec/integration/client_spec.rb +2 -0
- data/spec/integration/command_monitoring_spec.rb +1 -1
- data/spec/integration/command_spec.rb +1 -1
- data/spec/integration/connection_spec.rb +52 -35
- data/spec/integration/crud_spec.rb +174 -1
- data/spec/integration/cursor_pinning_spec.rb +121 -0
- data/spec/integration/cursor_reaping_spec.rb +8 -4
- data/spec/integration/fork_reconnect_spec.rb +1 -5
- data/spec/integration/get_more_spec.rb +1 -1
- data/spec/integration/heartbeat_events_spec.rb +1 -1
- data/spec/integration/map_reduce_spec.rb +77 -0
- data/spec/integration/query_cache_spec.rb +47 -2
- data/spec/integration/query_cache_transactions_spec.rb +1 -1
- data/spec/integration/read_concern_spec.rb +1 -1
- data/spec/integration/read_preference_spec.rb +17 -13
- data/spec/integration/reconnect_spec.rb +30 -12
- data/spec/integration/retryable_errors_spec.rb +1 -1
- data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +1 -1
- data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -1
- data/spec/integration/sdam_error_handling_spec.rb +5 -3
- data/spec/integration/sdam_events_spec.rb +35 -19
- data/spec/integration/sdam_prose_spec.rb +1 -1
- data/spec/integration/server_monitor_spec.rb +1 -0
- data/spec/integration/server_selector_spec.rb +22 -5
- data/spec/integration/server_spec.rb +2 -0
- data/spec/integration/srv_monitoring_spec.rb +1 -1
- data/spec/integration/step_down_spec.rb +1 -1
- data/spec/integration/transaction_pinning_spec.rb +120 -0
- data/spec/integration/versioned_api_examples_spec.rb +45 -0
- data/spec/integration/x509_auth_spec.rb +1 -1
- data/spec/lite_spec_helper.rb +1 -2
- data/spec/mongo/address/unix_spec.rb +1 -0
- data/spec/mongo/auth/cr_spec.rb +2 -3
- data/spec/mongo/auth/ldap_spec.rb +2 -3
- data/spec/mongo/auth/scram_spec.rb +2 -3
- data/spec/mongo/auth/user/view_spec.rb +1 -1
- data/spec/mongo/auth/x509_spec.rb +2 -3
- data/spec/mongo/bulk_write_spec.rb +3 -3
- data/spec/mongo/client_construction_spec.rb +259 -28
- data/spec/mongo/client_spec.rb +6 -4
- data/spec/mongo/cluster/cursor_reaper_spec.rb +36 -21
- data/spec/mongo/cluster/periodic_executor_spec.rb +3 -1
- data/spec/mongo/cluster_spec.rb +44 -3
- data/spec/mongo/collection/view/aggregation_spec.rb +72 -96
- data/spec/mongo/collection/view/builder/find_command_spec.rb +4 -0
- data/spec/mongo/collection/view/builder/op_query_spec.rb +4 -0
- data/spec/mongo/collection/view/change_stream_spec.rb +1 -1
- data/spec/mongo/collection/view/map_reduce_spec.rb +15 -2
- data/spec/mongo/collection_crud_spec.rb +7 -2
- data/spec/mongo/collection_ddl_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +1 -1
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +4 -0
- data/spec/mongo/cursor/builder/op_get_more_spec.rb +4 -0
- data/spec/mongo/cursor_spec.rb +15 -5
- data/spec/mongo/database_spec.rb +15 -15
- data/spec/mongo/error/operation_failure_heavy_spec.rb +1 -1
- data/spec/mongo/grid/fs_bucket_spec.rb +18 -12
- data/spec/mongo/grid/stream/write_spec.rb +3 -9
- data/spec/mongo/grid/stream_spec.rb +1 -1
- data/spec/mongo/index/view_spec.rb +2 -2
- data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
- data/spec/mongo/{collection/view → operation/find}/builder/flags_spec.rb +2 -2
- data/spec/mongo/{collection/view → operation/find}/builder/modifiers_spec.rb +2 -2
- data/spec/mongo/operation/find/legacy_spec.rb +1 -0
- data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
- data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
- data/spec/mongo/operation/kill_cursors_spec.rb +4 -1
- data/spec/mongo/operation/read_preference_legacy_spec.rb +4 -0
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +26 -1
- data/spec/mongo/operation/update/bulk_spec.rb +1 -1
- data/spec/mongo/operation/update/op_msg_spec.rb +1 -1
- data/spec/mongo/query_cache_spec.rb +6 -2
- data/spec/mongo/server/connection_common_spec.rb +62 -11
- data/spec/mongo/server/connection_pool_spec.rb +73 -7
- data/spec/mongo/server/connection_spec.rb +138 -43
- data/spec/mongo/server/description_spec.rb +1 -1
- data/spec/mongo/server/monitor/connection_spec.rb +22 -0
- data/spec/mongo/server/monitor_spec.rb +4 -3
- data/spec/mongo/server/push_monitor_spec.rb +101 -0
- data/spec/mongo/server_selector_spec.rb +136 -15
- data/spec/mongo/session/session_pool_spec.rb +42 -10
- data/spec/mongo/session_transaction_spec.rb +15 -30
- data/spec/mongo/socket/ssl_spec.rb +26 -58
- data/spec/mongo/socket/unix_spec.rb +1 -0
- data/spec/mongo/uri_option_parsing_spec.rb +38 -5
- data/spec/mongo/utils_spec.rb +0 -14
- data/spec/runners/change_streams/test.rb +1 -1
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/connection_string.rb +7 -3
- data/spec/runners/crud/operation.rb +5 -3
- data/spec/runners/crud/requirement.rb +1 -0
- data/spec/runners/crud/verifier.rb +1 -2
- data/spec/runners/crud.rb +1 -1
- data/spec/runners/sdam.rb +2 -1
- data/spec/runners/transactions/test.rb +2 -2
- data/spec/runners/unified/assertions.rb +5 -4
- data/spec/runners/unified/crud_operations.rb +77 -23
- data/spec/runners/unified/ddl_operations.rb +29 -1
- data/spec/runners/unified/entity_map.rb +3 -3
- data/spec/runners/unified/event_subscriber.rb +2 -2
- data/spec/runners/unified/support_operations.rb +16 -3
- data/spec/runners/unified/test.rb +18 -3
- data/spec/runners/unified.rb +1 -1
- data/spec/shared/lib/mrss/cluster_config.rb +6 -1
- data/spec/shared/lib/mrss/constraints.rb +11 -5
- data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
- data/spec/shared/share/Dockerfile.erb +5 -4
- data/spec/shared/shlib/server.sh +70 -20
- data/spec/spec_tests/change_streams_spec.rb +1 -1
- data/spec/spec_tests/cmap_spec.rb +4 -1
- data/spec/spec_tests/command_monitoring_spec.rb +2 -2
- data/spec/spec_tests/data/command_monitoring/find.yml +9 -9
- data/spec/spec_tests/data/crud/read/aggregate-collation.yml +2 -1
- data/spec/spec_tests/data/crud/read/aggregate-out.yml +1 -0
- data/spec/spec_tests/data/crud/read/count-collation.yml +2 -1
- data/spec/spec_tests/data/crud/read/distinct-collation.yml +2 -1
- data/spec/spec_tests/data/crud/read/find-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/deleteMany-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/deleteOne-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/findOneAndDelete-collation.yml +3 -2
- data/spec/spec_tests/data/crud/write/findOneAndReplace-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/findOneAndUpdate-collation.yml +3 -2
- data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +3 -2
- data/spec/spec_tests/data/crud/write/updateMany-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/updateOne-collation.yml +2 -1
- data/spec/spec_tests/data/crud_unified/aggregate-let.yml +138 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +155 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +151 -0
- data/spec/spec_tests/data/crud_unified/deleteMany-let.yml +91 -0
- data/spec/spec_tests/data/crud_unified/deleteOne-let.yml +89 -0
- data/spec/spec_tests/data/crud_unified/find-let.yml +71 -0
- data/spec/spec_tests/data/crud_unified/findOneAndDelete-let.yml +88 -0
- data/spec/spec_tests/data/crud_unified/findOneAndReplace-let.yml +94 -0
- data/spec/spec_tests/data/crud_unified/findOneAndUpdate-let.yml +96 -0
- data/spec/spec_tests/data/crud_unified/updateMany-let.yml +103 -0
- data/spec/spec_tests/data/crud_unified/updateOne-let.yml +98 -0
- data/spec/spec_tests/data/load_balancers/event-monitoring.yml +99 -0
- data/spec/spec_tests/data/load_balancers/lb-connection-establishment.yml +36 -0
- data/spec/spec_tests/data/load_balancers/non-lb-connection-establishment.yml +56 -0
- data/spec/spec_tests/data/load_balancers/server-selection.yml +50 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Secondary.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Sharded/SmallMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Single/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/mapReduce.yml +3 -1
- data/spec/spec_tests/data/sdam/load-balanced/discover_load_balancer.yml +25 -0
- data/spec/spec_tests/data/sdam_integration/find-network-error.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +3 -1
- data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +3 -1
- data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +2 -0
- data/spec/spec_tests/data/sdam_monitoring/load_balancer.yml +65 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +13 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +6 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-multiple-hosts.yml +5 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +10 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-false.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-true.yml +0 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/encoded-userinfo-and-db.yml +15 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/loadBalanced-false-txt.yml +10 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/longer-parent-in-return.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/misformatted-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/no-results.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/not-enough-parts.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-result-default-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record-multiple-strings.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch1.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch2.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch3.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch4.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch5.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-too-short.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-wrong.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-default-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-nonstandard-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-txt-records.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-not-allowed-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-ssl-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-uri-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-unallowed-option.yml +0 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-admin-database.yml +13 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-auth.yml +12 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-two-hosts.yml +0 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-client-error.yml +69 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-server-error.yml +102 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +258 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +482 -0
- data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-abort.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-commit.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-writes.yml +2 -0
- data/spec/spec_tests/data/uri_options/connection-options.yml +60 -0
- data/spec/spec_tests/load_balancers_spec.rb +15 -0
- data/spec/spec_tests/retryable_reads_spec.rb +2 -2
- data/spec/spec_tests/retryable_writes_spec.rb +1 -1
- data/spec/spec_tests/sdam_integration_spec.rb +1 -1
- data/spec/spec_tests/sdam_monitoring_spec.rb +10 -5
- data/spec/spec_tests/sdam_spec.rb +1 -1
- data/spec/spec_tests/seed_list_discovery_spec.rb +118 -0
- data/spec/spec_tests/sessions_unified_spec.rb +13 -0
- data/spec/spec_tests/uri_options_spec.rb +4 -4
- data/spec/stress/fork_reconnect_stress_spec.rb +1 -5
- data/spec/stress/push_monitor_close_spec.rb +44 -0
- data/spec/support/certificates/atlas-ocsp-ca.crt +82 -90
- data/spec/support/certificates/atlas-ocsp.crt +127 -122
- data/spec/support/common_shortcuts.rb +2 -3
- data/spec/support/matchers.rb +13 -0
- data/spec/support/shared/auth_context.rb +16 -0
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_config.rb +10 -11
- data/spec/support/using_hash.rb +31 -0
- data/spec/support/utils.rb +1 -1
- data.tar.gz.sig +3 -4
- metadata +1111 -1029
- metadata.gz.sig +2 -3
- data/lib/mongo/collection/view/builder/find_command.rb +0 -173
- data/lib/mongo/collection/view/builder/op_query.rb +0 -94
- data/lib/mongo/cursor/builder/get_more_command.rb +0 -80
- data/lib/mongo/cursor/builder/kill_cursors_command.rb +0 -111
- data/lib/mongo/cursor/builder/op_get_more.rb +0 -64
- data/lib/mongo/cursor/builder/op_kill_cursors.rb +0 -106
- data/lib/mongo/server/context.rb +0 -72
- data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -66
- data/spec/runners/unified/using_hash.rb +0 -34
- data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -79
- data/spec/support/event_subscriber.rb +0 -221
data/lib/mongo/cluster.rb
CHANGED
@@ -159,6 +159,10 @@ module Mongo
|
|
159
159
|
@sdam_flow_lock = Mutex.new
|
160
160
|
Session::SessionPool.create(self)
|
161
161
|
|
162
|
+
if seeds.empty? && load_balanced?
|
163
|
+
raise ArgumentError, 'Load-balanced clusters with no seeds are prohibited'
|
164
|
+
end
|
165
|
+
|
162
166
|
# The opening topology is always unknown with no servers.
|
163
167
|
# https://github.com/mongodb/specifications/pull/388
|
164
168
|
opening_topology = Topology::Unknown.new(options, monitoring, self)
|
@@ -171,7 +175,7 @@ module Mongo
|
|
171
175
|
@seeds = seeds = seeds.uniq
|
172
176
|
servers = seeds.map do |seed|
|
173
177
|
# Server opening events must be sent after topology change events.
|
174
|
-
# Therefore separate server addition, done here before
|
178
|
+
# Therefore separate server addition, done here before topology change
|
175
179
|
# event is published, from starting to monitor the server which is
|
176
180
|
# done later.
|
177
181
|
add(seed, monitor: false)
|
@@ -179,11 +183,20 @@ module Mongo
|
|
179
183
|
|
180
184
|
if seeds.size >= 1
|
181
185
|
# Recreate the topology to get the current server list into it
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
186
|
+
recreate_topology(topology, opening_topology)
|
187
|
+
end
|
188
|
+
|
189
|
+
if load_balanced?
|
190
|
+
# We are required by the specifications to produce certain SDAM events
|
191
|
+
# when in load-balanced topology.
|
192
|
+
# These events don't make a lot of sense from the standpoint of the
|
193
|
+
# driver's SDAM implementation, nor from the standpoint of the
|
194
|
+
# driver's load balancer implementation.
|
195
|
+
# They are just required boilerplate.
|
196
|
+
#
|
197
|
+
# Note that this call must be done above the monitoring_io check
|
198
|
+
# because that short-circuits the rest of the constructor.
|
199
|
+
fabricate_lb_sdam_events_and_set_server_type
|
187
200
|
end
|
188
201
|
|
189
202
|
if options[:monitoring_io] == false
|
@@ -203,7 +216,7 @@ module Mongo
|
|
203
216
|
@connected = true
|
204
217
|
|
205
218
|
if options[:cleanup] != false
|
206
|
-
@cursor_reaper = CursorReaper.new
|
219
|
+
@cursor_reaper = CursorReaper.new(self)
|
207
220
|
@socket_reaper = SocketReaper.new(self)
|
208
221
|
@periodic_executor = PeriodicExecutor.new([
|
209
222
|
@cursor_reaper, @socket_reaper,
|
@@ -212,54 +225,56 @@ module Mongo
|
|
212
225
|
@periodic_executor.run!
|
213
226
|
end
|
214
227
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
servers.each do |server|
|
219
|
-
server.start_monitoring
|
220
|
-
end
|
228
|
+
unless load_balanced?
|
229
|
+
# Need to record start time prior to starting monitoring
|
230
|
+
start_monotime = Utils.monotonic_time
|
221
231
|
|
222
|
-
|
223
|
-
|
224
|
-
# The server selection timeout can be very short especially in
|
225
|
-
# tests, when the client waits for a synchronous scan before
|
226
|
-
# starting server selection. Limiting the scan to server selection time
|
227
|
-
# then aborts the scan before it can process even local servers.
|
228
|
-
# Therefore, allow at least 3 seconds for the scan here.
|
229
|
-
if server_selection_timeout < 3
|
230
|
-
server_selection_timeout = 3
|
232
|
+
servers.each do |server|
|
233
|
+
server.start_monitoring
|
231
234
|
end
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
#
|
240
|
-
|
241
|
-
|
242
|
-
end
|
243
|
-
if servers.all? { |server| server.last_scan_monotime && server.last_scan_monotime >= start_monotime }
|
244
|
-
break
|
245
|
-
end
|
246
|
-
if (time_remaining = deadline - Utils.monotonic_time) <= 0
|
247
|
-
break
|
235
|
+
|
236
|
+
if options[:scan] != false
|
237
|
+
server_selection_timeout = options[:server_selection_timeout] || ServerSelector::SERVER_SELECTION_TIMEOUT
|
238
|
+
# The server selection timeout can be very short especially in
|
239
|
+
# tests, when the client waits for a synchronous scan before
|
240
|
+
# starting server selection. Limiting the scan to server selection time
|
241
|
+
# then aborts the scan before it can process even local servers.
|
242
|
+
# Therefore, allow at least 3 seconds for the scan here.
|
243
|
+
if server_selection_timeout < 3
|
244
|
+
server_selection_timeout = 3
|
248
245
|
end
|
249
|
-
|
250
|
-
#
|
251
|
-
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
246
|
+
deadline = start_monotime + server_selection_timeout
|
247
|
+
# Wait for the first scan of each server to complete, for
|
248
|
+
# backwards compatibility.
|
249
|
+
# If any servers are discovered during this SDAM round we are going to
|
250
|
+
# wait for these servers to also be queried, and so on, up to the
|
251
|
+
# server selection timeout or the 3 second minimum.
|
252
|
+
loop do
|
253
|
+
# Ensure we do not try to read the servers list while SDAM is running
|
254
|
+
servers = @sdam_flow_lock.synchronize do
|
255
|
+
servers_list.dup
|
256
|
+
end
|
257
|
+
if servers.all? { |server| server.last_scan_monotime && server.last_scan_monotime >= start_monotime }
|
258
|
+
break
|
259
|
+
end
|
260
|
+
if (time_remaining = deadline - Utils.monotonic_time) <= 0
|
261
|
+
break
|
262
|
+
end
|
263
|
+
log_debug("Waiting for up to #{'%.2f' % time_remaining} seconds for servers to be scanned: #{summary}")
|
264
|
+
# Since the semaphore may have been signaled between us checking
|
265
|
+
# the servers list above and the wait call below, we should not
|
266
|
+
# wait for the full remaining time - wait for up to 1 second, then
|
267
|
+
# recheck the state.
|
268
|
+
begin
|
269
|
+
server_selection_semaphore.wait([time_remaining, 1].min)
|
270
|
+
rescue ::Timeout::Error
|
271
|
+
# nothing
|
272
|
+
end
|
258
273
|
end
|
259
274
|
end
|
260
|
-
end
|
261
275
|
|
262
|
-
|
276
|
+
start_stop_srv_monitor
|
277
|
+
end
|
263
278
|
end
|
264
279
|
|
265
280
|
# Create a cluster for the provided client, for use when we don't want the
|
@@ -321,6 +336,14 @@ module Mongo
|
|
321
336
|
def_delegators :topology, :replica_set?, :replica_set_name, :sharded?,
|
322
337
|
:single?, :unknown?
|
323
338
|
|
339
|
+
# Returns whether the cluster is configured to be in the load-balanced
|
340
|
+
# topology.
|
341
|
+
#
|
342
|
+
# @return [ true | false ] Whether the topology is load-balanced.
|
343
|
+
def load_balanced?
|
344
|
+
topology.is_a?(Topology::LoadBalanced)
|
345
|
+
end
|
346
|
+
|
324
347
|
[:register_cursor, :schedule_kill_cursor, :unregister_cursor].each do |m|
|
325
348
|
define_method(m) do |*args|
|
326
349
|
if options[:cleanup] != false
|
@@ -599,9 +622,25 @@ module Mongo
|
|
599
622
|
# on 4.2+ servers).
|
600
623
|
# @option aptions [ true | false ] :awaited Whether the updated description
|
601
624
|
# was a result of processing an awaited hello.
|
625
|
+
# @option options [ Object ] :service_id Change state for the specified
|
626
|
+
# service id only.
|
602
627
|
#
|
603
628
|
# @api private
|
604
629
|
def run_sdam_flow(previous_desc, updated_desc, options = {})
|
630
|
+
if load_balanced?
|
631
|
+
if updated_desc.config.empty?
|
632
|
+
unless options[:keep_connection_pool]
|
633
|
+
servers_list.each do |server|
|
634
|
+
# TODO should service id be taken out of updated_desc?
|
635
|
+
# We could also assert that
|
636
|
+
# options[:service_id] == updated_desc.service_id
|
637
|
+
server.clear_connection_pool(service_id: options[:service_id])
|
638
|
+
end
|
639
|
+
end
|
640
|
+
end
|
641
|
+
return
|
642
|
+
end
|
643
|
+
|
605
644
|
@sdam_flow_lock.synchronize do
|
606
645
|
flow = SdamFlow.new(self, previous_desc, updated_desc,
|
607
646
|
awaited: options[:awaited])
|
@@ -782,8 +821,15 @@ module Mongo
|
|
782
821
|
def add(host, add_options=nil)
|
783
822
|
address = Address.new(host, options)
|
784
823
|
if !addresses.include?(address)
|
785
|
-
|
786
|
-
|
824
|
+
opts = options.merge(monitor: false)
|
825
|
+
# Note that in a load-balanced topology, every server must be a
|
826
|
+
# load balancer (load_balancer: true is specified in the options)
|
827
|
+
# but this option isn't set here because we are required by the
|
828
|
+
# specifications to pretent the server started out as an unknown one
|
829
|
+
# and publish server description change event into the load balancer
|
830
|
+
# one. The actual correct description for this server will be set
|
831
|
+
# by the fabricate_lb_sdam_events_and_set_server_type method.
|
832
|
+
server = Server.new(address, self, @monitoring, event_listeners, opts)
|
787
833
|
@update_lock.synchronize do
|
788
834
|
# Need to recheck whether server is present in @servers, because
|
789
835
|
# the previous check was not under a lock.
|
@@ -899,6 +945,10 @@ module Mongo
|
|
899
945
|
#
|
900
946
|
# @api private
|
901
947
|
def validate_session_support!
|
948
|
+
if topology.is_a?(Topology::LoadBalanced)
|
949
|
+
return
|
950
|
+
end
|
951
|
+
|
902
952
|
@state_change_lock.synchronize do
|
903
953
|
@sdam_flow_lock.synchronize do
|
904
954
|
if topology.data_bearing_servers?
|
@@ -982,6 +1032,41 @@ module Mongo
|
|
982
1032
|
msg = "The deployment that the driver is connected to does not support sessions: #{reason}"
|
983
1033
|
raise Error::SessionsNotSupported, msg
|
984
1034
|
end
|
1035
|
+
|
1036
|
+
def fabricate_lb_sdam_events_and_set_server_type
|
1037
|
+
# Although there is no monitoring connection in load balanced mode,
|
1038
|
+
# we must emit the following series of SDAM events.
|
1039
|
+
server = @servers.first
|
1040
|
+
# We are guaranteed to have the server here.
|
1041
|
+
server.publish_opening_event
|
1042
|
+
server_desc = server.description
|
1043
|
+
# This is where a load balancer actually gets its correct server
|
1044
|
+
# description.
|
1045
|
+
server.update_description(
|
1046
|
+
Server::Description.new(server.address, {},
|
1047
|
+
load_balancer: true,
|
1048
|
+
force_load_balancer: options[:connect] == :load_balanced,
|
1049
|
+
)
|
1050
|
+
)
|
1051
|
+
publish_sdam_event(
|
1052
|
+
Monitoring::SERVER_DESCRIPTION_CHANGED,
|
1053
|
+
Monitoring::Event::ServerDescriptionChanged.new(
|
1054
|
+
server.address,
|
1055
|
+
topology,
|
1056
|
+
server_desc,
|
1057
|
+
server.description
|
1058
|
+
)
|
1059
|
+
)
|
1060
|
+
recreate_topology(topology, topology)
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
def recreate_topology(new_topology_template, previous_topology)
|
1064
|
+
@topology = topology.class.new(new_topology_template.options, new_topology_template.monitoring, self)
|
1065
|
+
publish_sdam_event(
|
1066
|
+
Monitoring::TOPOLOGY_CHANGED,
|
1067
|
+
Monitoring::Event::TopologyChanged.new(previous_topology, @topology)
|
1068
|
+
)
|
1069
|
+
end
|
985
1070
|
end
|
986
1071
|
end
|
987
1072
|
|
@@ -73,6 +73,25 @@ module Mongo
|
|
73
73
|
# @param [ Array<Hash> ] pipeline The pipeline of operations.
|
74
74
|
# @param [ Hash ] options The aggregation options.
|
75
75
|
#
|
76
|
+
# @option options [ true, false ] :allow_disk_use Set to true if disk
|
77
|
+
# usage is allowed during the aggregation.
|
78
|
+
# @option options [ Integer ] :batch_size The number of documents to return
|
79
|
+
# per batch.
|
80
|
+
# @option options [ true, false ] :bypass_document_validation Whether or
|
81
|
+
# not to skip document level validation.
|
82
|
+
# @option options [ Hash ] :collation The collation to use.
|
83
|
+
# @option options [ String ] :comment Associate a comment with the aggregation.
|
84
|
+
# @option options [ String ] :hint The index to use for the aggregation.
|
85
|
+
# @option options [ Hash ] :let Mapping of variables to use in the pipeline.
|
86
|
+
# See the server documentation for details.
|
87
|
+
# @option options [ Integer ] :max_time_ms The maximum amount of time in
|
88
|
+
# milliseconds to allow the aggregation to run.
|
89
|
+
# @option options [ true, false ] :use_cursor Indicates whether the command
|
90
|
+
# will request that the server provide results using a cursor. Note that
|
91
|
+
# as of server version 3.6, aggregations always provide results using a
|
92
|
+
# cursor and this option is therefore not valid.
|
93
|
+
# @option options [ Session ] :session The session to use.
|
94
|
+
#
|
76
95
|
# @since 2.0.0
|
77
96
|
def initialize(view, pipeline, options = {})
|
78
97
|
@view = view
|
@@ -108,42 +127,63 @@ module Mongo
|
|
108
127
|
@view.send(:server_selector)
|
109
128
|
end
|
110
129
|
|
111
|
-
def aggregate_spec(session)
|
112
|
-
Builder::Aggregation.new(
|
130
|
+
def aggregate_spec(server, session, read_preference)
|
131
|
+
Builder::Aggregation.new(
|
132
|
+
pipeline,
|
133
|
+
view,
|
134
|
+
options.merge(session: session, read_preference: read_preference)
|
135
|
+
).specification
|
113
136
|
end
|
114
137
|
|
115
138
|
def new(options)
|
116
139
|
Aggregation.new(view, pipeline, options)
|
117
140
|
end
|
118
141
|
|
119
|
-
def initial_query_op(session)
|
120
|
-
Operation::Aggregate.new(aggregate_spec(session))
|
142
|
+
def initial_query_op(server, session, read_preference)
|
143
|
+
Operation::Aggregate.new(aggregate_spec(server, session, read_preference))
|
121
144
|
end
|
122
145
|
|
123
|
-
|
124
|
-
|
125
|
-
|
146
|
+
# Return effective read preference for the operation.
|
147
|
+
#
|
148
|
+
# If the pipeline contains $merge or $out, and read preference specified
|
149
|
+
# by user is secondary or secondary_preferred, and selected server is below
|
150
|
+
# 5.0, than this method returns primary read preference, because the
|
151
|
+
# aggregation will be routed to primary. Otherwise return the original
|
152
|
+
# read preference.
|
153
|
+
#
|
154
|
+
# See https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#read-preferences-and-server-selection
|
155
|
+
#
|
156
|
+
# @param [ Server ] server The server on which the operation
|
157
|
+
# should be executed.
|
158
|
+
# @return [ Hash | nil ] read preference hash that should be sent with
|
159
|
+
# this command.
|
160
|
+
def effective_read_preference(server)
|
161
|
+
return unless view.read_preference
|
162
|
+
return view.read_preference unless write?
|
163
|
+
return view.read_preference unless [:secondary, :secondary_preferred].include?(view.read_preference[:mode])
|
164
|
+
|
165
|
+
primary_read_preference = {mode: :primary}
|
166
|
+
if server.primary?
|
167
|
+
log_warn("Routing the Aggregation operation to the primary server")
|
168
|
+
primary_read_preference
|
169
|
+
elsif server.mongos? && !server.features.merge_out_on_secondary_enabled?
|
170
|
+
log_warn("Routing the Aggregation operation to the primary server")
|
171
|
+
primary_read_preference
|
172
|
+
else
|
173
|
+
view.read_preference
|
126
174
|
end
|
127
|
-
description.standalone? || description.mongos? || description.primary? || secondary_ok?
|
128
|
-
end
|
129
175
|
|
130
|
-
def secondary_ok?
|
131
|
-
!write?
|
132
176
|
end
|
133
177
|
|
134
178
|
def send_initial_query(server, session)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
def validate_collation!(server)
|
144
|
-
if options[:collation] && !server.with_connection { |connection| connection.features }.collation_enabled?
|
145
|
-
raise Error::UnsupportedCollation.new
|
146
|
-
end
|
179
|
+
initial_query_op(
|
180
|
+
server,
|
181
|
+
session,
|
182
|
+
effective_read_preference(server)
|
183
|
+
).execute(
|
184
|
+
server,
|
185
|
+
context: Operation::Context.new(client: client, session: session)
|
186
|
+
)
|
147
187
|
end
|
148
188
|
|
149
189
|
# Skip, sort, limit, projection are specified as pipeline stages
|
@@ -30,16 +30,17 @@ module Mongo
|
|
30
30
|
#
|
31
31
|
# @since 2.2.0
|
32
32
|
MAPPINGS = BSON::Document.new(
|
33
|
-
:
|
34
|
-
:
|
33
|
+
allow_disk_use: 'allowDiskUse',
|
34
|
+
bypass_document_validation: 'bypassDocumentValidation',
|
35
|
+
explain: 'explain',
|
36
|
+
collation: 'collation',
|
37
|
+
comment: 'comment',
|
38
|
+
hint: 'hint',
|
39
|
+
let: 'let',
|
35
40
|
# This is intentional; max_await_time_ms is an alias for maxTimeMS
|
36
41
|
# used on getMore commands for change streams.
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:bypass_document_validation => 'bypassDocumentValidation',
|
40
|
-
:collation => 'collation',
|
41
|
-
:hint => 'hint',
|
42
|
-
:comment => 'comment'
|
42
|
+
max_await_time_ms: 'maxTimeMS',
|
43
|
+
max_time_ms: 'maxTimeMS',
|
43
44
|
).freeze
|
44
45
|
|
45
46
|
def_delegators :@view, :collection, :database, :read, :write_concern
|
@@ -55,12 +56,9 @@ module Mongo
|
|
55
56
|
|
56
57
|
# Initialize the builder.
|
57
58
|
#
|
58
|
-
# @example Initialize the builder.
|
59
|
-
# Aggregation.new(map, reduce, view, options)
|
60
|
-
#
|
61
59
|
# @param [ Array<Hash> ] pipeline The aggregation pipeline.
|
62
60
|
# @param [ Collection::View ] view The collection view.
|
63
|
-
# @param [ Hash ] options The map/reduce options.
|
61
|
+
# @param [ Hash ] options The map/reduce and read preference options.
|
64
62
|
#
|
65
63
|
# @since 2.2.0
|
66
64
|
def initialize(pipeline, view, options)
|
@@ -79,11 +77,12 @@ module Mongo
|
|
79
77
|
# @since 2.2.0
|
80
78
|
def specification
|
81
79
|
spec = {
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
80
|
+
selector: aggregation_command,
|
81
|
+
db_name: database.name,
|
82
|
+
read: @options[:read_preference] || view.read_preference,
|
83
|
+
session: @options[:session],
|
84
|
+
collation: @options[:collation],
|
85
|
+
}
|
87
86
|
if write?
|
88
87
|
spec.update(write_concern: write_concern)
|
89
88
|
end
|
@@ -36,7 +36,7 @@ module Mongo
|
|
36
36
|
scope: 'scope',
|
37
37
|
verbose: 'verbose',
|
38
38
|
bypass_document_validation: 'bypassDocumentValidation',
|
39
|
-
collation: 'collation'
|
39
|
+
collation: 'collation',
|
40
40
|
).freeze
|
41
41
|
|
42
42
|
def_delegators :@view, :collection, :database, :filter, :read, :write_concern
|
@@ -71,36 +71,6 @@ module Mongo
|
|
71
71
|
@options = options
|
72
72
|
end
|
73
73
|
|
74
|
-
# Get the specification for issuing a find command on the map/reduce
|
75
|
-
# results.
|
76
|
-
#
|
77
|
-
# @example Get the command specification.
|
78
|
-
# builder.command_specification
|
79
|
-
#
|
80
|
-
# @return [ Hash ] The specification.
|
81
|
-
#
|
82
|
-
# @since 2.2.0
|
83
|
-
def command_specification
|
84
|
-
{
|
85
|
-
selector: find_command,
|
86
|
-
db_name: query_database,
|
87
|
-
read: read,
|
88
|
-
session: options[:session]
|
89
|
-
}
|
90
|
-
end
|
91
|
-
|
92
|
-
# Get the specification for the document query after a map/reduce.
|
93
|
-
#
|
94
|
-
# @example Get the query specification.
|
95
|
-
# builder.query_specification
|
96
|
-
#
|
97
|
-
# @return [ Hash ] The specification.
|
98
|
-
#
|
99
|
-
# @since 2.2.0
|
100
|
-
def query_specification
|
101
|
-
{ selector: {}, options: {}, db_name: query_database, coll_name: query_collection }
|
102
|
-
end
|
103
|
-
|
104
74
|
# Get the specification to pass to the map/reduce operation.
|
105
75
|
#
|
106
76
|
# @example Get the specification.
|
@@ -113,6 +83,8 @@ module Mongo
|
|
113
83
|
spec = {
|
114
84
|
selector: map_reduce_command,
|
115
85
|
db_name: database.name,
|
86
|
+
# Note that selector just above may also have a read preference
|
87
|
+
# specified, per the #map_reduce_command method below.
|
116
88
|
read: read,
|
117
89
|
session: options[:session]
|
118
90
|
}
|
@@ -121,8 +93,6 @@ module Mongo
|
|
121
93
|
|
122
94
|
private
|
123
95
|
|
124
|
-
OUT_ACTIONS = [ :replace, :merge, :reduce ].freeze
|
125
|
-
|
126
96
|
def write?(spec)
|
127
97
|
if out = spec[:selector][:out]
|
128
98
|
out.is_a?(String) ||
|
@@ -130,37 +100,30 @@ module Mongo
|
|
130
100
|
end
|
131
101
|
end
|
132
102
|
|
133
|
-
def find_command
|
134
|
-
BSON::Document.new('find' => query_collection, 'filter' => {})
|
135
|
-
end
|
136
|
-
|
137
103
|
def map_reduce_command
|
138
104
|
command = BSON::Document.new(
|
139
105
|
:mapReduce => collection.name,
|
140
106
|
:map => map,
|
141
107
|
:reduce => reduce,
|
142
108
|
:query => filter,
|
143
|
-
:out => { inline: 1 }
|
109
|
+
:out => { inline: 1 },
|
144
110
|
)
|
111
|
+
# Shouldn't this use self.read ?
|
145
112
|
if collection.read_concern
|
146
113
|
command[:readConcern] = Options::Mapper.transform_values_to_strings(
|
147
114
|
collection.read_concern)
|
148
115
|
end
|
149
|
-
command.
|
116
|
+
command.update(view_options)
|
117
|
+
command.update(options.slice(:collation))
|
118
|
+
# Read preference isn't simply passed in the command payload
|
119
|
+
# (it may need to be converted to wire protocol flags)
|
120
|
+
# so remove it here and hopefully it's handled elsewhere.
|
121
|
+
# If not, RUBY-2706.
|
122
|
+
command.delete(:read)
|
150
123
|
command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
|
151
124
|
command
|
152
125
|
end
|
153
126
|
|
154
|
-
def query_database
|
155
|
-
options[:out].respond_to?(:keys) && options[:out][:db] ? options[:out][:db] : database.name
|
156
|
-
end
|
157
|
-
|
158
|
-
def query_collection
|
159
|
-
if options[:out].respond_to?(:keys)
|
160
|
-
options[:out][OUT_ACTIONS.find { |action| options[:out][action] }]
|
161
|
-
end || options[:out]
|
162
|
-
end
|
163
|
-
|
164
127
|
def view_options
|
165
128
|
@view_options ||= (opts = view.options.dup
|
166
129
|
opts.delete(:session)
|
@@ -17,7 +17,3 @@
|
|
17
17
|
|
18
18
|
require 'mongo/collection/view/builder/aggregation'
|
19
19
|
require 'mongo/collection/view/builder/map_reduce'
|
20
|
-
require 'mongo/collection/view/builder/op_query'
|
21
|
-
require 'mongo/collection/view/builder/find_command'
|
22
|
-
require 'mongo/collection/view/builder/flags'
|
23
|
-
require 'mongo/collection/view/builder/modifiers'
|
@@ -298,8 +298,8 @@ module Mongo
|
|
298
298
|
[{ '$changeStream' => change_doc }] + @change_stream_filters
|
299
299
|
end
|
300
300
|
|
301
|
-
def aggregate_spec(session)
|
302
|
-
super(session).tap do |spec|
|
301
|
+
def aggregate_spec(server, session, read_preference)
|
302
|
+
super(server, session, read_preference).tap do |spec|
|
303
303
|
spec[:selector][:aggregate] = 1 unless for_collection?
|
304
304
|
end
|
305
305
|
end
|
@@ -349,7 +349,11 @@ module Mongo
|
|
349
349
|
end
|
350
350
|
|
351
351
|
def send_initial_query(server, session)
|
352
|
-
initial_query_op(
|
352
|
+
initial_query_op(server, session, view.read_preference)
|
353
|
+
.execute(
|
354
|
+
server,
|
355
|
+
context: Operation::Context.new(client: client, session: session)
|
356
|
+
)
|
353
357
|
end
|
354
358
|
|
355
359
|
def time_to_bson_timestamp(time)
|