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
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2026. 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
|
+
// Translates the core KV operation request/response structs to and from the couchbase.kv.v1
|
|
21
|
+
// protobuf messages. The response builders take an already-populated key_value_error_context (the
|
|
22
|
+
// component derives it from the gRPC status) and fill the value/cas/token, deliberately not
|
|
23
|
+
// reusing the MCBP-bound encode_to/make_response.
|
|
24
|
+
|
|
25
|
+
#include "core/document_id.hxx"
|
|
26
|
+
#include "core/error_context/key_value.hxx"
|
|
27
|
+
#include "core/logger/logger.hxx"
|
|
28
|
+
#include "core/operations/document_append.hxx"
|
|
29
|
+
#include "core/operations/document_decrement.hxx"
|
|
30
|
+
#include "core/operations/document_exists.hxx"
|
|
31
|
+
#include "core/operations/document_get.hxx"
|
|
32
|
+
#include "core/operations/document_get_and_lock.hxx"
|
|
33
|
+
#include "core/operations/document_get_and_touch.hxx"
|
|
34
|
+
#include "core/operations/document_get_projected.hxx"
|
|
35
|
+
#include "core/operations/document_increment.hxx"
|
|
36
|
+
#include "core/operations/document_insert.hxx"
|
|
37
|
+
#include "core/operations/document_prepend.hxx"
|
|
38
|
+
#include "core/operations/document_remove.hxx"
|
|
39
|
+
#include "core/operations/document_replace.hxx"
|
|
40
|
+
#include "core/operations/document_touch.hxx"
|
|
41
|
+
#include "core/operations/document_unlock.hxx"
|
|
42
|
+
#include "core/operations/document_upsert.hxx"
|
|
43
|
+
#include "core/protostellar/compression_settings.hxx"
|
|
44
|
+
#include "core/utils/binary.hxx"
|
|
45
|
+
|
|
46
|
+
#include <couchbase/cas.hxx>
|
|
47
|
+
#include <couchbase/durability_level.hxx>
|
|
48
|
+
#include <couchbase/error_codes.hxx>
|
|
49
|
+
#include <couchbase/mutation_token.hxx>
|
|
50
|
+
|
|
51
|
+
#include <couchbase/kv/v1/kv.pb.h>
|
|
52
|
+
|
|
53
|
+
#include <cstdint>
|
|
54
|
+
#include <optional>
|
|
55
|
+
#include <string>
|
|
56
|
+
|
|
57
|
+
namespace couchbase::core::protostellar::kv
|
|
58
|
+
{
|
|
59
|
+
namespace v1 = ::couchbase::kv::v1;
|
|
60
|
+
|
|
61
|
+
// Value bytes go through core::utils::to_binary / to_string so the couchbase2 path shares one
|
|
62
|
+
// conversion with the rest of core rather than carrying its own memcpy helpers.
|
|
63
|
+
|
|
64
|
+
template<typename Request>
|
|
65
|
+
void
|
|
66
|
+
set_location(Request& proto, const document_id& id)
|
|
67
|
+
{
|
|
68
|
+
proto.set_bucket_name(id.bucket());
|
|
69
|
+
proto.set_scope_name(id.scope());
|
|
70
|
+
proto.set_collection_name(id.collection());
|
|
71
|
+
proto.set_key(id.key());
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// The expiry encoding below is dictated by the gateway, which is what translates these messages
|
|
75
|
+
// into MCBP and is therefore the authority on what each shape means. Line references are to
|
|
76
|
+
// couchbase/stellar-gateway at commit 910af15aefcc094378636972dd22875c5e485ee9, and are pinned to
|
|
77
|
+
// the exact file contents by blob hash so they stay checkable after the files move:
|
|
78
|
+
//
|
|
79
|
+
// kvserver.go git cat-file -p dde6353d06439fa4d8e0445f2362e8b460ff1265
|
|
80
|
+
// helpers.go git cat-file -p 5bd3ad7dcaf3bf2ada354ad9846cf4a87aa73a31
|
|
81
|
+
//
|
|
82
|
+
// The core request carries expiry with the memcached convention: a value of at most the 30-day
|
|
83
|
+
// cutoff is a relative duration in seconds; above it, it is an absolute Unix-epoch timestamp (this
|
|
84
|
+
// is how core/impl/expiry.cxx encodes durations >= 30 days and absolute time points).
|
|
85
|
+
//
|
|
86
|
+
// The proto oneof is not that shape. expiry_secs is *always* a duration: the gateway passes it
|
|
87
|
+
// through when it is <= 2592000 and otherwise re-bases it onto "now + N seconds"
|
|
88
|
+
// (helpers.go:48-67, secsExpiryToGocbcorex), so an already-absolute core value sent through
|
|
89
|
+
// expiry_secs would be read as a ~50-year duration. Absolute values therefore have to use
|
|
90
|
+
// expiry_time, which the gateway takes as an epoch second (helpers.go:44-46). The cutoff itself is
|
|
91
|
+
// relative on both sides: the gateway's own boundary is `expiry <= 2592000`.
|
|
92
|
+
inline constexpr std::uint32_t relative_expiry_cutoff_seconds = 60U * 60U * 24U * 30U; // 2,592,000
|
|
93
|
+
|
|
94
|
+
// An absent expiry oneof is the gateway's encoding for "preserve the document's existing expiry",
|
|
95
|
+
// not for "no expiry": both Upsert and Replace map a nil oneof to opts.PreserveExpiry = true
|
|
96
|
+
// (kvserver.go:478-484 and :580-581). "No expiry" must therefore be an explicit zero, which the
|
|
97
|
+
// gateway maps to never-expires (helpers.go:49-51); the classic transport serialises the same zero
|
|
98
|
+
// into the extras (core/protocol/cmd_upsert.cxx:82-91). Touch and GetAndTouch reject an absent
|
|
99
|
+
// oneof outright -- "Expiry time specification is unknown." (kvserver.go:297-303, :131-137) -- so
|
|
100
|
+
// the field is not optional there either. The oneof is omitted only when the caller asked to
|
|
101
|
+
// preserve, which for ReplaceRequest is the only available encoding: unlike UpsertRequest it has no
|
|
102
|
+
// preserve_expiry_on_existing field at all.
|
|
103
|
+
template<typename Proto>
|
|
104
|
+
void
|
|
105
|
+
set_expiry(Proto& proto, std::uint32_t expiry, bool preserve_expiry = false)
|
|
106
|
+
{
|
|
107
|
+
if (preserve_expiry) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (expiry <= relative_expiry_cutoff_seconds) {
|
|
111
|
+
proto.set_expiry_secs(expiry);
|
|
112
|
+
} else {
|
|
113
|
+
proto.mutable_expiry_time()->set_seconds(static_cast<std::int64_t>(expiry));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// couchbase::durability_level::none means "no requirement" — the proto field is left unset.
|
|
118
|
+
inline auto
|
|
119
|
+
to_proto_durability(couchbase::durability_level level) -> std::optional<v1::DurabilityLevel>
|
|
120
|
+
{
|
|
121
|
+
switch (level) {
|
|
122
|
+
case couchbase::durability_level::none:
|
|
123
|
+
return std::nullopt;
|
|
124
|
+
case couchbase::durability_level::majority:
|
|
125
|
+
return v1::DURABILITY_LEVEL_MAJORITY;
|
|
126
|
+
case couchbase::durability_level::majority_and_persist_to_active:
|
|
127
|
+
return v1::DURABILITY_LEVEL_MAJORITY_AND_PERSIST_TO_ACTIVE;
|
|
128
|
+
case couchbase::durability_level::persist_to_majority:
|
|
129
|
+
return v1::DURABILITY_LEVEL_PERSIST_TO_MAJORITY;
|
|
130
|
+
}
|
|
131
|
+
return std::nullopt;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
inline auto
|
|
135
|
+
to_core_token(const v1::MutationToken& token) -> couchbase::mutation_token
|
|
136
|
+
{
|
|
137
|
+
return couchbase::mutation_token{ token.vbucket_uuid(),
|
|
138
|
+
token.seq_no(),
|
|
139
|
+
static_cast<std::uint16_t>(token.vbucket_id()),
|
|
140
|
+
token.bucket_name() };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Every response that carries a document body puts it in a content oneof, and the generated
|
|
144
|
+
// accessor for the inactive arm returns the empty-string singleton. The active arm therefore has to
|
|
145
|
+
// be tested before reading either one, or a compressed payload decodes to an empty value with a
|
|
146
|
+
// valid CAS -- indistinguishable from an empty document.
|
|
147
|
+
template<typename Proto>
|
|
148
|
+
[[nodiscard]] auto
|
|
149
|
+
content_is_compressed(const Proto& proto) -> bool
|
|
150
|
+
{
|
|
151
|
+
return proto.content_case() == Proto::kContentCompressed;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ── Compression (RFC 77) ───────────────────────────────────────────────────────
|
|
155
|
+
|
|
156
|
+
// snappy lives in kv_converter.cxx (compiled into the client library) so <snappy.h> stays out of
|
|
157
|
+
// this header, which white-box tests include — they then need neither snappy's headers nor its
|
|
158
|
+
// symbols. maybe_compress returns the compressed bytes when compression is enabled and the value
|
|
159
|
+
// clears the size/ratio threshold, else std::nullopt ("store uncompressed"); snappy_uncompress
|
|
160
|
+
// returns std::nullopt on malformed input and on a frame declaring more than the transport's
|
|
161
|
+
// maximum message size, which no legitimate value can exceed.
|
|
162
|
+
[[nodiscard]] auto
|
|
163
|
+
maybe_compress(const std::vector<std::byte>& value, const compression_settings& compression)
|
|
164
|
+
-> std::optional<std::string>;
|
|
165
|
+
[[nodiscard]] auto
|
|
166
|
+
snappy_uncompress(const std::string& compressed) -> std::optional<std::string>;
|
|
167
|
+
|
|
168
|
+
// Signals the gateway that it may return snappy-compressed content (RFC 77: send
|
|
169
|
+
// COMPRESSION_ENABLED_OPTIONAL when enabled; leave the field unset when the user disabled
|
|
170
|
+
// compression; never COMPRESSION_ENABLED_ALWAYS).
|
|
171
|
+
template<typename Proto>
|
|
172
|
+
inline void
|
|
173
|
+
set_read_compression(Proto& proto, const compression_settings& compression)
|
|
174
|
+
{
|
|
175
|
+
if (compression.enabled) {
|
|
176
|
+
proto.set_compression(v1::COMPRESSION_ENABLED_OPTIONAL);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Fills a write request's content oneof, snappy-compressing when maybe_compress deems it
|
|
181
|
+
// worthwhile.
|
|
182
|
+
template<typename Proto>
|
|
183
|
+
inline void
|
|
184
|
+
set_write_content(Proto& proto,
|
|
185
|
+
const std::vector<std::byte>& value,
|
|
186
|
+
const compression_settings& compression)
|
|
187
|
+
{
|
|
188
|
+
if (auto compressed = maybe_compress(value, compression)) {
|
|
189
|
+
proto.set_content_compressed(std::move(*compressed));
|
|
190
|
+
} else {
|
|
191
|
+
proto.set_content_uncompressed(utils::to_string(value));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Reads a response's content oneof, snappy-decoding a compressed payload. Returns nullopt when the
|
|
196
|
+
// compressed arm does not decode: handing back empty bytes instead would produce a value that no
|
|
197
|
+
// caller can distinguish from an empty document, which is the same silent data-loss trap that made
|
|
198
|
+
// the unguarded oneof read wrong before compression landed. A gateway emitting an undecodable
|
|
199
|
+
// snappy frame is a server-side fault, so the callers surface it as internal_server_failure rather
|
|
200
|
+
// than inventing a value.
|
|
201
|
+
template<typename Proto>
|
|
202
|
+
inline auto
|
|
203
|
+
decode_content(const Proto& proto) -> std::optional<std::vector<std::byte>>
|
|
204
|
+
{
|
|
205
|
+
if (content_is_compressed(proto)) {
|
|
206
|
+
if (auto uncompressed = snappy_uncompress(proto.content_compressed())) {
|
|
207
|
+
return utils::to_binary(*uncompressed);
|
|
208
|
+
}
|
|
209
|
+
CB_LOG_DEBUG("failed to decompress snappy payload in response (compressed_size={})",
|
|
210
|
+
proto.content_compressed().size());
|
|
211
|
+
return std::nullopt;
|
|
212
|
+
}
|
|
213
|
+
return utils::to_binary(proto.content_uncompressed());
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ── Get ───────────────────────────────────────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
inline auto
|
|
219
|
+
encode(const operations::get_request& request, const compression_settings& compression)
|
|
220
|
+
-> v1::GetRequest
|
|
221
|
+
{
|
|
222
|
+
v1::GetRequest proto;
|
|
223
|
+
set_location(proto, request.id);
|
|
224
|
+
set_read_compression(proto, compression);
|
|
225
|
+
return proto;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
inline auto
|
|
229
|
+
decode(const v1::GetResponse& proto, key_value_error_context ctx) -> operations::get_response
|
|
230
|
+
{
|
|
231
|
+
operations::get_response response;
|
|
232
|
+
response.ctx = std::move(ctx);
|
|
233
|
+
auto value = decode_content(proto);
|
|
234
|
+
if (!value) {
|
|
235
|
+
response.ctx.override_ec(errc::common::internal_server_failure);
|
|
236
|
+
return response;
|
|
237
|
+
}
|
|
238
|
+
response.value = std::move(*value);
|
|
239
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
240
|
+
response.flags = proto.content_flags();
|
|
241
|
+
return response;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
inline auto
|
|
245
|
+
encode(const operations::get_projected_request& request, const compression_settings& compression)
|
|
246
|
+
-> v1::GetRequest
|
|
247
|
+
{
|
|
248
|
+
v1::GetRequest proto;
|
|
249
|
+
set_location(proto, request.id);
|
|
250
|
+
set_read_compression(proto, compression);
|
|
251
|
+
for (const auto& path : request.projections) {
|
|
252
|
+
proto.add_project(path);
|
|
253
|
+
}
|
|
254
|
+
return proto;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
inline auto
|
|
258
|
+
decode(const v1::GetResponse& proto,
|
|
259
|
+
key_value_error_context ctx,
|
|
260
|
+
const operations::get_projected_request& /* request */) -> operations::get_projected_response
|
|
261
|
+
{
|
|
262
|
+
operations::get_projected_response response;
|
|
263
|
+
response.ctx = std::move(ctx);
|
|
264
|
+
auto value = decode_content(proto);
|
|
265
|
+
if (!value) {
|
|
266
|
+
response.ctx.override_ec(errc::common::internal_server_failure);
|
|
267
|
+
return response;
|
|
268
|
+
}
|
|
269
|
+
response.value = std::move(*value);
|
|
270
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
271
|
+
response.flags = proto.content_flags();
|
|
272
|
+
if (proto.has_expiry()) {
|
|
273
|
+
response.expiry = static_cast<std::uint32_t>(proto.expiry().seconds());
|
|
274
|
+
}
|
|
275
|
+
return response;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ── Mutations (upsert / insert / replace / remove) ─────────────────────────────
|
|
279
|
+
|
|
280
|
+
template<typename Response, typename Proto>
|
|
281
|
+
inline auto
|
|
282
|
+
decode_mutation(const Proto& proto, key_value_error_context ctx) -> Response
|
|
283
|
+
{
|
|
284
|
+
Response response;
|
|
285
|
+
response.ctx = std::move(ctx);
|
|
286
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
287
|
+
if (proto.has_mutation_token()) {
|
|
288
|
+
response.token = to_core_token(proto.mutation_token());
|
|
289
|
+
}
|
|
290
|
+
return response;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
inline auto
|
|
294
|
+
encode(const operations::upsert_request& request, const compression_settings& compression)
|
|
295
|
+
-> v1::UpsertRequest
|
|
296
|
+
{
|
|
297
|
+
v1::UpsertRequest proto;
|
|
298
|
+
set_location(proto, request.id);
|
|
299
|
+
set_write_content(proto, request.value, compression);
|
|
300
|
+
proto.set_content_flags(request.flags);
|
|
301
|
+
// preserve_expiry is expressed by omitting the oneof, NOT through the proto's
|
|
302
|
+
// preserve_expiry_on_existing flag. The gateway rejects that flag outright whenever the oneof is
|
|
303
|
+
// absent -- "Cannot specify preserve expiry with no expiry, leave expiry undefined to preserve
|
|
304
|
+
// expiry." (kvserver.go:478-482) -- and again when the oneof carries a zero (:498-501), while a
|
|
305
|
+
// nil oneof already means preserve (:484). Setting both is an InvalidArgument, not a redundancy.
|
|
306
|
+
set_expiry(proto, request.expiry, request.preserve_expiry);
|
|
307
|
+
if (const auto level = to_proto_durability(request.durability_level); level) {
|
|
308
|
+
proto.set_durability_level(*level);
|
|
309
|
+
}
|
|
310
|
+
return proto;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
inline auto
|
|
314
|
+
encode(const operations::insert_request& request, const compression_settings& compression)
|
|
315
|
+
-> v1::InsertRequest
|
|
316
|
+
{
|
|
317
|
+
v1::InsertRequest proto;
|
|
318
|
+
set_location(proto, request.id);
|
|
319
|
+
set_write_content(proto, request.value, compression);
|
|
320
|
+
proto.set_content_flags(request.flags);
|
|
321
|
+
// insert has no preserve_expiry: a document that does not exist yet has no expiry to preserve.
|
|
322
|
+
set_expiry(proto, request.expiry);
|
|
323
|
+
if (const auto level = to_proto_durability(request.durability_level); level) {
|
|
324
|
+
proto.set_durability_level(*level);
|
|
325
|
+
}
|
|
326
|
+
return proto;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
inline auto
|
|
330
|
+
encode(const operations::replace_request& request, const compression_settings& compression)
|
|
331
|
+
-> v1::ReplaceRequest
|
|
332
|
+
{
|
|
333
|
+
v1::ReplaceRequest proto;
|
|
334
|
+
set_location(proto, request.id);
|
|
335
|
+
set_write_content(proto, request.value, compression);
|
|
336
|
+
proto.set_content_flags(request.flags);
|
|
337
|
+
if (request.cas.value() != 0) {
|
|
338
|
+
proto.set_cas(request.cas.value());
|
|
339
|
+
}
|
|
340
|
+
set_expiry(proto, request.expiry, request.preserve_expiry);
|
|
341
|
+
if (const auto level = to_proto_durability(request.durability_level); level) {
|
|
342
|
+
proto.set_durability_level(*level);
|
|
343
|
+
}
|
|
344
|
+
return proto;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
inline auto
|
|
348
|
+
encode(const operations::remove_request& request) -> v1::RemoveRequest
|
|
349
|
+
{
|
|
350
|
+
v1::RemoveRequest proto;
|
|
351
|
+
set_location(proto, request.id);
|
|
352
|
+
if (request.cas.value() != 0) {
|
|
353
|
+
proto.set_cas(request.cas.value());
|
|
354
|
+
}
|
|
355
|
+
if (const auto level = to_proto_durability(request.durability_level); level) {
|
|
356
|
+
proto.set_durability_level(*level);
|
|
357
|
+
}
|
|
358
|
+
return proto;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
inline auto
|
|
362
|
+
decode(const v1::UpsertResponse& proto, key_value_error_context ctx) -> operations::upsert_response
|
|
363
|
+
{
|
|
364
|
+
return decode_mutation<operations::upsert_response>(proto, std::move(ctx));
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
inline auto
|
|
368
|
+
decode(const v1::InsertResponse& proto, key_value_error_context ctx) -> operations::insert_response
|
|
369
|
+
{
|
|
370
|
+
return decode_mutation<operations::insert_response>(proto, std::move(ctx));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
inline auto
|
|
374
|
+
decode(const v1::ReplaceResponse& proto, key_value_error_context ctx)
|
|
375
|
+
-> operations::replace_response
|
|
376
|
+
{
|
|
377
|
+
return decode_mutation<operations::replace_response>(proto, std::move(ctx));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
inline auto
|
|
381
|
+
decode(const v1::RemoveResponse& proto, key_value_error_context ctx) -> operations::remove_response
|
|
382
|
+
{
|
|
383
|
+
return decode_mutation<operations::remove_response>(proto, std::move(ctx));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// ── Touch / Exists / lock / counters / append / prepend ────────────────────────
|
|
387
|
+
|
|
388
|
+
inline auto
|
|
389
|
+
encode(const operations::touch_request& request) -> v1::TouchRequest
|
|
390
|
+
{
|
|
391
|
+
v1::TouchRequest proto;
|
|
392
|
+
set_location(proto, request.id);
|
|
393
|
+
set_expiry(proto, request.expiry);
|
|
394
|
+
return proto;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
inline auto
|
|
398
|
+
decode(const v1::TouchResponse& proto, key_value_error_context ctx) -> operations::touch_response
|
|
399
|
+
{
|
|
400
|
+
operations::touch_response response;
|
|
401
|
+
response.ctx = std::move(ctx);
|
|
402
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
403
|
+
return response;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
inline auto
|
|
407
|
+
encode(const operations::exists_request& request) -> v1::ExistsRequest
|
|
408
|
+
{
|
|
409
|
+
v1::ExistsRequest proto;
|
|
410
|
+
set_location(proto, request.id);
|
|
411
|
+
return proto;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
inline auto
|
|
415
|
+
decode(const v1::ExistsResponse& proto, key_value_error_context ctx) -> operations::exists_response
|
|
416
|
+
{
|
|
417
|
+
operations::exists_response response;
|
|
418
|
+
response.ctx = std::move(ctx);
|
|
419
|
+
response.document_exists = proto.result();
|
|
420
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
421
|
+
return response;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
inline auto
|
|
425
|
+
encode(const operations::get_and_lock_request& request, const compression_settings& compression)
|
|
426
|
+
-> v1::GetAndLockRequest
|
|
427
|
+
{
|
|
428
|
+
v1::GetAndLockRequest proto;
|
|
429
|
+
set_location(proto, request.id);
|
|
430
|
+
proto.set_lock_time_secs(request.lock_time);
|
|
431
|
+
set_read_compression(proto, compression);
|
|
432
|
+
return proto;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
inline auto
|
|
436
|
+
decode(const v1::GetAndLockResponse& proto, key_value_error_context ctx)
|
|
437
|
+
-> operations::get_and_lock_response
|
|
438
|
+
{
|
|
439
|
+
operations::get_and_lock_response response;
|
|
440
|
+
response.ctx = std::move(ctx);
|
|
441
|
+
auto value = decode_content(proto);
|
|
442
|
+
if (!value) {
|
|
443
|
+
response.ctx.override_ec(errc::common::internal_server_failure);
|
|
444
|
+
return response;
|
|
445
|
+
}
|
|
446
|
+
response.value = std::move(*value);
|
|
447
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
448
|
+
response.flags = proto.content_flags();
|
|
449
|
+
return response;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
inline auto
|
|
453
|
+
encode(const operations::unlock_request& request) -> v1::UnlockRequest
|
|
454
|
+
{
|
|
455
|
+
v1::UnlockRequest proto;
|
|
456
|
+
set_location(proto, request.id);
|
|
457
|
+
proto.set_cas(request.cas.value());
|
|
458
|
+
return proto;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
inline auto
|
|
462
|
+
decode(const v1::UnlockResponse& /* proto */, key_value_error_context ctx)
|
|
463
|
+
-> operations::unlock_response
|
|
464
|
+
{
|
|
465
|
+
operations::unlock_response response;
|
|
466
|
+
response.ctx = std::move(ctx);
|
|
467
|
+
return response;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
inline auto
|
|
471
|
+
encode(const operations::get_and_touch_request& request, const compression_settings& compression)
|
|
472
|
+
-> v1::GetAndTouchRequest
|
|
473
|
+
{
|
|
474
|
+
v1::GetAndTouchRequest proto;
|
|
475
|
+
set_location(proto, request.id);
|
|
476
|
+
set_expiry(proto, request.expiry);
|
|
477
|
+
set_read_compression(proto, compression);
|
|
478
|
+
return proto;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
inline auto
|
|
482
|
+
decode(const v1::GetAndTouchResponse& proto, key_value_error_context ctx)
|
|
483
|
+
-> operations::get_and_touch_response
|
|
484
|
+
{
|
|
485
|
+
operations::get_and_touch_response response;
|
|
486
|
+
response.ctx = std::move(ctx);
|
|
487
|
+
auto value = decode_content(proto);
|
|
488
|
+
if (!value) {
|
|
489
|
+
response.ctx.override_ec(errc::common::internal_server_failure);
|
|
490
|
+
return response;
|
|
491
|
+
}
|
|
492
|
+
response.value = std::move(*value);
|
|
493
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
494
|
+
response.flags = proto.content_flags();
|
|
495
|
+
return response;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
template<typename Request, typename Proto>
|
|
499
|
+
inline void
|
|
500
|
+
set_counter_fields(Proto& proto, const Request& request)
|
|
501
|
+
{
|
|
502
|
+
set_location(proto, request.id);
|
|
503
|
+
proto.set_delta(request.delta);
|
|
504
|
+
set_expiry(proto, request.expiry);
|
|
505
|
+
if (request.initial_value.has_value()) {
|
|
506
|
+
proto.set_initial(static_cast<std::int64_t>(request.initial_value.value()));
|
|
507
|
+
}
|
|
508
|
+
if (const auto level = to_proto_durability(request.durability_level); level) {
|
|
509
|
+
proto.set_durability_level(*level);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
template<typename Response, typename Proto>
|
|
514
|
+
inline auto
|
|
515
|
+
decode_counter(const Proto& proto, key_value_error_context ctx) -> Response
|
|
516
|
+
{
|
|
517
|
+
Response response;
|
|
518
|
+
response.ctx = std::move(ctx);
|
|
519
|
+
response.content = static_cast<std::uint64_t>(proto.content());
|
|
520
|
+
response.cas = couchbase::cas{ proto.cas() };
|
|
521
|
+
if (proto.has_mutation_token()) {
|
|
522
|
+
response.token = to_core_token(proto.mutation_token());
|
|
523
|
+
}
|
|
524
|
+
return response;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
inline auto
|
|
528
|
+
encode(const operations::increment_request& request) -> v1::IncrementRequest
|
|
529
|
+
{
|
|
530
|
+
v1::IncrementRequest proto;
|
|
531
|
+
set_counter_fields(proto, request);
|
|
532
|
+
return proto;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
inline auto
|
|
536
|
+
decode(const v1::IncrementResponse& proto, key_value_error_context ctx)
|
|
537
|
+
-> operations::increment_response
|
|
538
|
+
{
|
|
539
|
+
return decode_counter<operations::increment_response>(proto, std::move(ctx));
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
inline auto
|
|
543
|
+
encode(const operations::decrement_request& request) -> v1::DecrementRequest
|
|
544
|
+
{
|
|
545
|
+
v1::DecrementRequest proto;
|
|
546
|
+
set_counter_fields(proto, request);
|
|
547
|
+
return proto;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
inline auto
|
|
551
|
+
decode(const v1::DecrementResponse& proto, key_value_error_context ctx)
|
|
552
|
+
-> operations::decrement_response
|
|
553
|
+
{
|
|
554
|
+
return decode_counter<operations::decrement_response>(proto, std::move(ctx));
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
inline auto
|
|
558
|
+
encode(const operations::append_request& request) -> v1::AppendRequest
|
|
559
|
+
{
|
|
560
|
+
v1::AppendRequest proto;
|
|
561
|
+
set_location(proto, request.id);
|
|
562
|
+
proto.set_content(utils::to_string(request.value));
|
|
563
|
+
if (request.cas.value() != 0) {
|
|
564
|
+
proto.set_cas(request.cas.value());
|
|
565
|
+
}
|
|
566
|
+
if (const auto level = to_proto_durability(request.durability_level); level) {
|
|
567
|
+
proto.set_durability_level(*level);
|
|
568
|
+
}
|
|
569
|
+
return proto;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
inline auto
|
|
573
|
+
decode(const v1::AppendResponse& proto, key_value_error_context ctx) -> operations::append_response
|
|
574
|
+
{
|
|
575
|
+
return decode_mutation<operations::append_response>(proto, std::move(ctx));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
inline auto
|
|
579
|
+
encode(const operations::prepend_request& request) -> v1::PrependRequest
|
|
580
|
+
{
|
|
581
|
+
v1::PrependRequest proto;
|
|
582
|
+
set_location(proto, request.id);
|
|
583
|
+
proto.set_content(utils::to_string(request.value));
|
|
584
|
+
if (request.cas.value() != 0) {
|
|
585
|
+
proto.set_cas(request.cas.value());
|
|
586
|
+
}
|
|
587
|
+
if (const auto level = to_proto_durability(request.durability_level); level) {
|
|
588
|
+
proto.set_durability_level(*level);
|
|
589
|
+
}
|
|
590
|
+
return proto;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
inline auto
|
|
594
|
+
decode(const v1::PrependResponse& proto, key_value_error_context ctx)
|
|
595
|
+
-> operations::prepend_response
|
|
596
|
+
{
|
|
597
|
+
return decode_mutation<operations::prepend_response>(proto, std::move(ctx));
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
} // namespace couchbase::core::protostellar::kv
|