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
|
@@ -34,4 +34,22 @@ struct is_cancellable_operation : public std::false_type {
|
|
|
34
34
|
|
|
35
35
|
template<typename T>
|
|
36
36
|
inline constexpr bool is_cancellable_operation_v = is_cancellable_operation<T>::value;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Operations that pick the node to dispatch to themselves, instead of being
|
|
40
|
+
* routed by the vbucket map alone.
|
|
41
|
+
*
|
|
42
|
+
* Specialize this only for a request that provides
|
|
43
|
+
* @c resolve_route(const topology::configuration&) returning an
|
|
44
|
+
* @c std::optional<impl::replica_route_decision>, and a writable @c partition
|
|
45
|
+
* member: that is the whole interface @c bucket::map_and_send() calls through
|
|
46
|
+
* this trait. An empty optional declines self-routing for that request, and the
|
|
47
|
+
* vbucket-map path routes it instead.
|
|
48
|
+
*/
|
|
49
|
+
template<typename T>
|
|
50
|
+
struct resolves_own_route : public std::false_type {
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
template<typename T>
|
|
54
|
+
inline constexpr bool resolves_own_route_v = resolves_own_route<T>::value;
|
|
37
55
|
} // namespace couchbase::core::operations
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2020-2021 Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "query_response_parsing.hxx"
|
|
19
|
+
|
|
20
|
+
#include "core/operations/management/error_utils.hxx"
|
|
21
|
+
#include "core/utils/contains_string.hxx"
|
|
22
|
+
#include "core/utils/duration_parser.hxx"
|
|
23
|
+
#include "core/utils/json.hxx"
|
|
24
|
+
|
|
25
|
+
#include <couchbase/error_codes.hxx>
|
|
26
|
+
|
|
27
|
+
#include <tao/json/value.hpp>
|
|
28
|
+
|
|
29
|
+
namespace couchbase::core::operations
|
|
30
|
+
{
|
|
31
|
+
|
|
32
|
+
auto
|
|
33
|
+
parse_query_meta(const tao::json::value& payload) -> query_response::query_meta_data
|
|
34
|
+
{
|
|
35
|
+
query_response::query_meta_data meta{};
|
|
36
|
+
|
|
37
|
+
if (const auto* i = payload.find("requestID"); i != nullptr) {
|
|
38
|
+
meta.request_id = i->get_string();
|
|
39
|
+
}
|
|
40
|
+
if (const auto* i = payload.find("clientContextID"); i != nullptr) {
|
|
41
|
+
meta.client_context_id = i->get_string();
|
|
42
|
+
}
|
|
43
|
+
if (const auto* s = payload.find("status"); s != nullptr) {
|
|
44
|
+
meta.status = s->get_string();
|
|
45
|
+
}
|
|
46
|
+
if (const auto* s = payload.find("signature"); s != nullptr) {
|
|
47
|
+
meta.signature = couchbase::core::utils::json::generate(*s);
|
|
48
|
+
}
|
|
49
|
+
if (const auto* p = payload.find("profile"); p != nullptr) {
|
|
50
|
+
meta.profile = couchbase::core::utils::json::generate(*p);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (const auto* m = payload.find("metrics"); m != nullptr) {
|
|
54
|
+
query_response::query_metrics metrics{};
|
|
55
|
+
metrics.result_count = m->at("resultCount").get_unsigned();
|
|
56
|
+
metrics.result_size = m->at("resultSize").get_unsigned();
|
|
57
|
+
metrics.elapsed_time = utils::parse_duration(m->at("elapsedTime").get_string());
|
|
58
|
+
metrics.execution_time = utils::parse_duration(m->at("executionTime").get_string());
|
|
59
|
+
metrics.sort_count = m->template optional<std::uint64_t>("sortCount").value_or(0);
|
|
60
|
+
metrics.mutation_count = m->template optional<std::uint64_t>("mutationCount").value_or(0);
|
|
61
|
+
metrics.error_count = m->template optional<std::uint64_t>("errorCount").value_or(0);
|
|
62
|
+
metrics.warning_count = m->template optional<std::uint64_t>("warningCount").value_or(0);
|
|
63
|
+
meta.metrics.emplace(metrics);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (const auto* e = payload.find("errors"); e != nullptr) {
|
|
67
|
+
std::vector<query_response::query_problem> problems{};
|
|
68
|
+
for (const auto& err : e->get_array()) {
|
|
69
|
+
query_response::query_problem problem;
|
|
70
|
+
problem.code = err.at("code").get_unsigned();
|
|
71
|
+
problem.message = err.at("msg").get_string();
|
|
72
|
+
if (const auto* reason = err.find("reason"); reason != nullptr && reason->is_object()) {
|
|
73
|
+
problem.reason = reason->optional<std::uint64_t>("code");
|
|
74
|
+
problem.retry = reason->optional<bool>("retry");
|
|
75
|
+
}
|
|
76
|
+
problems.emplace_back(problem);
|
|
77
|
+
}
|
|
78
|
+
meta.errors.emplace(problems);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (const auto* w = payload.find("warnings"); w != nullptr) {
|
|
82
|
+
std::vector<query_response::query_problem> problems{};
|
|
83
|
+
for (const auto& warn : w->get_array()) {
|
|
84
|
+
query_response::query_problem problem;
|
|
85
|
+
problem.code = warn.at("code").get_unsigned();
|
|
86
|
+
problem.message = warn.at("msg").get_string();
|
|
87
|
+
problems.emplace_back(problem);
|
|
88
|
+
}
|
|
89
|
+
meta.warnings.emplace(problems);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return meta;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
auto
|
|
96
|
+
map_query_error(const query_response::query_meta_data& meta, std::uint32_t http_status)
|
|
97
|
+
-> std::error_code
|
|
98
|
+
{
|
|
99
|
+
const auto unmatched =
|
|
100
|
+
http_status == 400 ? errc::common::invalid_argument : errc::common::internal_server_failure;
|
|
101
|
+
|
|
102
|
+
if (meta.status == "success" && http_status != 400) {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!meta.errors || meta.errors->empty()) {
|
|
107
|
+
/* Unreachable from make_response, which only calls map_query_error after confirming
|
|
108
|
+
* errors is non-empty; present for the streaming-path caller, which has no such guard. */
|
|
109
|
+
return unmatched;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const auto& first = meta.errors->front();
|
|
113
|
+
const auto first_code = first.code;
|
|
114
|
+
const auto& first_message = first.message;
|
|
115
|
+
|
|
116
|
+
std::error_code ec{};
|
|
117
|
+
|
|
118
|
+
switch (first_code) {
|
|
119
|
+
case 1065: /* IKey: "service.io.request.unrecognized_parameter" */
|
|
120
|
+
if ((first_message.find("Unrecognized parameter in request") != std::string::npos) &&
|
|
121
|
+
(first_message.find("preserve_expiry") != std::string::npos)) {
|
|
122
|
+
ec = errc::common::feature_not_available;
|
|
123
|
+
} else {
|
|
124
|
+
ec = errc::common::invalid_argument;
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
case 1080: /* IKey: "timeout" */
|
|
128
|
+
ec = errc::common::unambiguous_timeout;
|
|
129
|
+
break;
|
|
130
|
+
case 3000: /* IKey: "parse.syntax_error" */
|
|
131
|
+
ec = errc::common::parsing_failure;
|
|
132
|
+
break;
|
|
133
|
+
case 4040: /* IKey: "plan.build_prepared.no_such_name" */
|
|
134
|
+
case 4050: /* IKey: "plan.build_prepared.unrecognized_prepared" */
|
|
135
|
+
case 4060: /* IKey: "plan.build_prepared.no_such_name" */
|
|
136
|
+
case 4070: /* IKey: "plan.build_prepared.decoding" */
|
|
137
|
+
case 4080: /* IKey: "plan.build_prepared.name_encoded_plan_mismatch" */
|
|
138
|
+
case 4090: /* IKey: "plan.build_prepared.name_not_in_encoded_plan" */
|
|
139
|
+
/* NOTE: make_response also does cache.erase + throw retry_http_request for codes
|
|
140
|
+
* 4040/4050/4070. That stateful logic stays in make_response. This pure classifier
|
|
141
|
+
* returns prepared_statement_failure so callers (e.g. streaming path) get a
|
|
142
|
+
* non-empty error_code. */
|
|
143
|
+
ec = errc::query::prepared_statement_failure;
|
|
144
|
+
break;
|
|
145
|
+
case 4300: /* IKey: "plan.new_index_already_exists" */
|
|
146
|
+
ec = errc::common::index_exists;
|
|
147
|
+
break;
|
|
148
|
+
case 5000: /* IKey: "Internal Error" */
|
|
149
|
+
if (utils::contains_string(first_message, "index", true) &&
|
|
150
|
+
utils::contains_string(first_message, "already exist", true)) {
|
|
151
|
+
ec = errc::common::index_exists;
|
|
152
|
+
} else if (utils::contains_string(first_message, "Index does not exist") ||
|
|
153
|
+
(utils::contains_string(first_message, "index", true) &&
|
|
154
|
+
utils::contains_string(first_message, "not found", true))) {
|
|
155
|
+
ec = errc::common::index_not_found;
|
|
156
|
+
} else if (first_message.find("Bucket Not Found") != std::string::npos) {
|
|
157
|
+
ec = errc::common::bucket_not_found;
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
case 12009: /* IKey: "datastore.couchbase.DML_error" */
|
|
161
|
+
if (first_message.find("CAS mismatch") != std::string::npos) {
|
|
162
|
+
ec = errc::common::cas_mismatch;
|
|
163
|
+
} else {
|
|
164
|
+
switch (first.reason.value_or(0)) {
|
|
165
|
+
case 12033:
|
|
166
|
+
ec = errc::common::cas_mismatch;
|
|
167
|
+
break;
|
|
168
|
+
case 17014:
|
|
169
|
+
ec = errc::key_value::document_not_found;
|
|
170
|
+
break;
|
|
171
|
+
case 17012:
|
|
172
|
+
ec = errc::key_value::document_exists;
|
|
173
|
+
break;
|
|
174
|
+
default:
|
|
175
|
+
ec = errc::query::dml_failure;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
break;
|
|
180
|
+
case 12004: /* IKey: "datastore.couchbase.primary_idx_not_found" */
|
|
181
|
+
case 12016: /* IKey: "datastore.couchbase.index_not_found" */
|
|
182
|
+
ec = errc::common::index_not_found;
|
|
183
|
+
break;
|
|
184
|
+
case 13014: /* IKey: "datastore.couchbase.insufficient_credentials" */
|
|
185
|
+
ec = errc::common::authentication_failure;
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
if ((first_code >= 12000 && first_code < 13000) ||
|
|
189
|
+
(first_code >= 14000 && first_code < 15000)) {
|
|
190
|
+
ec = errc::query::index_failure;
|
|
191
|
+
} else if (first_code >= 4000 && first_code < 5000) {
|
|
192
|
+
ec = errc::query::planning_failure;
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!ec) {
|
|
198
|
+
auto common_ec = management::extract_common_query_error_code(first_code, first_message);
|
|
199
|
+
if (common_ec) {
|
|
200
|
+
ec = common_ec.value();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (!ec) {
|
|
205
|
+
ec = unmatched;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return ec;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
} // namespace couchbase::core::operations
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2020-2021 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/operations/document_query.hxx"
|
|
21
|
+
|
|
22
|
+
#include <couchbase/error_codes.hxx>
|
|
23
|
+
|
|
24
|
+
#include <tao/json/forward.hpp>
|
|
25
|
+
|
|
26
|
+
#include <cstdint>
|
|
27
|
+
#include <system_error>
|
|
28
|
+
|
|
29
|
+
namespace couchbase::core::operations
|
|
30
|
+
{
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse query meta-data fields (status, metrics, warnings, errors, signature, profile,
|
|
34
|
+
* requestID, clientContextID) from a top-level response payload.
|
|
35
|
+
*
|
|
36
|
+
* Pure function — no side effects, no access to request state.
|
|
37
|
+
*/
|
|
38
|
+
auto
|
|
39
|
+
parse_query_meta(const tao::json::value& payload) -> query_response::query_meta_data;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Map query meta-data to an error_code.
|
|
43
|
+
*
|
|
44
|
+
* Pure classifier — no side effects, no cache mutations, no exceptions thrown.
|
|
45
|
+
* All prepared-statement codes (4040/4050/4060/4070/4080/4090) are classified as
|
|
46
|
+
* prepared_statement_failure here; the cache-erase + retry_http_request throw remains in
|
|
47
|
+
* make_response and applies only to the 4040/4050/4070 subset.
|
|
48
|
+
*
|
|
49
|
+
* Returns an empty error_code when the query succeeded (meta.status == "success", http_status is
|
|
50
|
+
* not 400, and no prepared-statement retry needed).
|
|
51
|
+
*
|
|
52
|
+
* http_status is the status of the response that carried the metadata, or 0 where there is none.
|
|
53
|
+
* A failure that matches no specific mapping is invalid_argument for an HTTP 400 (RFC-58) and
|
|
54
|
+
* internal_server_failure otherwise.
|
|
55
|
+
*/
|
|
56
|
+
[[nodiscard]] auto
|
|
57
|
+
map_query_error(const query_response::query_meta_data& meta, std::uint32_t http_status = 0)
|
|
58
|
+
-> std::error_code;
|
|
59
|
+
|
|
60
|
+
} // namespace couchbase::core::operations
|
|
@@ -28,8 +28,6 @@ struct s3_external_link;
|
|
|
28
28
|
|
|
29
29
|
namespace impl
|
|
30
30
|
{
|
|
31
|
-
struct get_replica_request;
|
|
32
|
-
struct get_replica_response;
|
|
33
31
|
struct lookup_in_replica_request;
|
|
34
32
|
struct lookup_in_replica_response;
|
|
35
33
|
struct observe_seqno_request;
|
|
@@ -51,6 +49,8 @@ struct decrement_response;
|
|
|
51
49
|
struct exists_request;
|
|
52
50
|
struct exists_response;
|
|
53
51
|
struct get_request;
|
|
52
|
+
struct get_replica_request;
|
|
53
|
+
struct get_replica_response;
|
|
54
54
|
struct get_response;
|
|
55
55
|
struct get_all_replicas_request;
|
|
56
56
|
struct get_all_replicas_response;
|
|
@@ -106,7 +106,7 @@ using replace_request_with_legacy_durability = impl::with_legacy_durability<repl
|
|
|
106
106
|
using upsert_request_with_legacy_durability = impl::with_legacy_durability<upsert_request>;
|
|
107
107
|
|
|
108
108
|
using get_request_with_cancellation = impl::with_cancellation<get_request>;
|
|
109
|
-
using get_replica_request_with_cancellation = impl::with_cancellation<
|
|
109
|
+
using get_replica_request_with_cancellation = impl::with_cancellation<get_replica_request>;
|
|
110
110
|
using lookup_in_request_with_cancellation = impl::with_cancellation<lookup_in_request>;
|
|
111
111
|
using lookup_in_replica_request_with_cancellation =
|
|
112
112
|
impl::with_cancellation<impl::lookup_in_replica_request>;
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
#include "origin.hxx"
|
|
19
|
-
#include <couchbase/build_config.hxx>
|
|
20
19
|
|
|
21
20
|
#include "core/utils/connection_string.hxx"
|
|
22
21
|
#include "topology/configuration.hxx"
|
|
@@ -224,24 +223,6 @@ struct traits<couchbase::transactions::transactions_config::built> {
|
|
|
224
223
|
}
|
|
225
224
|
};
|
|
226
225
|
|
|
227
|
-
template<>
|
|
228
|
-
struct traits<couchbase::core::columnar::security_options> {
|
|
229
|
-
template<template<typename...> class Traits>
|
|
230
|
-
static void assign(tao::json::basic_value<Traits>& v,
|
|
231
|
-
const couchbase::core::columnar::security_options& o)
|
|
232
|
-
{
|
|
233
|
-
v = {
|
|
234
|
-
{ "trust_only_capella", o.trust_only_capella },
|
|
235
|
-
{ "trust_only_pem_file", o.trust_only_pem_file },
|
|
236
|
-
{ "trust_only_pem_string", o.trust_only_pem_string },
|
|
237
|
-
{ "trust_only_platform", o.trust_only_platform },
|
|
238
|
-
{ "trust_only_certificates", o.trust_only_certificates.size() },
|
|
239
|
-
// TODO(JC): add if/when we support the cipher_suites option
|
|
240
|
-
// { "cipher_suites", utils::join_strings(o.cipher_suites, ":") },
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
|
|
245
226
|
} // namespace tao::json
|
|
246
227
|
|
|
247
228
|
namespace couchbase::core
|
|
@@ -267,13 +248,10 @@ origin::to_json() const -> std::string
|
|
|
267
248
|
{ "config_poll_floor", options_.config_poll_floor },
|
|
268
249
|
{ "user_agent_extra", options_.user_agent_extra },
|
|
269
250
|
{ "dump_configuration", options_.dump_configuration },
|
|
251
|
+
{ "log_redaction", options_.log_redaction },
|
|
270
252
|
{ "disable_mozilla_ca_certificates", options_.disable_mozilla_ca_certificates },
|
|
271
253
|
{ "network", options_.network },
|
|
272
254
|
{ "tls_verify", options_.tls_verify },
|
|
273
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
274
|
-
{ "dispatch_timeout", options_.dispatch_timeout },
|
|
275
|
-
{ "security_options", options_.security_options },
|
|
276
|
-
#else
|
|
277
255
|
{ "key_value_timeout", options_.key_value_timeout },
|
|
278
256
|
{ "key_value_durable_timeout", options_.key_value_durable_timeout },
|
|
279
257
|
{ "view_timeout", options_.view_timeout },
|
|
@@ -297,7 +275,6 @@ origin::to_json() const -> std::string
|
|
|
297
275
|
{ "orphan_reporter_options", options_.orphan_options },
|
|
298
276
|
{ "transactions_options", options_.transactions },
|
|
299
277
|
{ "server_group", options_.server_group },
|
|
300
|
-
#endif
|
|
301
278
|
},
|
|
302
279
|
},
|
|
303
280
|
};
|
|
@@ -311,6 +288,9 @@ origin::to_json() const -> std::string
|
|
|
311
288
|
}
|
|
312
289
|
json["bootstrap_nodes"] = nodes;
|
|
313
290
|
}
|
|
291
|
+
// Every value in here is left as it is. The document this returns is annotated as a whole at
|
|
292
|
+
// the log site, because a tag written into one of its string values would be read back as part
|
|
293
|
+
// of that value by anything that parses the line as JSON.
|
|
314
294
|
return tao::json::to_string(json);
|
|
315
295
|
}
|
|
316
296
|
|
|
@@ -319,9 +299,15 @@ origin::to_json() const -> std::string
|
|
|
319
299
|
couchbase::core::origin::origin(origin&& other) noexcept
|
|
320
300
|
: options_(std::move(other.options_))
|
|
321
301
|
, nodes_(std::move(other.nodes_))
|
|
322
|
-
|
|
302
|
+
// next_node_ is an iterator into nodes_. Container move construction transfers the buffer, so
|
|
303
|
+
// iterators into the source stay valid and now denote elements of nodes_ -- other.next_node_ can
|
|
304
|
+
// be adopted as-is, preserving the round-robin position. The empty case is guarded separately
|
|
305
|
+
// because that guarantee does not extend to a past-the-end iterator. nodes_ is declared before
|
|
306
|
+
// next_node_, so it is already initialized here.
|
|
307
|
+
, next_node_(nodes_.empty() ? nodes_.begin() : other.next_node_)
|
|
323
308
|
, exhausted_(other.exhausted_)
|
|
324
309
|
, connection_string_(std::move(other.connection_string_))
|
|
310
|
+
, uses_protostellar_(other.uses_protostellar_)
|
|
325
311
|
, credentials_(std::move(other.credentials_))
|
|
326
312
|
{
|
|
327
313
|
}
|
|
@@ -330,20 +316,38 @@ auto
|
|
|
330
316
|
couchbase::core::origin::operator=(origin&& other) noexcept -> origin&
|
|
331
317
|
{
|
|
332
318
|
if (this != &other) {
|
|
319
|
+
const auto offset = other.nodes_.empty() ? 0 : other.next_node_ - other.nodes_.begin();
|
|
333
320
|
options_ = std::move(other.options_);
|
|
334
321
|
nodes_ = std::move(other.nodes_);
|
|
335
|
-
next_node_ =
|
|
322
|
+
next_node_ = nodes_.begin() + offset;
|
|
336
323
|
exhausted_ = other.exhausted_;
|
|
337
324
|
connection_string_ = std::move(other.connection_string_);
|
|
325
|
+
uses_protostellar_ = other.uses_protostellar_;
|
|
338
326
|
credentials_ = std::move(other.credentials_);
|
|
339
327
|
}
|
|
340
328
|
return *this;
|
|
341
329
|
}
|
|
342
330
|
|
|
331
|
+
// A copy is a fresh origin that has not attempted anything, so the rotation cursor is deliberately
|
|
332
|
+
// reset rather than carried. This matters: next_address() marks an origin exhausted as it hands out
|
|
333
|
+
// the *last* node, which on a single-node cluster is the very first call, so a cluster origin is
|
|
334
|
+
// normally exhausted immediately after bootstrap. open_bucket() copies that origin into every
|
|
335
|
+
// bucket and on into every session, and mcbp_session::initiate_bootstrap() tests exhausted()
|
|
336
|
+
// before it ever calls next_address() -- so carrying the flag would send a session that has tried
|
|
337
|
+
// nothing down the "reached the end of the list of bootstrap nodes" path: an unconditional 500 ms
|
|
338
|
+
// backoff.
|
|
339
|
+
//
|
|
340
|
+
// Moving, by contrast, does carry it: a move transfers identity rather than producing an
|
|
341
|
+
// independent origin.
|
|
342
|
+
//
|
|
343
|
+
// connection_string_ and uses_protostellar_ *are* copied. They were being dropped entirely, which
|
|
344
|
+
// left connection_string() returning "" on any copied origin.
|
|
343
345
|
couchbase::core::origin::origin(const couchbase::core::origin& other)
|
|
344
346
|
: options_(other.options_)
|
|
345
347
|
, nodes_(other.nodes_)
|
|
346
348
|
, next_node_(nodes_.begin())
|
|
349
|
+
, connection_string_(other.connection_string_)
|
|
350
|
+
, uses_protostellar_(other.uses_protostellar_)
|
|
347
351
|
{
|
|
348
352
|
update_credentials(other.credentials());
|
|
349
353
|
}
|
|
@@ -378,6 +382,7 @@ couchbase::core::origin::origin(couchbase::core::cluster_credentials auth,
|
|
|
378
382
|
const couchbase::core::utils::connection_string& connstr)
|
|
379
383
|
: options_(connstr.options)
|
|
380
384
|
, connection_string_(connstr.input)
|
|
385
|
+
, uses_protostellar_(connstr.uses_protostellar())
|
|
381
386
|
, credentials_(std::move(auth))
|
|
382
387
|
{
|
|
383
388
|
nodes_.reserve(connstr.bootstrap_nodes.size());
|
|
@@ -396,10 +401,13 @@ couchbase::core::origin::operator=(const couchbase::core::origin& other) -> couc
|
|
|
396
401
|
{
|
|
397
402
|
if (this != &other) {
|
|
398
403
|
options_ = other.options_;
|
|
404
|
+
connection_string_ = other.connection_string_;
|
|
399
405
|
update_credentials(other.credentials());
|
|
400
406
|
nodes_ = other.nodes_;
|
|
407
|
+
// Rotation state is reset, not carried -- see the copy constructor for why.
|
|
401
408
|
next_node_ = nodes_.begin();
|
|
402
409
|
exhausted_ = false;
|
|
410
|
+
uses_protostellar_ = other.uses_protostellar_;
|
|
403
411
|
}
|
|
404
412
|
return *this;
|
|
405
413
|
}
|
|
@@ -409,6 +417,11 @@ couchbase::core::origin::connection_string() const -> const std::string&
|
|
|
409
417
|
return connection_string_;
|
|
410
418
|
}
|
|
411
419
|
auto
|
|
420
|
+
couchbase::core::origin::uses_protostellar() const -> bool
|
|
421
|
+
{
|
|
422
|
+
return uses_protostellar_;
|
|
423
|
+
}
|
|
424
|
+
auto
|
|
412
425
|
couchbase::core::origin::username() const -> std::string
|
|
413
426
|
{
|
|
414
427
|
const std::shared_lock lock(credentials_mutex_);
|
|
@@ -458,6 +471,16 @@ couchbase::core::origin::get_nodes() const -> std::vector<std::string>
|
|
|
458
471
|
}
|
|
459
472
|
return res;
|
|
460
473
|
}
|
|
474
|
+
auto
|
|
475
|
+
couchbase::core::origin::get_node_addresses() const -> std::vector<std::string>
|
|
476
|
+
{
|
|
477
|
+
std::vector<std::string> res;
|
|
478
|
+
res.reserve(nodes_.size());
|
|
479
|
+
for (const auto& [hostname, port] : nodes_) {
|
|
480
|
+
res.emplace_back(fmt::format("{}:{}", hostname, port));
|
|
481
|
+
}
|
|
482
|
+
return res;
|
|
483
|
+
}
|
|
461
484
|
|
|
462
485
|
void
|
|
463
486
|
couchbase::core::origin::shuffle_nodes()
|
|
@@ -502,6 +525,11 @@ couchbase::core::origin::set_nodes_from_config(const topology::configuration& co
|
|
|
502
525
|
shuffle_nodes();
|
|
503
526
|
}
|
|
504
527
|
next_node_ = nodes_.begin();
|
|
528
|
+
// Matches set_nodes(): the node list has just been replaced, so any exhaustion recorded against
|
|
529
|
+
// the previous list is meaningless. Without this an origin that was exhausted stays exhausted
|
|
530
|
+
// across every config update -- cluster.cxx calls this on a long-lived origin that
|
|
531
|
+
// next_address() will have marked exhausted.
|
|
532
|
+
exhausted_ = false;
|
|
505
533
|
}
|
|
506
534
|
void
|
|
507
535
|
couchbase::core::origin::update_credentials(cluster_credentials auth)
|
|
@@ -60,6 +60,9 @@ struct origin {
|
|
|
60
60
|
auto operator=(const origin& other) -> origin&;
|
|
61
61
|
|
|
62
62
|
[[nodiscard]] auto connection_string() const -> const std::string&;
|
|
63
|
+
// True when built from a couchbase2:// connection string (Protostellar transport). Lets the
|
|
64
|
+
// connect path branch to the gRPC client without re-parsing the connection string.
|
|
65
|
+
[[nodiscard]] auto uses_protostellar() const -> bool;
|
|
63
66
|
[[nodiscard]] auto username() const -> std::string;
|
|
64
67
|
[[nodiscard]] auto password() const -> std::string;
|
|
65
68
|
[[nodiscard]] auto certificate_path() const -> std::string;
|
|
@@ -68,6 +71,10 @@ struct origin {
|
|
|
68
71
|
|
|
69
72
|
[[nodiscard]] auto get_hostnames() const -> std::vector<std::string>;
|
|
70
73
|
[[nodiscard]] auto get_nodes() const -> std::vector<std::string>;
|
|
74
|
+
// The same addresses as get_nodes(), without the display quotes baked into each entry. Log
|
|
75
|
+
// statements want them bare so that logger::system_data_list() can put a tag inside the quotes it
|
|
76
|
+
// renders; a tag around a pre-quoted entry hashes the punctuation with the value.
|
|
77
|
+
[[nodiscard]] auto get_node_addresses() const -> std::vector<std::string>;
|
|
71
78
|
|
|
72
79
|
void shuffle_nodes();
|
|
73
80
|
void set_nodes(node_list nodes);
|
|
@@ -84,6 +91,10 @@ struct origin {
|
|
|
84
91
|
[[nodiscard]] auto options() const -> const couchbase::core::cluster_options&;
|
|
85
92
|
[[nodiscard]] auto options() -> couchbase::core::cluster_options&;
|
|
86
93
|
[[nodiscard]] auto credentials() const -> couchbase::core::cluster_credentials;
|
|
94
|
+
// A JSON dump of the whole origin, less the credentials. Its only callers are the log
|
|
95
|
+
// statements in the cluster open paths, and they annotate the whole document: a tag written
|
|
96
|
+
// into one of these values instead would be read back as part of that value by anything that
|
|
97
|
+
// parses the line as JSON. So nothing in here is annotated.
|
|
87
98
|
[[nodiscard]] auto to_json() const -> std::string;
|
|
88
99
|
|
|
89
100
|
private:
|
|
@@ -92,6 +103,7 @@ private:
|
|
|
92
103
|
node_list::iterator next_node_{};
|
|
93
104
|
bool exhausted_{ false };
|
|
94
105
|
std::string connection_string_{};
|
|
106
|
+
bool uses_protostellar_{ false };
|
|
95
107
|
cluster_credentials credentials_{};
|
|
96
108
|
mutable std::shared_mutex credentials_mutex_{};
|
|
97
109
|
};
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
#include <couchbase/build_info.hxx>
|
|
21
21
|
|
|
22
22
|
#include "logger/logger.hxx"
|
|
23
|
+
#include "logger/redaction.hxx"
|
|
23
24
|
#include "utils/concurrent_fixed_priority_queue.hxx"
|
|
24
25
|
#include "utils/json.hxx"
|
|
25
26
|
|
|
@@ -120,7 +121,7 @@ private:
|
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
if (auto report = self->flush_and_create_output(); report.has_value()) {
|
|
123
|
-
CB_LOG_WARNING("Orphan responses observed: {}", report.value());
|
|
124
|
+
CB_LOG_WARNING("Orphan responses observed: {}", logger::system_data(report.value()));
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
self->rearm();
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
#include <mutex>
|
|
26
26
|
#include <system_error>
|
|
27
27
|
|
|
28
|
-
#ifdef
|
|
28
|
+
#ifdef _WIN32
|
|
29
29
|
// We need to include windows.h _before_ wincrypt.h
|
|
30
30
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
31
31
|
#define WIN32_LEAN_AND_MEAN
|
|
@@ -45,7 +45,7 @@ class RandomGeneratorProvider
|
|
|
45
45
|
public:
|
|
46
46
|
RandomGeneratorProvider()
|
|
47
47
|
{
|
|
48
|
-
#ifdef
|
|
48
|
+
#ifdef _WIN32
|
|
49
49
|
if (!CryptAcquireContext(
|
|
50
50
|
&handle, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
|
|
51
51
|
throw std::system_error(int(GetLastError()),
|
|
@@ -69,7 +69,7 @@ public:
|
|
|
69
69
|
|
|
70
70
|
virtual ~RandomGeneratorProvider()
|
|
71
71
|
{
|
|
72
|
-
#ifdef
|
|
72
|
+
#ifdef _WIN32
|
|
73
73
|
CryptReleaseContext(handle, 0);
|
|
74
74
|
#else
|
|
75
75
|
close(handle);
|
|
@@ -78,8 +78,8 @@ public:
|
|
|
78
78
|
|
|
79
79
|
auto getBytes(void* dest, std::size_t size) -> bool
|
|
80
80
|
{
|
|
81
|
-
const std::
|
|
82
|
-
#ifdef
|
|
81
|
+
const std::scoped_lock<std::mutex> lock(mutex);
|
|
82
|
+
#ifdef _WIN32
|
|
83
83
|
return CryptGenRandom(handle, (DWORD)size, static_cast<BYTE*>(dest));
|
|
84
84
|
#else
|
|
85
85
|
#if defined(__clang__) && defined(__clang_analyzer__)
|
|
@@ -92,7 +92,7 @@ public:
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
private:
|
|
95
|
-
#ifdef
|
|
95
|
+
#ifdef _WIN32
|
|
96
96
|
HCRYPTPROV handle{};
|
|
97
97
|
#else
|
|
98
98
|
int handle = -1;
|
|
@@ -107,7 +107,7 @@ RandomGenerator::RandomGenerator()
|
|
|
107
107
|
{
|
|
108
108
|
if (!shared_provider) {
|
|
109
109
|
// This might be the first one, lets lock and create
|
|
110
|
-
const std::
|
|
110
|
+
const std::scoped_lock<std::mutex> guard(shared_provider_lock);
|
|
111
111
|
if (!shared_provider) { // cppcheck-suppress identicalInnerCondition; DCLP
|
|
112
112
|
shared_provider = std::make_unique<RandomGeneratorProvider>();
|
|
113
113
|
}
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
namespace couchbase::core::protocol
|
|
24
24
|
{
|
|
25
25
|
auto
|
|
26
|
-
compress_value(const std::vector<std::byte>& value,
|
|
27
|
-
|
|
26
|
+
compress_value(const std::vector<std::byte>& value, const std::vector<std::byte>::iterator& output)
|
|
27
|
+
-> std::pair<bool, std::uint32_t>
|
|
28
28
|
{
|
|
29
29
|
static const double min_ratio = 0.83;
|
|
30
30
|
|