couchbase 3.8.2 → 3.9.1
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 +1 -1
- data/ext/CMakeLists.txt +16 -1
- data/ext/cache/cpm/{CPM_0.42.0.cmake → CPM_0.43.1.cmake} +18 -2
- data/ext/cache/extconf_include.rb +6 -6
- data/ext/cache/mozilla-ca-bundle.crt +121 -55
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +136 -23
- data/ext/couchbase/cmake/APKBUILD.in +25 -4
- data/ext/couchbase/cmake/Bundler.cmake +143 -34
- data/ext/couchbase/cmake/CPM.cmake +126 -12
- data/ext/couchbase/cmake/Cache.cmake +7 -1
- data/ext/couchbase/cmake/CompilerOptions.cmake +1 -1
- data/ext/couchbase/cmake/CompilerWarnings.cmake +17 -6
- data/ext/couchbase/cmake/GrpcProtobuf.cmake +481 -0
- data/ext/couchbase/cmake/OpenSSL.cmake +82 -7
- data/ext/couchbase/cmake/Packaging.cmake +519 -65
- data/ext/couchbase/cmake/Protostellar.cmake +250 -0
- data/ext/couchbase/cmake/Sanitizers.cmake +61 -50
- data/ext/couchbase/cmake/StaticAnalyzers.cmake +16 -5
- data/ext/couchbase/cmake/TestFramework.cmake +283 -0
- data/ext/couchbase/cmake/TestFrameworkAddTests.cmake +51 -0
- data/ext/couchbase/cmake/Testing.cmake +27 -9
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +141 -8
- data/ext/couchbase/cmake/VersionInfo.cmake +50 -0
- data/ext/couchbase/cmake/build_config.hxx.in +2 -1
- data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +101 -23
- data/ext/couchbase/cmake/couchbase_cxx_client_static-config.cmake.in +7 -0
- data/ext/couchbase/cmake/couchbase_cxx_client_static.pc.in +2 -0
- data/ext/couchbase/cmake/gRPC_Generate.cmake +58 -0
- data/ext/couchbase/cmake/protobuf_Generate.cmake +69 -0
- data/ext/couchbase/cmake/require-git-checkout.cmake +25 -0
- data/ext/couchbase/cmake/tarball_glob.txt +49 -0
- data/ext/couchbase/core/agent_group.cxx +0 -8
- data/ext/couchbase/core/agent_group.hxx +0 -4
- data/ext/couchbase/core/analytics_stream.cxx +314 -0
- data/ext/couchbase/core/analytics_stream.hxx +129 -0
- data/ext/couchbase/core/analytics_stream_component.cxx +245 -0
- data/ext/couchbase/core/analytics_stream_component.hxx +67 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +25 -3
- data/ext/couchbase/core/app_telemetry_meter.hxx +77 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +7 -6
- data/ext/couchbase/core/bucket.cxx +381 -87
- data/ext/couchbase/core/bucket.hxx +105 -25
- data/ext/couchbase/core/bucket_unit_test_api.hxx +57 -0
- data/ext/couchbase/core/capella.hxx +91 -0
- data/ext/couchbase/core/cluster.cxx +1551 -397
- data/ext/couchbase/core/cluster.hxx +39 -8
- data/ext/couchbase/core/cluster_agent.cxx +0 -8
- data/ext/couchbase/core/cluster_agent.hxx +0 -4
- data/ext/couchbase/core/cluster_options.hxx +26 -3
- data/ext/couchbase/core/collections_component.cxx +39 -15
- data/ext/couchbase/core/config_profiles.cxx +1 -1
- data/ext/couchbase/core/crud_component.cxx +2 -2
- data/ext/couchbase/core/crud_options.hxx +34 -0
- data/ext/couchbase/core/crypto/cbcrypto.cc +18 -13
- data/ext/couchbase/core/document_id_redaction.hxx +81 -0
- data/ext/couchbase/core/error_context/base_error_context.hxx +7 -6
- data/ext/couchbase/core/error_context/key_value.cxx +25 -2
- data/ext/couchbase/core/error_context/key_value.hxx +60 -33
- data/ext/couchbase/core/error_context/key_value_error_context.hxx +16 -15
- data/ext/couchbase/core/error_context/search.hxx +5 -0
- data/ext/couchbase/core/error_context/search_json.hxx +3 -0
- data/ext/couchbase/core/error_context/subdocument_error_context.hxx +19 -18
- data/ext/couchbase/core/error_context/view.hxx +5 -0
- data/ext/couchbase/core/free_form_http_request.cxx +237 -4
- data/ext/couchbase/core/free_form_http_request.hxx +41 -8
- data/ext/couchbase/core/http_component.cxx +300 -284
- data/ext/couchbase/core/http_component.hxx +0 -4
- data/ext/couchbase/core/impl/analytics.cxx +38 -5
- data/ext/couchbase/core/impl/analytics.hxx +34 -0
- data/ext/couchbase/core/impl/bootstrap_error.hxx +0 -3
- data/ext/couchbase/core/impl/collection.cxx +215 -202
- data/ext/couchbase/core/impl/collection_manager.cxx +1 -1
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +45 -18
- data/ext/couchbase/core/impl/error.cxx +22 -2
- data/ext/couchbase/core/impl/internal_analytics_stream_result.hxx +111 -0
- data/ext/couchbase/core/impl/internal_query_stream_result.hxx +110 -0
- data/ext/couchbase/core/impl/invoke_with_node_id.hxx +15 -7
- data/ext/couchbase/core/impl/key_value_error_category.cxx +6 -0
- data/ext/couchbase/core/impl/lookup_in_replica.cxx +10 -10
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +4 -4
- data/ext/couchbase/core/impl/node_id.cxx +49 -13
- data/ext/couchbase/core/impl/observability_recorder.cxx +12 -2
- data/ext/couchbase/core/impl/observe_poll.cxx +63 -23
- data/ext/couchbase/core/impl/public_analytics_stream_result.cxx +372 -0
- data/ext/couchbase/core/impl/public_bucket.cxx +48 -2
- data/ext/couchbase/core/impl/public_cluster.cxx +229 -42
- data/ext/couchbase/core/impl/public_query_stream_result.cxx +380 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_replicas_from_preferred_server_group_result.cxx +42 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_result.cxx +42 -0
- data/ext/couchbase/core/impl/query.cxx +76 -7
- data/ext/couchbase/core/impl/query.hxx +36 -0
- data/ext/couchbase/core/impl/query_index_manager.cxx +54 -1
- data/ext/couchbase/core/impl/replica_utils.cxx +101 -0
- data/ext/couchbase/core/impl/replica_utils.hxx +64 -0
- data/ext/couchbase/core/impl/resolve_node_id.hxx +125 -0
- data/ext/couchbase/core/impl/scope.cxx +70 -0
- data/ext/couchbase/core/impl/search.cxx +31 -1
- data/ext/couchbase/core/impl/transactions.cxx +130 -0
- data/ext/couchbase/core/impl/wait_until_ready.cxx +439 -0
- data/ext/couchbase/core/impl/wait_until_ready.hxx +110 -0
- data/ext/couchbase/core/impl/with_bucket_config_or_timeout.hxx +180 -0
- data/ext/couchbase/core/impl/with_cancellation.hxx +11 -3
- data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +1 -2
- data/ext/couchbase/core/io/dns_client.cxx +122 -45
- data/ext/couchbase/core/io/dns_codec.hxx +21 -21
- data/ext/couchbase/core/io/dns_config.cxx +21 -6
- data/ext/couchbase/core/io/http_command.hxx +149 -121
- data/ext/couchbase/core/io/http_error.hxx +107 -0
- data/ext/couchbase/core/io/http_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_session.cxx +606 -154
- data/ext/couchbase/core/io/http_session.hxx +147 -30
- data/ext/couchbase/core/io/http_session_manager.hxx +329 -382
- data/ext/couchbase/core/io/http_streaming_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_streaming_response.cxx +328 -43
- data/ext/couchbase/core/io/http_streaming_response.hxx +37 -3
- data/ext/couchbase/core/io/mcbp_buffer_pool.hxx +122 -0
- data/ext/couchbase/core/io/mcbp_command.hxx +150 -51
- data/ext/couchbase/core/io/mcbp_command_id.hxx +45 -0
- data/ext/couchbase/core/io/mcbp_message.cxx +9 -1
- data/ext/couchbase/core/io/mcbp_message.hxx +19 -0
- data/ext/couchbase/core/io/mcbp_output_queue.hxx +150 -0
- data/ext/couchbase/core/io/mcbp_parser.cxx +24 -7
- data/ext/couchbase/core/io/mcbp_session.cxx +309 -301
- data/ext/couchbase/core/io/mcbp_session.hxx +27 -18
- data/ext/couchbase/core/io/opaque_ring_table.hxx +145 -0
- data/ext/couchbase/core/io/retry_orchestrator.hxx +6 -5
- data/ext/couchbase/core/io/stream_deadline.hxx +50 -0
- data/ext/couchbase/core/io/streams.cxx +151 -21
- data/ext/couchbase/core/io/streams.hxx +48 -1
- data/ext/couchbase/core/logger/logger.cxx +36 -0
- data/ext/couchbase/core/logger/logger.hxx +46 -6
- data/ext/couchbase/core/logger/redaction.hxx +503 -0
- data/ext/couchbase/core/management/eventing_status.hxx +10 -0
- data/ext/couchbase/core/management/eventing_status_json.hxx +4 -0
- data/ext/couchbase/core/mcbp/big_endian.cxx +1 -1
- data/ext/couchbase/core/mcbp/codec.cxx +27 -18
- data/ext/couchbase/core/mcbp/operation_queue.cxx +2 -2
- data/ext/couchbase/core/mcbp/packet.hxx +2 -2
- data/ext/couchbase/core/mcbp/queue_request.cxx +23 -6
- data/ext/couchbase/core/mcbp/queue_request.hxx +21 -0
- data/ext/couchbase/core/meta/features.hxx +13 -0
- data/ext/couchbase/core/meta/version.cxx +6 -3
- data/ext/couchbase/core/metrics/logging_meter.cxx +5 -10
- data/ext/couchbase/core/metrics/meter_wrapper.cxx +63 -33
- data/ext/couchbase/core/metrics/meter_wrapper.hxx +55 -3
- data/ext/couchbase/core/operations/analytics_response_parsing.cxx +177 -0
- data/ext/couchbase/core/operations/analytics_response_parsing.hxx +55 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +48 -130
- data/ext/couchbase/core/operations/document_analytics.hxx +14 -2
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +15 -7
- data/ext/couchbase/core/operations/document_get_any_replica.hxx +19 -8
- data/ext/couchbase/core/operations/document_get_projected.cxx +1 -1
- data/ext/couchbase/core/{impl/get_replica.cxx → operations/document_get_replica.cxx} +21 -3
- data/ext/couchbase/core/{impl/get_replica.hxx → operations/document_get_replica.hxx} +31 -4
- data/ext/couchbase/core/operations/document_lookup_in.cxx +10 -10
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +228 -198
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +215 -217
- data/ext/couchbase/core/operations/document_query.cxx +108 -221
- data/ext/couchbase/core/operations/document_query.hxx +18 -4
- data/ext/couchbase/core/operations/document_search.cxx +52 -8
- data/ext/couchbase/core/operations/document_search.hxx +3 -0
- data/ext/couchbase/core/operations/document_view.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +15 -8
- data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +4 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +2 -1
- data/ext/couchbase/core/operations/management/analytics_index_create.cxx +33 -8
- data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +12 -7
- data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_link_create.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +10 -4
- data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +6 -4
- data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +4 -3
- data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +1 -1
- data/ext/couchbase/core/operations/management/change_password.cxx +2 -0
- data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/error_utils.cxx +60 -6
- data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
- data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
- data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
- data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
- data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
- data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
- data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
- data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
- data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
- data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
- data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
- data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
- data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
- data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
- data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
- data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
- data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
- data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
- data/ext/couchbase/core/operations_fwd.hxx +3 -3
- data/ext/couchbase/core/origin.cxx +54 -26
- data/ext/couchbase/core/origin.hxx +12 -0
- data/ext/couchbase/core/orphan_reporter.cxx +2 -1
- data/ext/couchbase/core/platform/random.cc +7 -7
- data/ext/couchbase/core/protocol/client_request.cxx +2 -2
- data/ext/couchbase/core/protocol/client_request.hxx +38 -21
- data/ext/couchbase/core/protocol/client_response.cxx +11 -3
- data/ext/couchbase/core/protocol/client_response.hxx +27 -6
- data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
- data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
- data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
- data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
- data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
- data/ext/couchbase/core/protocol/datatype.hxx +118 -1
- data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
- data/ext/couchbase/core/protocol/magic.hxx +4 -0
- data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
- data/ext/couchbase/core/protocol/server_request.hxx +3 -1
- data/ext/couchbase/core/protocol/status.cxx +1 -1
- data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
- data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
- data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
- data/ext/couchbase/core/protostellar/component.cxx +2445 -0
- data/ext/couchbase/core/protostellar/component.hxx +391 -0
- data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
- data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
- data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
- data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
- data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
- data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
- data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
- data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
- data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
- data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
- data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
- data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
- data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
- data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
- data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
- data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
- data/ext/couchbase/core/query_stream.cxx +447 -0
- data/ext/couchbase/core/query_stream.hxx +141 -0
- data/ext/couchbase/core/query_stream_component.cxx +243 -0
- data/ext/couchbase/core/query_stream_component.hxx +68 -0
- data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
- data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
- data/ext/couchbase/core/response_handler.hxx +41 -4
- data/ext/couchbase/core/row_streamer.cxx +332 -46
- data/ext/couchbase/core/row_streamer.hxx +31 -1
- data/ext/couchbase/core/row_streamer_options.hxx +55 -0
- data/ext/couchbase/core/sasl/client.h +3 -0
- data/ext/couchbase/core/search_scoring.hxx +66 -0
- data/ext/couchbase/core/stream_error_details.hxx +69 -0
- data/ext/couchbase/core/timeout_defaults.hxx +0 -1
- data/ext/couchbase/core/topology/capabilities.hxx +6 -0
- data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
- data/ext/couchbase/core/topology/configuration.cxx +21 -6
- data/ext/couchbase/core/topology/configuration.hxx +29 -8
- data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
- data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
- data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
- data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
- data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +108 -63
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +19 -2
- data/ext/couchbase/core/transactions/error_list.hxx +2 -2
- data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
- data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
- data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
- data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
- data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
- data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
- data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
- data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
- data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
- data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
- data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
- data/ext/couchbase/core/transactions/transactions.cxx +3 -55
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +165 -72
- data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
- data/ext/couchbase/core/transactions/utils.cxx +10 -0
- data/ext/couchbase/core/transactions/waitable_op_list.hxx +2 -2
- data/ext/couchbase/core/transactions.hxx +9 -9
- data/ext/couchbase/core/utils/byteswap.hxx +166 -9
- data/ext/couchbase/core/utils/connection_string.cxx +50 -85
- data/ext/couchbase/core/utils/connection_string.hxx +15 -0
- data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
- data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
- data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
- data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
- data/ext/couchbase/core/utils/movable_function.hxx +301 -52
- data/ext/couchbase/core/utils/name_codec.hxx +154 -11
- data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
- data/ext/couchbase/core/utils/url_codec.cxx +12 -51
- data/ext/couchbase/core/websocket_codec.cxx +13 -37
- data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
- data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
- data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
- data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
- data/ext/couchbase/couchbase/bucket.hxx +57 -0
- data/ext/couchbase/couchbase/cluster.hxx +183 -5
- data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
- data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
- data/ext/couchbase/couchbase/collection.hxx +234 -14
- data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
- data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
- data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
- data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
- data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/error.hxx +32 -0
- data/ext/couchbase/couchbase/error_codes.hxx +33 -1
- data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
- data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
- data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
- data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
- data/ext/couchbase/couchbase/get_result.hxx +1 -0
- data/ext/couchbase/couchbase/increment_options.hxx +1 -1
- data/ext/couchbase/couchbase/insert_options.hxx +1 -1
- data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/match_query.hxx +1 -1
- data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
- data/ext/couchbase/couchbase/network_options.hxx +1 -1
- data/ext/couchbase/couchbase/node_id.hxx +42 -14
- data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
- data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
- data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
- data/ext/couchbase/couchbase/query_options.hxx +23 -12
- data/ext/couchbase/couchbase/query_row.hxx +111 -0
- data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
- data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
- data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
- data/ext/couchbase/couchbase/replace_options.hxx +3 -3
- data/ext/couchbase/couchbase/result.hxx +14 -3
- data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
- data/ext/couchbase/couchbase/scope.hxx +85 -2
- data/ext/couchbase/couchbase/search_options.hxx +58 -8
- data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
- data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
- data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
- data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
- data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
- data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
- data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
- data/ext/couchbase/couchbase/transactions.hxx +27 -18
- data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
- data/ext/couchbase/couchbase/vector_query.hxx +1 -1
- data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
- data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
- data/ext/extconf.rb +15 -10
- data/ext/rcb_analytics.cxx +82 -102
- data/ext/rcb_backend.cxx +42 -36
- data/ext/rcb_backend.hxx +2 -0
- data/ext/rcb_buckets.cxx +47 -59
- data/ext/rcb_collections.cxx +42 -52
- data/ext/rcb_crud.cxx +345 -224
- data/ext/rcb_diagnostics.cxx +117 -27
- data/ext/rcb_exceptions.cxx +152 -99
- data/ext/rcb_exceptions.hxx +25 -0
- data/ext/rcb_extras.cxx +18 -19
- data/ext/rcb_hdr_histogram.cxx +19 -4
- data/ext/rcb_logger.cxx +202 -27
- data/ext/rcb_logger.hxx +12 -0
- data/ext/rcb_multi.cxx +40 -40
- data/ext/rcb_observability.cxx +7 -5
- data/ext/rcb_query.cxx +99 -142
- data/ext/rcb_range_scan.cxx +41 -35
- data/ext/rcb_search.cxx +98 -99
- data/ext/rcb_users.cxx +36 -56
- data/ext/rcb_utils.cxx +100 -37
- data/ext/rcb_utils.hxx +287 -33
- data/ext/rcb_version.cxx +1 -1
- data/ext/rcb_views.cxx +55 -51
- data/lib/active_support/cache/couchbase_store.rb +77 -12
- data/lib/couchbase/bucket.rb +20 -0
- data/lib/couchbase/cluster.rb +17 -0
- data/lib/couchbase/collection.rb +36 -1
- data/lib/couchbase/errors.rb +18 -0
- data/lib/couchbase/fork_hooks.rb +16 -7
- data/lib/couchbase/get_replica_strategy.rb +89 -0
- data/lib/couchbase/logger.rb +1 -1
- data/lib/couchbase/management/analytics_index_manager.rb +15 -15
- data/lib/couchbase/management/bucket_manager.rb +6 -6
- data/lib/couchbase/management/collection_manager.rb +6 -6
- data/lib/couchbase/management/query_index_manager.rb +7 -7
- data/lib/couchbase/management/search_index_manager.rb +13 -13
- data/lib/couchbase/management/user_manager.rb +10 -10
- data/lib/couchbase/management/view_index_manager.rb +5 -5
- data/lib/couchbase/options.rb +174 -42
- data/lib/couchbase/protostellar/bucket.rb +4 -0
- data/lib/couchbase/protostellar/cluster.rb +4 -0
- data/lib/couchbase/protostellar/collection.rb +4 -0
- data/lib/couchbase/protostellar/error_handling.rb +2 -1
- data/lib/couchbase/protostellar/request.rb +1 -0
- data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
- data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
- data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
- data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
- data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
- data/lib/couchbase/search_options.rb +95 -6
- data/lib/couchbase/version.rb +1 -1
- metadata +91 -33
- data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
- data/ext/couchbase/core/columnar/agent.hxx +0 -71
- data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
- data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
- data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
- data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
- data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
- data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
- data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
- data/ext/couchbase/core/columnar/error.hxx +0 -51
- data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
- data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
- data/ext/couchbase/core/columnar/management_component.cxx +0 -300
- data/ext/couchbase/core/columnar/management_component.hxx +0 -56
- data/ext/couchbase/core/columnar/query_component.cxx +0 -523
- data/ext/couchbase/core/columnar/query_component.hxx +0 -57
- data/ext/couchbase/core/columnar/query_options.hxx +0 -59
- data/ext/couchbase/core/columnar/query_result.cxx +0 -130
- data/ext/couchbase/core/columnar/query_result.hxx +0 -78
- data/ext/couchbase/core/io/config_tracker.cxx +0 -687
- data/ext/couchbase/core/io/config_tracker.hxx +0 -123
|
@@ -1,523 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2024. Couchbase, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#include "query_component.hxx"
|
|
19
|
-
|
|
20
|
-
#include "backoff_calculator.hxx"
|
|
21
|
-
#include "core/free_form_http_request.hxx"
|
|
22
|
-
#include "core/http_component.hxx"
|
|
23
|
-
#include "core/logger/logger.hxx"
|
|
24
|
-
#include "core/pending_operation_connection_info.hxx"
|
|
25
|
-
#include "core/platform/uuid.h"
|
|
26
|
-
#include "core/row_streamer.hxx"
|
|
27
|
-
#include "core/service_type.hxx"
|
|
28
|
-
#include "core/utils/json.hxx"
|
|
29
|
-
#include "error.hxx"
|
|
30
|
-
#include "error_codes.hxx"
|
|
31
|
-
#include "query_result.hxx"
|
|
32
|
-
#include "retry_info.hxx"
|
|
33
|
-
|
|
34
|
-
#include <asio/io_context.hpp>
|
|
35
|
-
#include <asio/steady_timer.hpp>
|
|
36
|
-
#include <gsl/util>
|
|
37
|
-
#include <spdlog/fmt/bundled/chrono.h>
|
|
38
|
-
#include <spdlog/fmt/bundled/core.h>
|
|
39
|
-
#include <tao/json/value.hpp>
|
|
40
|
-
#include <tl/expected.hpp>
|
|
41
|
-
|
|
42
|
-
#include <cstdint>
|
|
43
|
-
#include <memory>
|
|
44
|
-
#include <mutex>
|
|
45
|
-
#include <string>
|
|
46
|
-
#include <system_error>
|
|
47
|
-
#include <utility>
|
|
48
|
-
#include <vector>
|
|
49
|
-
|
|
50
|
-
namespace couchbase::core::columnar
|
|
51
|
-
{
|
|
52
|
-
class pending_query_operation
|
|
53
|
-
: public std::enable_shared_from_this<pending_query_operation>
|
|
54
|
-
, public pending_operation
|
|
55
|
-
{
|
|
56
|
-
public:
|
|
57
|
-
pending_query_operation(const query_options& options,
|
|
58
|
-
asio::io_context& io,
|
|
59
|
-
http_component& http,
|
|
60
|
-
std::chrono::milliseconds default_timeout)
|
|
61
|
-
: client_context_id_{ uuid::to_string(uuid::random()) }
|
|
62
|
-
, timeout_{ options.timeout.value_or(default_timeout) }
|
|
63
|
-
, payload_(build_query_payload(options))
|
|
64
|
-
, http_req_{ build_query_request(options) }
|
|
65
|
-
, io_{ io }
|
|
66
|
-
, deadline_{ io_ }
|
|
67
|
-
, retry_timer_{ io_ }
|
|
68
|
-
, http_{ http }
|
|
69
|
-
{
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
auto invoke_callback(query_result res, error err)
|
|
73
|
-
{
|
|
74
|
-
const std::scoped_lock lock{ callback_mutex_ };
|
|
75
|
-
if (auto cb = std::move(callback_); cb) {
|
|
76
|
-
cb(std::move(res), std::move(err));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
auto dispatch() -> error
|
|
81
|
-
{
|
|
82
|
-
auto op = http_.do_http_request(
|
|
83
|
-
http_req_, [self = shared_from_this()](auto resp, error_union err) mutable {
|
|
84
|
-
std::shared_ptr<pending_operation> op;
|
|
85
|
-
{
|
|
86
|
-
const std::scoped_lock lock{ self->pending_op_mutex_ };
|
|
87
|
-
std::swap(op, self->pending_op_);
|
|
88
|
-
}
|
|
89
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
90
|
-
if (std::holds_alternative<impl::bootstrap_error>(err)) {
|
|
91
|
-
auto bootstrap_error = std::get<impl::bootstrap_error>(err);
|
|
92
|
-
auto message = fmt::format(
|
|
93
|
-
"Failed to execute the HTTP request for the query due to a bootstrap error. "
|
|
94
|
-
"See logs for further details. bootstrap_error.message={}",
|
|
95
|
-
bootstrap_error.error_message);
|
|
96
|
-
self->invoke_callback({}, { maybe_convert_error_code(bootstrap_error.ec), message });
|
|
97
|
-
} else {
|
|
98
|
-
auto ec = maybe_convert_error_code(std::get<std::error_code>(err));
|
|
99
|
-
if (ec == errc::timeout) {
|
|
100
|
-
return self->trigger_timeout();
|
|
101
|
-
}
|
|
102
|
-
self->invoke_callback({}, { ec, "Failed to execute the HTTP request for the query" });
|
|
103
|
-
}
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
// op can be null if the pending_query_operation was cancelled.
|
|
107
|
-
if (op) {
|
|
108
|
-
auto op_info = std::dynamic_pointer_cast<pending_operation_connection_info>(op);
|
|
109
|
-
self->retry_info_.last_dispatched_from = op_info->dispatched_from();
|
|
110
|
-
self->retry_info_.last_dispatched_to = op_info->dispatched_to();
|
|
111
|
-
self->retry_info_.last_dispatched_to_host = op_info->dispatched_to_host();
|
|
112
|
-
}
|
|
113
|
-
auto streamer = std::make_shared<row_streamer>(self->io_, resp.body(), "/results/^");
|
|
114
|
-
return streamer->start(
|
|
115
|
-
[self, streamer, resp = std::move(resp)](const auto& metadata_header, auto ec) mutable {
|
|
116
|
-
if (ec) {
|
|
117
|
-
self->invoke_callback({}, { maybe_convert_error_code(ec) });
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
auto error_parse_res =
|
|
121
|
-
self->parse_error(resp.status_code(), utils::json::parse(metadata_header));
|
|
122
|
-
|
|
123
|
-
if (error_parse_res.retriable) {
|
|
124
|
-
self->retry_info_.last_error = error_parse_res.err;
|
|
125
|
-
return self->maybe_retry();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (error_parse_res.err) {
|
|
129
|
-
self->invoke_callback({}, { error_parse_res.err });
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
self->invoke_callback(query_result{ std::move(*streamer) }, {});
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
if (op.has_value()) {
|
|
137
|
-
const std::scoped_lock lock{ pending_op_mutex_ };
|
|
138
|
-
pending_op_ = op.value();
|
|
139
|
-
return {};
|
|
140
|
-
}
|
|
141
|
-
retry_timer_.cancel();
|
|
142
|
-
deadline_.cancel();
|
|
143
|
-
error return_error{};
|
|
144
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
145
|
-
if (std::holds_alternative<impl::bootstrap_error>(op.error())) {
|
|
146
|
-
auto bootstrap_error = std::get<impl::bootstrap_error>(op.error());
|
|
147
|
-
auto message =
|
|
148
|
-
fmt::format("Failed to create the HTTP pending operation due to a bootstrap error. "
|
|
149
|
-
"See logs for further details. bootstrap_error.message={}",
|
|
150
|
-
bootstrap_error.error_message);
|
|
151
|
-
return_error.ec = bootstrap_error.ec;
|
|
152
|
-
return_error.message = message;
|
|
153
|
-
} else {
|
|
154
|
-
return_error.ec = std::get<std::error_code>(op.error());
|
|
155
|
-
return_error.message = "Failed to create the HTTP pending operation.";
|
|
156
|
-
}
|
|
157
|
-
#else
|
|
158
|
-
return_error.ec = op.error();
|
|
159
|
-
#endif
|
|
160
|
-
invoke_callback({}, return_error);
|
|
161
|
-
return return_error;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
auto start(query_callback&& callback) -> error
|
|
165
|
-
{
|
|
166
|
-
callback_ = std::move(callback);
|
|
167
|
-
|
|
168
|
-
deadline_.expires_after(timeout_);
|
|
169
|
-
deadline_.async_wait([self = shared_from_this()](auto ec) {
|
|
170
|
-
if (ec == asio::error::operation_aborted) {
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
CB_LOG_DEBUG(R"(Columnar Query request timed out: retry_attempts={})",
|
|
174
|
-
self->retry_info_.retry_attempts);
|
|
175
|
-
self->trigger_timeout();
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
return dispatch();
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
void cancel() override
|
|
182
|
-
{
|
|
183
|
-
cancelled_ = true;
|
|
184
|
-
retry_timer_.cancel();
|
|
185
|
-
deadline_.cancel();
|
|
186
|
-
std::shared_ptr<pending_operation> op;
|
|
187
|
-
{
|
|
188
|
-
const std::scoped_lock lock{ pending_op_mutex_ };
|
|
189
|
-
std::swap(op, pending_op_);
|
|
190
|
-
}
|
|
191
|
-
if (op) {
|
|
192
|
-
op->cancel();
|
|
193
|
-
}
|
|
194
|
-
// This will only call the callback if it has not already been called (e.g. in the case of a
|
|
195
|
-
// timeout).
|
|
196
|
-
invoke_callback({},
|
|
197
|
-
{ couchbase::core::columnar::client_errc::canceled,
|
|
198
|
-
"The query operation was canceled by the caller." });
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private:
|
|
202
|
-
void update_http_request_timeout()
|
|
203
|
-
{
|
|
204
|
-
http_req_.timeout = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
205
|
-
deadline_.expiry() - std::chrono::steady_clock::now());
|
|
206
|
-
const auto server_timeout = http_req_.timeout + std::chrono::seconds(5);
|
|
207
|
-
payload_["timeout"] = fmt::format("{}ms", server_timeout.count());
|
|
208
|
-
http_req_.body = couchbase::core::utils::json::generate(payload_);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
void maybe_retry()
|
|
212
|
-
{
|
|
213
|
-
if (cancelled_) {
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
auto backoff = backoff_calculator_(retry_info_.retry_attempts);
|
|
217
|
-
if (std::chrono::steady_clock::now() + backoff >= deadline_.expiry()) {
|
|
218
|
-
// Retrying will exceed the deadline, time out immediately instead.
|
|
219
|
-
return trigger_timeout();
|
|
220
|
-
}
|
|
221
|
-
retry_timer_.expires_after(backoff);
|
|
222
|
-
retry_timer_.async_wait([self = shared_from_this()](auto ec) {
|
|
223
|
-
if (ec == asio::error::operation_aborted) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
self->retry_info_.retry_attempts++;
|
|
227
|
-
self->http_req_.internal.undesired_endpoint = self->retry_info_.last_dispatched_to;
|
|
228
|
-
self->update_http_request_timeout();
|
|
229
|
-
CB_LOG_DEBUG(
|
|
230
|
-
"Retrying Query: client_context_id={}, http_timeout={}, retry_attempt={}, errors={}",
|
|
231
|
-
self->client_context_id_,
|
|
232
|
-
self->http_req_.timeout,
|
|
233
|
-
self->retry_info_.retry_attempts,
|
|
234
|
-
utils::json::generate(self->retry_info_.last_error.ctx["errors"]));
|
|
235
|
-
auto err = self->dispatch();
|
|
236
|
-
if (err) {
|
|
237
|
-
self->invoke_callback({}, std::move(err));
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
void trigger_timeout()
|
|
243
|
-
{
|
|
244
|
-
error err{ errc::timeout };
|
|
245
|
-
enhance_error(err);
|
|
246
|
-
invoke_callback({}, err);
|
|
247
|
-
cancel();
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
auto build_query_payload(const query_options& options) -> tao::json::value
|
|
251
|
-
{
|
|
252
|
-
tao::json::value payload{ { "statement", options.statement },
|
|
253
|
-
{ "client_context_id", client_context_id_ } };
|
|
254
|
-
if (options.database_name.has_value() && options.scope_name.has_value()) {
|
|
255
|
-
payload["query_context"] =
|
|
256
|
-
fmt::format("default:`{}`.`{}`", options.database_name.value(), options.scope_name.value());
|
|
257
|
-
}
|
|
258
|
-
if (!options.positional_parameters.empty()) {
|
|
259
|
-
std::vector<tao::json::value> params_json;
|
|
260
|
-
params_json.reserve(options.positional_parameters.size());
|
|
261
|
-
for (const auto& val : options.positional_parameters) {
|
|
262
|
-
params_json.emplace_back(utils::json::parse(val));
|
|
263
|
-
}
|
|
264
|
-
payload["args"] = std::move(params_json);
|
|
265
|
-
}
|
|
266
|
-
for (const auto& [name, val] : options.named_parameters) {
|
|
267
|
-
std::string key = name;
|
|
268
|
-
if (key[0] != '$') {
|
|
269
|
-
key.insert(key.begin(), '$');
|
|
270
|
-
}
|
|
271
|
-
payload[key] = utils::json::parse(val);
|
|
272
|
-
}
|
|
273
|
-
if (options.read_only.has_value()) {
|
|
274
|
-
payload["readonly"] = options.read_only.value();
|
|
275
|
-
}
|
|
276
|
-
if (options.scan_consistency.has_value()) {
|
|
277
|
-
switch (options.scan_consistency.value()) {
|
|
278
|
-
case query_scan_consistency::not_bounded:
|
|
279
|
-
payload["scan_consistency"] = "not_bounded";
|
|
280
|
-
break;
|
|
281
|
-
case query_scan_consistency::request_plus:
|
|
282
|
-
payload["scan_consistency"] = "request_plus";
|
|
283
|
-
break;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const std::chrono::milliseconds server_timeout = timeout_ + std::chrono::seconds(5);
|
|
288
|
-
payload["timeout"] = fmt::format("{}ms", server_timeout.count());
|
|
289
|
-
|
|
290
|
-
for (const auto& [key, val] : options.raw) {
|
|
291
|
-
payload[key] = utils::json::parse(val);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return payload;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
auto build_query_request(const query_options& options) -> http_request
|
|
298
|
-
{
|
|
299
|
-
http_request req{ service_type::analytics, "POST" };
|
|
300
|
-
req.path = "/api/v1/request";
|
|
301
|
-
req.body = utils::json::generate(payload_);
|
|
302
|
-
req.timeout = timeout_;
|
|
303
|
-
|
|
304
|
-
req.client_context_id = client_context_id_;
|
|
305
|
-
req.headers["connection"] = "keep-alive";
|
|
306
|
-
req.headers["content-type"] = "application/json";
|
|
307
|
-
if (options.priority.has_value() && options.priority.value()) {
|
|
308
|
-
req.headers["analytics-priority"] = "-1";
|
|
309
|
-
}
|
|
310
|
-
if (options.read_only.has_value()) {
|
|
311
|
-
req.is_read_only = options.read_only.value();
|
|
312
|
-
}
|
|
313
|
-
CB_LOG_DEBUG("QUERY REQUEST: client_context_id={}, body={}.", client_context_id_, req.body);
|
|
314
|
-
return req;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
struct error_parse_result {
|
|
318
|
-
error err{};
|
|
319
|
-
bool retriable{ false };
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
void enhance_error(error& err)
|
|
323
|
-
{
|
|
324
|
-
err.ctx["retry_attempts"] = retry_info_.retry_attempts;
|
|
325
|
-
err.ctx["last_dispatched_to"] = retry_info_.last_dispatched_to;
|
|
326
|
-
err.ctx["last_dispatched_from"] = retry_info_.last_dispatched_from;
|
|
327
|
-
|
|
328
|
-
// When reporting a timeout that is a result of an operation being retried, the last set of
|
|
329
|
-
// retryable errors should be listed.
|
|
330
|
-
if (err.ec == errc::timeout && retry_info_.last_error) {
|
|
331
|
-
if (const auto* e = retry_info_.last_error.ctx.find("errors"); e != nullptr) {
|
|
332
|
-
err.ctx["last_errors"] = e->get_array();
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
auto parse_error(const std::uint32_t& http_status_code,
|
|
338
|
-
const tao::json::value& metadata_header) -> error_parse_result
|
|
339
|
-
{
|
|
340
|
-
const auto* errors_json = metadata_header.find("errors");
|
|
341
|
-
if (errors_json == nullptr) {
|
|
342
|
-
return {};
|
|
343
|
-
}
|
|
344
|
-
CB_LOG_DEBUG("QUERY ERROR (client_context_id={}): {}.",
|
|
345
|
-
client_context_id_,
|
|
346
|
-
utils::json::generate(errors_json));
|
|
347
|
-
if (!errors_json->is_array()) {
|
|
348
|
-
return { { errc::generic,
|
|
349
|
-
"Could not parse errors from server response - expected JSON array" } };
|
|
350
|
-
}
|
|
351
|
-
if (errors_json->get_array().empty()) {
|
|
352
|
-
return {};
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
error_parse_result res;
|
|
356
|
-
res.retriable = true;
|
|
357
|
-
res.err.ctx["http_status"] = std::to_string(http_status_code);
|
|
358
|
-
res.err.ctx["errors"] = std::vector<tao::json::value>{};
|
|
359
|
-
enhance_error(res.err);
|
|
360
|
-
|
|
361
|
-
if (http_status_code == 401) {
|
|
362
|
-
res.err.ec = errc::invalid_credential;
|
|
363
|
-
} else {
|
|
364
|
-
res.err.ec = errc::query_error;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
std::int32_t first_error_code{ 0 };
|
|
368
|
-
std::string first_error_msg{};
|
|
369
|
-
|
|
370
|
-
std::int32_t first_non_retr_error_code{ 0 };
|
|
371
|
-
std::string first_non_retr_error_msg{};
|
|
372
|
-
|
|
373
|
-
for (auto error_json : errors_json->get_array()) {
|
|
374
|
-
bool retr{ false }; // An error is assumed to not be retriable if the field is missing
|
|
375
|
-
{
|
|
376
|
-
auto* r = error_json.find("retriable");
|
|
377
|
-
if (r != nullptr) {
|
|
378
|
-
if (!r->is_boolean()) {
|
|
379
|
-
return {
|
|
380
|
-
{ errc::generic,
|
|
381
|
-
"Could not parse error from server response - 'retriable' was not boolean" }
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
retr = r->get_boolean();
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// Operation is retriable iff all errors are retriable
|
|
389
|
-
res.retriable = res.retriable && retr;
|
|
390
|
-
|
|
391
|
-
std::string msg{};
|
|
392
|
-
{
|
|
393
|
-
auto* m = error_json.find("msg");
|
|
394
|
-
if (m == nullptr) {
|
|
395
|
-
return { { errc::generic,
|
|
396
|
-
"Could not parse error from server response - could not find 'msg' field" } };
|
|
397
|
-
}
|
|
398
|
-
if (!m->is_string()) {
|
|
399
|
-
return { { errc::generic,
|
|
400
|
-
"Could not parse error from server response - 'msg' field was not string" } };
|
|
401
|
-
}
|
|
402
|
-
msg = m->get_string();
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
std::int32_t code{};
|
|
406
|
-
{
|
|
407
|
-
auto* c = error_json.find("code");
|
|
408
|
-
if (c == nullptr) {
|
|
409
|
-
return { { errc::generic,
|
|
410
|
-
"Could not parse error from server response - could not find 'code' field" } };
|
|
411
|
-
}
|
|
412
|
-
if (!(c->is_unsigned() || c->is_signed())) {
|
|
413
|
-
return {
|
|
414
|
-
{ errc::generic,
|
|
415
|
-
"Could not parse error from server response - 'code' field was not an integer" }
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
code = c->is_signed() ? gsl::narrow_cast<std::int32_t>(c->get_signed())
|
|
419
|
-
: gsl::narrow_cast<std::int32_t>(c->get_unsigned());
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
tao::json::value error = {
|
|
423
|
-
{ "code", code },
|
|
424
|
-
{ "msg", msg },
|
|
425
|
-
};
|
|
426
|
-
res.err.ctx["errors"].get_array().emplace_back(std::move(error));
|
|
427
|
-
|
|
428
|
-
if (first_error_code == 0) {
|
|
429
|
-
first_error_code = code;
|
|
430
|
-
first_error_msg = msg;
|
|
431
|
-
}
|
|
432
|
-
if (!retr && first_non_retr_error_code == 0) {
|
|
433
|
-
first_non_retr_error_code = code;
|
|
434
|
-
first_non_retr_error_msg = msg;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
switch (code) {
|
|
438
|
-
case 20000:
|
|
439
|
-
res.err.ec = errc::invalid_credential;
|
|
440
|
-
break;
|
|
441
|
-
case 21002:
|
|
442
|
-
res.err.ec = errc::timeout;
|
|
443
|
-
break;
|
|
444
|
-
default:
|
|
445
|
-
break;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
if (res.err.ec == errc::query_error) {
|
|
450
|
-
// If any of the errors is not retriable, report the first non-retriable code/message in the
|
|
451
|
-
// error properties
|
|
452
|
-
if (first_non_retr_error_code != 0) {
|
|
453
|
-
res.err.properties =
|
|
454
|
-
query_error_properties{ first_non_retr_error_code, first_non_retr_error_msg };
|
|
455
|
-
} else {
|
|
456
|
-
res.err.properties = query_error_properties{ first_error_code, first_error_msg };
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
return res;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
std::string client_context_id_;
|
|
464
|
-
std::chrono::milliseconds timeout_;
|
|
465
|
-
tao::json::value payload_;
|
|
466
|
-
http_request http_req_;
|
|
467
|
-
asio::io_context& io_;
|
|
468
|
-
asio::steady_timer deadline_;
|
|
469
|
-
asio::steady_timer retry_timer_;
|
|
470
|
-
http_component& http_;
|
|
471
|
-
query_callback callback_{};
|
|
472
|
-
std::mutex callback_mutex_{};
|
|
473
|
-
std::shared_ptr<pending_operation> pending_op_{};
|
|
474
|
-
std::mutex pending_op_mutex_{};
|
|
475
|
-
std::atomic_bool cancelled_{ false };
|
|
476
|
-
backoff_calculator backoff_calculator_{ default_backoff_calculator };
|
|
477
|
-
retry_info retry_info_{};
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
class query_component_impl : public std::enable_shared_from_this<query_component_impl>
|
|
481
|
-
{
|
|
482
|
-
public:
|
|
483
|
-
query_component_impl(asio::io_context& io,
|
|
484
|
-
http_component http,
|
|
485
|
-
std::chrono::milliseconds default_timeout)
|
|
486
|
-
: io_{ io }
|
|
487
|
-
, http_{ std::move(http) }
|
|
488
|
-
, default_timeout_{ default_timeout }
|
|
489
|
-
{
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
auto execute_query(const query_options& options, query_callback&& callback)
|
|
493
|
-
-> tl::expected<std::shared_ptr<pending_operation>, error>
|
|
494
|
-
{
|
|
495
|
-
auto op = std::make_shared<pending_query_operation>(options, io_, http_, default_timeout_);
|
|
496
|
-
auto err = op->start(std::move(callback));
|
|
497
|
-
if (err) {
|
|
498
|
-
return tl::unexpected<error>(err);
|
|
499
|
-
}
|
|
500
|
-
return op;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
private:
|
|
504
|
-
asio::io_context& io_;
|
|
505
|
-
http_component http_;
|
|
506
|
-
std::chrono::milliseconds default_timeout_;
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
query_component::query_component(asio::io_context& io,
|
|
510
|
-
core::http_component http,
|
|
511
|
-
std::chrono::milliseconds default_timeout)
|
|
512
|
-
: impl_{ std::make_shared<query_component_impl>(io, std::move(http), default_timeout) }
|
|
513
|
-
{
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
auto
|
|
517
|
-
query_component::execute_query(const query_options& options, query_callback&& callback)
|
|
518
|
-
-> tl::expected<std::shared_ptr<pending_operation>, error>
|
|
519
|
-
{
|
|
520
|
-
return impl_->execute_query(options, std::move(callback));
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
} // namespace couchbase::core::columnar
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2024. Couchbase, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#pragma once
|
|
19
|
-
|
|
20
|
-
#include "core/impl/bootstrap_error.hxx"
|
|
21
|
-
#include "core/pending_operation.hxx"
|
|
22
|
-
#include "error.hxx"
|
|
23
|
-
#include "query_options.hxx"
|
|
24
|
-
|
|
25
|
-
#include <chrono>
|
|
26
|
-
#include <memory>
|
|
27
|
-
|
|
28
|
-
#include <tl/expected.hpp>
|
|
29
|
-
|
|
30
|
-
namespace asio
|
|
31
|
-
{
|
|
32
|
-
class io_context;
|
|
33
|
-
} // namespace asio
|
|
34
|
-
|
|
35
|
-
namespace couchbase::core
|
|
36
|
-
{
|
|
37
|
-
class http_component;
|
|
38
|
-
|
|
39
|
-
namespace columnar
|
|
40
|
-
{
|
|
41
|
-
class query_component_impl;
|
|
42
|
-
|
|
43
|
-
class query_component
|
|
44
|
-
{
|
|
45
|
-
public:
|
|
46
|
-
query_component(asio::io_context& io,
|
|
47
|
-
http_component http,
|
|
48
|
-
std::chrono::milliseconds default_timeout);
|
|
49
|
-
|
|
50
|
-
auto execute_query(const query_options& options, query_callback&& callback)
|
|
51
|
-
-> tl::expected<std::shared_ptr<pending_operation>, error>;
|
|
52
|
-
|
|
53
|
-
private:
|
|
54
|
-
std::shared_ptr<query_component_impl> impl_;
|
|
55
|
-
};
|
|
56
|
-
} // namespace columnar
|
|
57
|
-
} // namespace couchbase::core
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2024. Couchbase, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#pragma once
|
|
19
|
-
|
|
20
|
-
#include "error.hxx"
|
|
21
|
-
#include "query_result.hxx"
|
|
22
|
-
|
|
23
|
-
#include "core/json_string.hxx"
|
|
24
|
-
#include "core/utils/movable_function.hxx"
|
|
25
|
-
|
|
26
|
-
#include <chrono>
|
|
27
|
-
#include <map>
|
|
28
|
-
#include <optional>
|
|
29
|
-
#include <string>
|
|
30
|
-
#include <system_error>
|
|
31
|
-
#include <vector>
|
|
32
|
-
|
|
33
|
-
namespace couchbase::core::columnar
|
|
34
|
-
{
|
|
35
|
-
enum class query_scan_consistency : std::uint8_t {
|
|
36
|
-
not_bounded,
|
|
37
|
-
request_plus,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
struct query_options {
|
|
41
|
-
// Required
|
|
42
|
-
std::string statement;
|
|
43
|
-
|
|
44
|
-
// Optional - should be set if query is at scope-level
|
|
45
|
-
std::optional<std::string> database_name{};
|
|
46
|
-
std::optional<std::string> scope_name{};
|
|
47
|
-
|
|
48
|
-
// Optional - not sent on the wire if unset
|
|
49
|
-
std::optional<bool> priority{};
|
|
50
|
-
std::vector<couchbase::core::json_string> positional_parameters{};
|
|
51
|
-
std::map<std::string, couchbase::core::json_string> named_parameters{};
|
|
52
|
-
std::optional<bool> read_only{};
|
|
53
|
-
std::optional<query_scan_consistency> scan_consistency{};
|
|
54
|
-
std::map<std::string, couchbase::core::json_string> raw{};
|
|
55
|
-
std::optional<std::chrono::milliseconds> timeout{};
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
using query_callback = utils::movable_function<void(query_result result, error err)>;
|
|
59
|
-
} // namespace couchbase::core::columnar
|