couchbase 3.8.1 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- 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 +214 -155
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +130 -21
- 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 +10 -3
- 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 +1554 -398
- 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 +325 -25
- 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 +66 -0
- 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 +316 -317
- 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 +275 -14
- data/ext/couchbase/core/io/streams.hxx +53 -0
- 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/bucket_create.cxx +37 -38
- data/ext/couchbase/core/operations/management/bucket_update.cxx +26 -28
- 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 +59 -5
- 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 +362 -241
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +24 -3
- 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 +194 -66
- 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 +15 -4
- 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 +3 -29
- 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 +216 -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 +32 -0
- 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 +33 -14
- 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 +181 -44
- 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 +92 -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
|
@@ -84,7 +84,27 @@ public:
|
|
|
84
84
|
watch_context(const watch_context&) = delete;
|
|
85
85
|
auto operator=(const watch_context&) -> watch_context& = delete;
|
|
86
86
|
auto operator=(watch_context&&) -> watch_context& = delete;
|
|
87
|
-
|
|
87
|
+
|
|
88
|
+
~watch_context()
|
|
89
|
+
{
|
|
90
|
+
// Fail closed. During the polling-interval backoff the context is kept alive only by its own
|
|
91
|
+
// timer on the io_context; if the io_context is torn down then, that pending wait is dropped
|
|
92
|
+
// without running and the context is destroyed here with handler_ still set. Deliver an error
|
|
93
|
+
// so a std::future caller never observes broken_promise and a callback caller never hangs. (The
|
|
94
|
+
// GET-ALL request phase already fails closed -- core_.execute delivers request_canceled on
|
|
95
|
+
// close.) A moved-from context has an empty handler_, so this is a no-op there. Mirror
|
|
96
|
+
// finish(): move the handler out before invoking it and end the observability span, so the
|
|
97
|
+
// watch metrics are not left dangling on shutdown.
|
|
98
|
+
if (handler_) {
|
|
99
|
+
watch_query_indexes_handler handler{};
|
|
100
|
+
std::swap(handler, handler_);
|
|
101
|
+
try {
|
|
102
|
+
observability_recorder_->finish(errc::network::cluster_closed);
|
|
103
|
+
handler(couchbase::error{ errc::network::cluster_closed });
|
|
104
|
+
} catch (...) { // NOLINT(bugprone-empty-catch)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
88
108
|
|
|
89
109
|
void execute()
|
|
90
110
|
{
|
|
@@ -412,6 +432,39 @@ public:
|
|
|
412
432
|
collection_name,
|
|
413
433
|
options.parent_span);
|
|
414
434
|
|
|
435
|
+
// A closed cluster is the only thing origin() reports an error for, and it cannot be asked
|
|
436
|
+
// which transport it is on. Report it here rather than routing on a state that could not be
|
|
437
|
+
// read: the composite below would open a sub-operation span for a request it never sends.
|
|
438
|
+
const auto [origin_ec, origin] = core_.origin();
|
|
439
|
+
if (origin_ec) {
|
|
440
|
+
top_obs_rec->finish(origin_ec);
|
|
441
|
+
return handler(couchbase::error{ origin_ec });
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Over couchbase2 the gateway does server-side what the two round trips below do here:
|
|
445
|
+
// BuildDeferredIndexes takes the keyspace and builds every deferred index in it. RFC 77 lists
|
|
446
|
+
// it among the single operations rather than the composite ones -- only WatchIndexes is
|
|
447
|
+
// composite there -- so it is dispatched as one request and carries no sub-operation spans.
|
|
448
|
+
if (origin.uses_protostellar()) {
|
|
449
|
+
core::operations::management::query_index_build_deferred_request request{
|
|
450
|
+
bucket_name,
|
|
451
|
+
scope_name.empty() ? std::optional<std::string>{}
|
|
452
|
+
: std::optional<std::string>{ scope_name },
|
|
453
|
+
collection_name.empty() ? std::optional<std::string>{}
|
|
454
|
+
: std::optional<std::string>{ collection_name },
|
|
455
|
+
{},
|
|
456
|
+
{},
|
|
457
|
+
timeout,
|
|
458
|
+
top_obs_rec->operation_span(),
|
|
459
|
+
};
|
|
460
|
+
return core_.execute(
|
|
461
|
+
std::move(request),
|
|
462
|
+
[top_obs_rec = std::move(top_obs_rec), handler = std::move(handler)](const auto& resp) {
|
|
463
|
+
top_obs_rec->finish(resp.ctx.retry_attempts, resp.ctx.ec);
|
|
464
|
+
handler(core::impl::make_error(resp.ctx));
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
|
|
415
468
|
auto get_all_deferred_obs_rec = create_suboperation_observability_recorder(
|
|
416
469
|
core::tracing::operation::mgr_query_get_all_deferred_indexes,
|
|
417
470
|
bucket_name,
|
|
@@ -18,10 +18,111 @@
|
|
|
18
18
|
|
|
19
19
|
#include "replica_utils.hxx"
|
|
20
20
|
|
|
21
|
+
#include "core/impl/error.hxx"
|
|
21
22
|
#include "core/logger/logger.hxx"
|
|
22
23
|
|
|
24
|
+
#include <couchbase/error_codes.hxx>
|
|
25
|
+
|
|
26
|
+
#include <cstddef>
|
|
27
|
+
#include <optional>
|
|
28
|
+
#include <utility>
|
|
29
|
+
|
|
23
30
|
namespace couchbase::core::impl
|
|
24
31
|
{
|
|
32
|
+
auto
|
|
33
|
+
make_get_replica_error(const key_value_error_context& ctx) -> couchbase::error
|
|
34
|
+
{
|
|
35
|
+
if (ctx.ec() != errc::key_value::document_not_found) {
|
|
36
|
+
return make_error(ctx);
|
|
37
|
+
}
|
|
38
|
+
auto cause = make_error(ctx);
|
|
39
|
+
auto error_context = cause.ctx();
|
|
40
|
+
return { errc::key_value::document_not_found_on_replica,
|
|
41
|
+
{},
|
|
42
|
+
std::move(error_context),
|
|
43
|
+
std::move(cause),
|
|
44
|
+
ctx.last_dispatched_to_node_id() };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
auto
|
|
48
|
+
resolve_replica_index(const topology::configuration& config,
|
|
49
|
+
std::uint16_t vbucket,
|
|
50
|
+
std::size_t requested_replica,
|
|
51
|
+
bool wrap) -> replica_route_decision
|
|
52
|
+
{
|
|
53
|
+
replica_route_decision decision{};
|
|
54
|
+
decision.partition = vbucket;
|
|
55
|
+
|
|
56
|
+
if (!config.vbmap.has_value() || vbucket >= config.vbmap->size()) {
|
|
57
|
+
return decision;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!config.num_replicas.has_value()) {
|
|
61
|
+
// The configured count and the map are parsed independently, so a map can
|
|
62
|
+
// arrive without a count. Bounds cannot be decided without it, and taking
|
|
63
|
+
// the row as the count would route to a copy the bucket may not advertise,
|
|
64
|
+
// so this is treated the same as a map that has not arrived.
|
|
65
|
+
return decision;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// num_replicas bounds the index; the vbucket-map row bounds what is readable.
|
|
69
|
+
// A rebalance reshapes the rows after the new count is published, so a row
|
|
70
|
+
// can be shorter than the count. Such an index is valid and not yet readable,
|
|
71
|
+
// so it is not out of bounds.
|
|
72
|
+
const auto number_of_replicas = std::size_t{ *config.num_replicas };
|
|
73
|
+
if (number_of_replicas == 0) {
|
|
74
|
+
// This also keeps the wrap modulo below from dividing by zero.
|
|
75
|
+
decision.ec = errc::key_value::replica_index_out_of_bounds;
|
|
76
|
+
return decision;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// The row carries the active at position 0, so replica N is at N + 1 and the
|
|
80
|
+
// chain is one shorter than the row.
|
|
81
|
+
const auto& chain = config.vbmap->at(vbucket);
|
|
82
|
+
const auto chain_length = chain.empty() ? 0 : chain.size() - 1;
|
|
83
|
+
|
|
84
|
+
const auto readable = [&](std::size_t replica) -> std::optional<std::size_t> {
|
|
85
|
+
if (replica >= chain_length) {
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
// A -1 entry and a node index the topology does not list mean the same
|
|
89
|
+
// thing here: nothing to send to.
|
|
90
|
+
if (const auto server = config.server_by_vbucket(vbucket, replica + 1);
|
|
91
|
+
server.has_value() && server.value() < config.nodes.size()) {
|
|
92
|
+
return server;
|
|
93
|
+
}
|
|
94
|
+
return {};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
if (!wrap) {
|
|
98
|
+
if (requested_replica >= number_of_replicas) {
|
|
99
|
+
decision.ec = errc::key_value::replica_index_out_of_bounds;
|
|
100
|
+
return decision;
|
|
101
|
+
}
|
|
102
|
+
if (const auto server = readable(requested_replica); server.has_value()) {
|
|
103
|
+
decision.replica_position = requested_replica + 1;
|
|
104
|
+
decision.server_index = server;
|
|
105
|
+
return decision;
|
|
106
|
+
}
|
|
107
|
+
decision.ec = errc::key_value::replica_index_currently_unavailable;
|
|
108
|
+
return decision;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// wrap walks num_replicas, not the row, so an index past a short row still
|
|
112
|
+
// reaches the replicas the row does list.
|
|
113
|
+
const auto start = requested_replica % number_of_replicas;
|
|
114
|
+
for (std::size_t offset = 0; offset < number_of_replicas; ++offset) {
|
|
115
|
+
const auto replica = (start + offset) % number_of_replicas;
|
|
116
|
+
if (const auto server = readable(replica); server.has_value()) {
|
|
117
|
+
decision.replica_position = replica + 1;
|
|
118
|
+
decision.server_index = server;
|
|
119
|
+
return decision;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
decision.ec = errc::key_value::replica_index_currently_unavailable;
|
|
124
|
+
return decision;
|
|
125
|
+
}
|
|
25
126
|
|
|
26
127
|
auto
|
|
27
128
|
effective_nodes(const document_id& id,
|
|
@@ -19,12 +19,18 @@
|
|
|
19
19
|
#pragma once
|
|
20
20
|
|
|
21
21
|
#include "core/document_id.hxx"
|
|
22
|
+
#include "core/error_context/key_value_error_context.hxx"
|
|
22
23
|
#include "core/topology/configuration.hxx"
|
|
23
24
|
|
|
25
|
+
#include "couchbase/error.hxx"
|
|
24
26
|
#include "couchbase/read_preference.hxx"
|
|
25
27
|
|
|
28
|
+
#include <cstddef>
|
|
29
|
+
#include <cstdint>
|
|
26
30
|
#include <memory>
|
|
31
|
+
#include <optional>
|
|
27
32
|
#include <string>
|
|
33
|
+
#include <system_error>
|
|
28
34
|
#include <vector>
|
|
29
35
|
|
|
30
36
|
namespace couchbase::core::impl
|
|
@@ -34,6 +40,64 @@ struct readable_node {
|
|
|
34
40
|
std::size_t index;
|
|
35
41
|
};
|
|
36
42
|
|
|
43
|
+
/**
|
|
44
|
+
* What a targeted replica read asks of the routing. Translated out of the
|
|
45
|
+
* public strategy, so core does not depend on a public options header.
|
|
46
|
+
*/
|
|
47
|
+
struct replica_selection {
|
|
48
|
+
std::size_t replica_index{};
|
|
49
|
+
bool wrap{};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Where a replica read should be sent, or why it cannot be sent at all.
|
|
54
|
+
*
|
|
55
|
+
* Exactly one of three states:
|
|
56
|
+
*
|
|
57
|
+
* - @c ec set: terminal, and completes the operation.
|
|
58
|
+
* - @c ec clear and @c server_index unset: the current topology cannot route
|
|
59
|
+
* the request, so the caller takes its retry path.
|
|
60
|
+
* - @c server_index set: the node to dispatch to.
|
|
61
|
+
*/
|
|
62
|
+
struct replica_route_decision {
|
|
63
|
+
std::error_code ec{};
|
|
64
|
+
std::uint16_t partition{};
|
|
65
|
+
std::size_t replica_position{};
|
|
66
|
+
std::optional<std::size_t> server_index{};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Resolves a replica index, as the user requested it, against a vbucket map
|
|
71
|
+
* row.
|
|
72
|
+
*
|
|
73
|
+
* num_replicas bounds the index; the row bounds what is readable. A rebalance
|
|
74
|
+
* reshapes the rows after a new count is published, so the two can disagree.
|
|
75
|
+
*
|
|
76
|
+
* @param config current topology
|
|
77
|
+
* @param vbucket the vbucket the document belongs to
|
|
78
|
+
* @param requested_replica zero-based replica index, where 0 is the first
|
|
79
|
+
* replica and the active copy cannot be selected
|
|
80
|
+
* @param wrap walk on from an index that cannot be read to the next one that
|
|
81
|
+
* can, instead of failing
|
|
82
|
+
*/
|
|
83
|
+
auto
|
|
84
|
+
resolve_replica_index(const topology::configuration& config,
|
|
85
|
+
std::uint16_t vbucket,
|
|
86
|
+
std::size_t requested_replica,
|
|
87
|
+
bool wrap) -> replica_route_decision;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Builds the error a replica read completes with.
|
|
91
|
+
*
|
|
92
|
+
* A document missing from the replica is reported as
|
|
93
|
+
* @ref errc::key_value::document_not_found_on_replica, with
|
|
94
|
+
* @ref errc::key_value::document_not_found as its cause so that a caller can
|
|
95
|
+
* opt into the general condition by reading the cause. Every other code is
|
|
96
|
+
* reported as it is.
|
|
97
|
+
*/
|
|
98
|
+
auto
|
|
99
|
+
make_get_replica_error(const key_value_error_context& ctx) -> couchbase::error;
|
|
100
|
+
|
|
37
101
|
/**
|
|
38
102
|
* Returns list of server indexes to send operations. The index values are
|
|
39
103
|
* in range [0, number_of_replicas).
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2026-Present 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/topology/configuration.hxx"
|
|
21
|
+
|
|
22
|
+
#include <couchbase/error_codes.hxx>
|
|
23
|
+
#include <couchbase/node_id.hxx>
|
|
24
|
+
|
|
25
|
+
#include <memory>
|
|
26
|
+
#include <string>
|
|
27
|
+
#include <system_error>
|
|
28
|
+
#include <utility>
|
|
29
|
+
#include <vector>
|
|
30
|
+
|
|
31
|
+
namespace couchbase::core::impl
|
|
32
|
+
{
|
|
33
|
+
/**
|
|
34
|
+
* Pure helper that resolves a document key to the owning node's identity
|
|
35
|
+
* against a topology snapshot. Extracted out of @c collection_impl::node_id_for
|
|
36
|
+
* so the error-mapping branches (no config, no vbmap, out-of-range
|
|
37
|
+
* server_index, success) can be unit-tested without an io_context or a live
|
|
38
|
+
* cluster.
|
|
39
|
+
*
|
|
40
|
+
* @param config bucket configuration snapshot (may be null)
|
|
41
|
+
* @param document_key document key to map; empty input is reported as
|
|
42
|
+
* @c errc::common::invalid_argument
|
|
43
|
+
* @param t which port pair (plain/TLS) to use when deriving the
|
|
44
|
+
* node identity
|
|
45
|
+
* @return pair of (error_code, node_id). On success the @c error_code is
|
|
46
|
+
* default and the @c node_id is truthy; on failure the @c node_id
|
|
47
|
+
* is default-constructed (falsy).
|
|
48
|
+
*/
|
|
49
|
+
[[nodiscard]] inline auto
|
|
50
|
+
resolve_node_id_from_config(const std::shared_ptr<topology::configuration>& config,
|
|
51
|
+
const std::string& document_key,
|
|
52
|
+
topology::transport t) -> std::pair<std::error_code, couchbase::node_id>
|
|
53
|
+
{
|
|
54
|
+
if (document_key.empty()) {
|
|
55
|
+
return { errc::common::invalid_argument, {} };
|
|
56
|
+
}
|
|
57
|
+
if (!config || !config->vbmap.has_value() || config->vbmap->empty()) {
|
|
58
|
+
return { errc::network::configuration_not_available, {} };
|
|
59
|
+
}
|
|
60
|
+
// Only the server_index half of the mapping is needed here; the vbucket id
|
|
61
|
+
// is intentionally discarded (avoids an unused structured-binding name).
|
|
62
|
+
const auto server_index = config->map_key(document_key, 0).second;
|
|
63
|
+
if (!server_index.has_value() || server_index.value() >= config->nodes.size()) {
|
|
64
|
+
// An unresolvable server_index means the vBucket map is present but does
|
|
65
|
+
// not map this key to a known node (out-of-range or missing entry).
|
|
66
|
+
// Surface this as configuration_not_available rather than
|
|
67
|
+
// request_canceled so callers can distinguish an unusable map from an
|
|
68
|
+
// actual caller-initiated cancellation.
|
|
69
|
+
return { errc::network::configuration_not_available, {} };
|
|
70
|
+
}
|
|
71
|
+
auto resolved = config->nodes[server_index.value()].effective_node_id(t);
|
|
72
|
+
if (!resolved) {
|
|
73
|
+
// The node maps to the key but carries no identity for the selected
|
|
74
|
+
// transport (e.g. no KV port for that port pair). Returning success here
|
|
75
|
+
// would violate the contract that a non-error result is always truthy,
|
|
76
|
+
// so report it as an unusable configuration instead.
|
|
77
|
+
return { errc::network::configuration_not_available, {} };
|
|
78
|
+
}
|
|
79
|
+
// Type the first element explicitly so the pair's perfect-forwarding
|
|
80
|
+
// constructor is selected and `resolved` is genuinely moved (a leading `{}`
|
|
81
|
+
// would bind the const-reference constructor instead, defeating the move).
|
|
82
|
+
return { std::error_code{}, std::move(resolved) };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Pure helper that enumerates the KV-serving nodes of a bucket configuration
|
|
87
|
+
* snapshot. Extracted out of @c collection_impl::node_ids so the
|
|
88
|
+
* error-mapping branches (no config, empty KV-serving set, success) can be
|
|
89
|
+
* unit-tested without an io_context or a live cluster — and so the branch
|
|
90
|
+
* matches the contract of the sibling resolver above:
|
|
91
|
+
*
|
|
92
|
+
* - A missing/null config snapshot is reported as
|
|
93
|
+
* @c errc::network::configuration_not_available (it must not be a silent
|
|
94
|
+
* empty success: the caller cannot distinguish "the cluster has zero KV
|
|
95
|
+
* nodes" from "we don't know the topology yet").
|
|
96
|
+
* - An empty effective-node-ids set is reported the same way; this is the
|
|
97
|
+
* mid-rebalance transient that the original commit silently surfaced as
|
|
98
|
+
* a successful empty vector.
|
|
99
|
+
*
|
|
100
|
+
* @param config bucket configuration snapshot (may be null)
|
|
101
|
+
* @param t which port pair (plain/TLS) to use when deriving identity
|
|
102
|
+
* @return pair of (error_code, vector<node_id>). On success the @c
|
|
103
|
+
* error_code is default and the vector is non-empty; on failure the
|
|
104
|
+
* vector is empty.
|
|
105
|
+
*/
|
|
106
|
+
[[nodiscard]] inline auto
|
|
107
|
+
resolve_node_ids_from_config(const std::shared_ptr<topology::configuration>& config,
|
|
108
|
+
topology::transport t)
|
|
109
|
+
-> std::pair<std::error_code, std::vector<couchbase::node_id>>
|
|
110
|
+
{
|
|
111
|
+
if (!config) {
|
|
112
|
+
return { errc::network::configuration_not_available, {} };
|
|
113
|
+
}
|
|
114
|
+
auto nids = config->effective_node_ids(t);
|
|
115
|
+
if (nids.empty()) {
|
|
116
|
+
// Tighter than the original "return {}" — a momentarily-empty
|
|
117
|
+
// topology (e.g. mid-rebalance) is reported as unavailable rather
|
|
118
|
+
// than as a successful empty list, so registry-sweep loops keyed on
|
|
119
|
+
// node_id don't conclude the cluster has zero KV-serving nodes and
|
|
120
|
+
// discard every entry.
|
|
121
|
+
return { errc::network::configuration_not_available, {} };
|
|
122
|
+
}
|
|
123
|
+
return { {}, std::move(nids) };
|
|
124
|
+
}
|
|
125
|
+
} // namespace couchbase::core::impl
|
|
@@ -92,6 +92,22 @@ public:
|
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
void query_stream(std::string statement,
|
|
96
|
+
query_options::built options,
|
|
97
|
+
query_stream_handler&& handler) const
|
|
98
|
+
{
|
|
99
|
+
// Instrument the streaming operation exactly like the buffered scope query() above: build the
|
|
100
|
+
// recorder, thread its operation span into the request, and hand the recorder to the stream so
|
|
101
|
+
// it finishes at the terminal.
|
|
102
|
+
auto obs_rec = create_observability_recorder(
|
|
103
|
+
core::tracing::operation::query, core::service_type::query, options.parent_span);
|
|
104
|
+
obs_rec->with_query_statement(statement, options);
|
|
105
|
+
auto request = core::impl::build_query_request(
|
|
106
|
+
std::move(statement), query_context_, std::move(options), obs_rec->operation_span());
|
|
107
|
+
core::impl::dispatch_query_stream(
|
|
108
|
+
core_, std::move(request), std::move(obs_rec), std::move(handler));
|
|
109
|
+
}
|
|
110
|
+
|
|
95
111
|
void analytics_query(std::string statement,
|
|
96
112
|
analytics_options::built options,
|
|
97
113
|
analytics_handler&& handler) const
|
|
@@ -111,6 +127,20 @@ public:
|
|
|
111
127
|
});
|
|
112
128
|
}
|
|
113
129
|
|
|
130
|
+
void analytics_query_stream(std::string statement,
|
|
131
|
+
analytics_options::built options,
|
|
132
|
+
analytics_stream_handler&& handler) const
|
|
133
|
+
{
|
|
134
|
+
// Instrument the streaming operation exactly like the buffered scope analytics_query() above.
|
|
135
|
+
auto obs_rec = create_observability_recorder(
|
|
136
|
+
core::tracing::operation::analytics, core::service_type::analytics, options.parent_span);
|
|
137
|
+
obs_rec->with_query_statement(statement, options);
|
|
138
|
+
auto request = core::impl::build_analytics_request(
|
|
139
|
+
std::move(statement), std::move(options), bucket_name_, name_, obs_rec->operation_span());
|
|
140
|
+
core::impl::dispatch_analytics_stream(
|
|
141
|
+
core_, std::move(request), std::move(obs_rec), std::move(handler));
|
|
142
|
+
}
|
|
143
|
+
|
|
114
144
|
void search(std::string index_name,
|
|
115
145
|
couchbase::search_request request,
|
|
116
146
|
search_options::built options,
|
|
@@ -205,6 +235,26 @@ scope::query(std::string statement, const query_options& options) const
|
|
|
205
235
|
return future;
|
|
206
236
|
}
|
|
207
237
|
|
|
238
|
+
void
|
|
239
|
+
scope::query_stream(std::string statement,
|
|
240
|
+
const query_options& options,
|
|
241
|
+
query_stream_handler&& handler) const
|
|
242
|
+
{
|
|
243
|
+
return impl_->query_stream(std::move(statement), options.build(), std::move(handler));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
auto
|
|
247
|
+
scope::query_stream(std::string statement, const query_options& options) const
|
|
248
|
+
-> std::future<std::pair<error, query_stream_result>>
|
|
249
|
+
{
|
|
250
|
+
auto barrier = std::make_shared<std::promise<std::pair<error, query_stream_result>>>();
|
|
251
|
+
auto future = barrier->get_future();
|
|
252
|
+
query_stream(std::move(statement), options, [barrier](auto err, auto result) {
|
|
253
|
+
barrier->set_value({ std::move(err), std::move(result) });
|
|
254
|
+
});
|
|
255
|
+
return future;
|
|
256
|
+
}
|
|
257
|
+
|
|
208
258
|
void
|
|
209
259
|
scope::analytics_query(std::string statement,
|
|
210
260
|
const analytics_options& options,
|
|
@@ -225,6 +275,26 @@ scope::analytics_query(std::string statement, const analytics_options& options)
|
|
|
225
275
|
return future;
|
|
226
276
|
}
|
|
227
277
|
|
|
278
|
+
void
|
|
279
|
+
scope::analytics_query_stream(std::string statement,
|
|
280
|
+
const analytics_options& options,
|
|
281
|
+
analytics_stream_handler&& handler) const
|
|
282
|
+
{
|
|
283
|
+
return impl_->analytics_query_stream(std::move(statement), options.build(), std::move(handler));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
auto
|
|
287
|
+
scope::analytics_query_stream(std::string statement, const analytics_options& options) const
|
|
288
|
+
-> std::future<std::pair<error, analytics_stream_result>>
|
|
289
|
+
{
|
|
290
|
+
auto barrier = std::make_shared<std::promise<std::pair<error, analytics_stream_result>>>();
|
|
291
|
+
auto future = barrier->get_future();
|
|
292
|
+
analytics_query_stream(std::move(statement), options, [barrier](auto err, auto result) {
|
|
293
|
+
barrier->set_value({ std::move(err), std::move(result) });
|
|
294
|
+
});
|
|
295
|
+
return future;
|
|
296
|
+
}
|
|
297
|
+
|
|
228
298
|
void
|
|
229
299
|
scope::search(std::string index_name,
|
|
230
300
|
search_request request,
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
#include "core/cluster.hxx"
|
|
19
19
|
#include "core/operations/document_search.hxx"
|
|
20
|
+
#include "core/search_scoring.hxx"
|
|
20
21
|
#include "core/utils/json.hxx"
|
|
21
22
|
#include "encoded_search_facet.hxx"
|
|
22
23
|
#include "encoded_search_query.hxx"
|
|
@@ -100,7 +101,7 @@ map_facets(const std::map<std::string, std::shared_ptr<search_facet>, std::less<
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
auto
|
|
103
|
-
map_raw(std::map<std::string, codec::binary, std::less<>>& raw)
|
|
104
|
+
map_raw(const std::map<std::string, codec::binary, std::less<>>& raw)
|
|
104
105
|
-> std::map<std::string, couchbase::core::json_string>
|
|
105
106
|
{
|
|
106
107
|
std::map<std::string, couchbase::core::json_string> core_raw{};
|
|
@@ -125,6 +126,33 @@ map_vector_query_combination(const std::optional<couchbase::vector_query_combina
|
|
|
125
126
|
return {};
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
auto
|
|
130
|
+
map_scoring(const search_scoring::built& scoring) -> core::search_scoring_mode
|
|
131
|
+
{
|
|
132
|
+
return std::visit(
|
|
133
|
+
[](const auto& mode) -> core::search_scoring_mode {
|
|
134
|
+
using T = std::decay_t<decltype(mode)>;
|
|
135
|
+
if constexpr (std::is_same_v<T, search_scoring::built::none>) {
|
|
136
|
+
return core::search_scoring_none{};
|
|
137
|
+
} else if constexpr (std::is_same_v<T, search_scoring::built::reciprocal_rank_fusion>) {
|
|
138
|
+
return core::search_scoring_reciprocal_rank_fusion{ mode.rank_constant, mode.window_size };
|
|
139
|
+
} else if constexpr (std::is_same_v<T, search_scoring::built::relative_score_fusion>) {
|
|
140
|
+
return core::search_scoring_relative_score_fusion{ mode.window_size };
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
scoring.mode);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
void
|
|
147
|
+
apply_scoring(core::operations::search_request& request,
|
|
148
|
+
const std::optional<search_scoring::built>& scoring)
|
|
149
|
+
{
|
|
150
|
+
if (!scoring.has_value()) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
request.scoring = map_scoring(scoring.value());
|
|
154
|
+
}
|
|
155
|
+
|
|
128
156
|
} // namespace
|
|
129
157
|
|
|
130
158
|
auto
|
|
@@ -168,6 +196,7 @@ build_search_request(std::string index_name,
|
|
|
168
196
|
options.timeout,
|
|
169
197
|
};
|
|
170
198
|
request.parent_span = std::move(op_span);
|
|
199
|
+
apply_scoring(request, options.scoring);
|
|
171
200
|
return request;
|
|
172
201
|
}
|
|
173
202
|
|
|
@@ -213,6 +242,7 @@ build_search_request(std::string index_name,
|
|
|
213
242
|
options.timeout,
|
|
214
243
|
};
|
|
215
244
|
core_request.parent_span = std::move(op_span);
|
|
245
|
+
apply_scoring(core_request, options.scoring);
|
|
216
246
|
|
|
217
247
|
if (auto vector_search = request.vector_search(); vector_search.has_value()) {
|
|
218
248
|
core_request.vector_search = core::utils::json::generate_binary(vector_search->query);
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2026-Present 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 <couchbase/cluster.hxx>
|
|
19
|
+
#include <couchbase/transactions.hxx>
|
|
20
|
+
|
|
21
|
+
#include "core/impl/error.hxx"
|
|
22
|
+
#include "core/transactions.hxx"
|
|
23
|
+
#include "core/transactions/attempt_context_impl.hxx"
|
|
24
|
+
#include "core/transactions/exceptions.hxx"
|
|
25
|
+
|
|
26
|
+
#include <spdlog/fmt/bundled/format.h>
|
|
27
|
+
|
|
28
|
+
#include <couchbase/fmt/error.hxx>
|
|
29
|
+
|
|
30
|
+
namespace couchbase::transactions
|
|
31
|
+
{
|
|
32
|
+
void
|
|
33
|
+
maybe_throw(error err)
|
|
34
|
+
{
|
|
35
|
+
if (err && err.ec() != errc::transaction_op::transaction_op_failed) {
|
|
36
|
+
// We intentionally don't handle transaction_op_failed here, as we must have cached the
|
|
37
|
+
// transaction error internally already, which has the full context with the right error class
|
|
38
|
+
// etc.
|
|
39
|
+
if (err.ec().category() == core::impl::transaction_op_category()) {
|
|
40
|
+
throw core::transactions::op_exception(std::move(err));
|
|
41
|
+
}
|
|
42
|
+
throw std::system_error(err.ec(), fmt::format("{}", err));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class transactions_impl
|
|
47
|
+
{
|
|
48
|
+
public:
|
|
49
|
+
explicit transactions_impl(std::shared_ptr<core::transactions::transactions> core_txns)
|
|
50
|
+
: core_txns_{ std::move(core_txns) }
|
|
51
|
+
{
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
auto run(txn_logic&& logic, const transaction_options& options) const
|
|
55
|
+
-> std::pair<error, transaction_result>
|
|
56
|
+
{
|
|
57
|
+
try {
|
|
58
|
+
auto res = core_txns_->run(options, [logic = std::move(logic)](auto ctx) mutable {
|
|
59
|
+
const auto err =
|
|
60
|
+
logic(std::static_pointer_cast<core::transactions::attempt_context_impl>(ctx));
|
|
61
|
+
maybe_throw(std::move(err));
|
|
62
|
+
});
|
|
63
|
+
return { {}, res };
|
|
64
|
+
} catch (const core::transactions::transaction_exception& e) {
|
|
65
|
+
auto [err_ctx, res_from_exc] = e.get_transaction_result();
|
|
66
|
+
return std::make_pair(core::impl::make_error(err_ctx), std::move(res_from_exc));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
void run(async_txn_logic&& logic,
|
|
71
|
+
async_txn_complete_logic&& callback,
|
|
72
|
+
const transaction_options& options) const
|
|
73
|
+
{
|
|
74
|
+
core_txns_->run(
|
|
75
|
+
options,
|
|
76
|
+
[logic = std::move(logic)](auto ctx) mutable {
|
|
77
|
+
auto err = logic(std::static_pointer_cast<core::transactions::attempt_context_impl>(ctx));
|
|
78
|
+
maybe_throw(std::move(err));
|
|
79
|
+
},
|
|
80
|
+
[callback = std::move(callback)](auto exc, auto res) mutable {
|
|
81
|
+
if (exc.has_value()) {
|
|
82
|
+
auto [err_ctx, res_from_exc] = exc.value().get_transaction_result();
|
|
83
|
+
return callback(core::impl::make_error(err_ctx), std::move(res_from_exc));
|
|
84
|
+
}
|
|
85
|
+
return callback({}, std::move(res.value()));
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
[[nodiscard]] auto core() const -> std::shared_ptr<core::transactions::transactions>
|
|
90
|
+
{
|
|
91
|
+
return core_txns_;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private:
|
|
95
|
+
std::shared_ptr<core::transactions::transactions> core_txns_;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
transactions::transactions(std::shared_ptr<core::transactions::transactions> core_txns)
|
|
99
|
+
: impl_{ std::make_shared<transactions_impl>(std::move(core_txns)) }
|
|
100
|
+
{
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
auto
|
|
104
|
+
transactions::run(txn_logic&& logic, const transaction_options& cfg)
|
|
105
|
+
-> std::pair<error, transaction_result>
|
|
106
|
+
{
|
|
107
|
+
return impl_->run(std::move(logic), cfg);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void
|
|
111
|
+
transactions::run(async_txn_logic&& logic,
|
|
112
|
+
async_txn_complete_logic&& complete_callback,
|
|
113
|
+
const transaction_options& cfg)
|
|
114
|
+
{
|
|
115
|
+
return impl_->run(std::move(logic), std::move(complete_callback), cfg);
|
|
116
|
+
}
|
|
117
|
+
} // namespace couchbase::transactions
|
|
118
|
+
|
|
119
|
+
namespace couchbase::core::transactions
|
|
120
|
+
{
|
|
121
|
+
auto
|
|
122
|
+
get_core_transactions(const std::shared_ptr<couchbase::transactions::transactions>& transactions)
|
|
123
|
+
-> std::shared_ptr<core::transactions::transactions>
|
|
124
|
+
{
|
|
125
|
+
return reinterpret_cast<const std::shared_ptr<couchbase::transactions::transactions_impl>*>(
|
|
126
|
+
transactions.get())
|
|
127
|
+
->get()
|
|
128
|
+
->core();
|
|
129
|
+
}
|
|
130
|
+
} // namespace couchbase::core::transactions
|