couchbase 3.8.2 → 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 +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 +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 +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 +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 +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 +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 +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 +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 +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,265 @@
|
|
|
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 N1QL query request/response to and from the couchbase.query.v1 protobuf
|
|
21
|
+
// messages. Rows arrive across streamed QueryResponse messages and are buffered into
|
|
22
|
+
// query_response::rows when no callback is provided, or delivered incrementally to row_callback
|
|
23
|
+
// when present; the terminal message carries the metadata. Deliberately does not reuse the
|
|
24
|
+
// MCBP-bound encode_to/make_response (those build an HTTP body + parse a JSON reply).
|
|
25
|
+
//
|
|
26
|
+
// Query features with no couchbase2 equivalent are reported by can_encode() so the component can
|
|
27
|
+
// surface feature_not_available rather than silently dropping them: the `raw` passthrough map,
|
|
28
|
+
// use_replica, node targeting via send_to_node, and tuning values too large for the proto's
|
|
29
|
+
// uint32 fields.
|
|
30
|
+
|
|
31
|
+
#include "core/json_string.hxx"
|
|
32
|
+
#include "core/operations/document_query.hxx"
|
|
33
|
+
#include "core/protostellar/json_payload.hxx"
|
|
34
|
+
#include "core/protostellar/query_proto.hxx"
|
|
35
|
+
|
|
36
|
+
#include <couchbase/query_profile.hxx>
|
|
37
|
+
#include <couchbase/query_scan_consistency.hxx>
|
|
38
|
+
|
|
39
|
+
#include <chrono>
|
|
40
|
+
#include <cstdint>
|
|
41
|
+
#include <limits>
|
|
42
|
+
#include <optional>
|
|
43
|
+
#include <string>
|
|
44
|
+
|
|
45
|
+
namespace couchbase::core::protostellar::query
|
|
46
|
+
{
|
|
47
|
+
namespace v1 = ::couchbase::query::v1;
|
|
48
|
+
|
|
49
|
+
// The proto's tuning fields are uint32 while the core request holds them as uint64, so a value
|
|
50
|
+
// that does not fit is not encodable: casting it would ask the gateway to use the wrapped number.
|
|
51
|
+
[[nodiscard]] inline auto
|
|
52
|
+
fits_uint32(const std::optional<std::uint64_t>& value) -> bool
|
|
53
|
+
{
|
|
54
|
+
return !value.has_value() || *value <= std::numeric_limits<std::uint32_t>::max();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Query request features the couchbase2 gateway schema cannot express yet. The component maps this
|
|
58
|
+
// to feature_not_available instead of silently ignoring the caller's intent.
|
|
59
|
+
[[nodiscard]] inline auto
|
|
60
|
+
can_encode(const operations::query_request& request) -> bool
|
|
61
|
+
{
|
|
62
|
+
return request.raw.empty() && !request.use_replica.value_or(false) &&
|
|
63
|
+
!request.send_to_node.has_value() && fits_uint32(request.max_parallelism) &&
|
|
64
|
+
fits_uint32(request.pipeline_batch) && fits_uint32(request.pipeline_cap) &&
|
|
65
|
+
fits_uint32(request.scan_cap);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Split the SDK query_context ("default:`bucket`.`scope`") into the proto's bucket_name/scope_name.
|
|
69
|
+
// Any pair of backtick-delimited identifiers is accepted; a value that does not parse leaves both
|
|
70
|
+
// unset (the statement is then expected to be fully qualified).
|
|
71
|
+
inline void
|
|
72
|
+
apply_query_context(const std::string& query_context, v1::QueryRequest& proto)
|
|
73
|
+
{
|
|
74
|
+
std::string bucket;
|
|
75
|
+
std::string scope;
|
|
76
|
+
std::string* current = &bucket;
|
|
77
|
+
bool inside = false;
|
|
78
|
+
int identifiers = 0;
|
|
79
|
+
for (const char c : query_context) {
|
|
80
|
+
if (c == '`') {
|
|
81
|
+
if (inside) { // closing backtick ends an identifier
|
|
82
|
+
++identifiers;
|
|
83
|
+
if (identifiers == 1) {
|
|
84
|
+
current = &scope;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
inside = !inside;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (inside) {
|
|
91
|
+
current->push_back(c);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// A well-formed context is exactly two balanced backtick-delimited identifiers
|
|
95
|
+
// (`bucket`.`scope`). Anything else -- unbalanced, too few, or too many -- leaves both unset
|
|
96
|
+
// rather than routing on a half- or mis-parsed context.
|
|
97
|
+
if (!inside && identifiers == 2 && !bucket.empty() && !scope.empty()) {
|
|
98
|
+
proto.set_bucket_name(bucket);
|
|
99
|
+
proto.set_scope_name(scope);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
inline auto
|
|
104
|
+
encode(const operations::query_request& request) -> v1::QueryRequest
|
|
105
|
+
{
|
|
106
|
+
v1::QueryRequest proto;
|
|
107
|
+
proto.set_statement(request.statement);
|
|
108
|
+
if (request.client_context_id.has_value()) {
|
|
109
|
+
proto.set_client_context_id(*request.client_context_id);
|
|
110
|
+
}
|
|
111
|
+
if (request.query_context.has_value()) {
|
|
112
|
+
apply_query_context(*request.query_context, proto);
|
|
113
|
+
}
|
|
114
|
+
proto.set_read_only(request.readonly);
|
|
115
|
+
proto.set_flex_index(request.flex_index);
|
|
116
|
+
proto.set_preserve_expiry(request.preserve_expiry);
|
|
117
|
+
// adhoc=false means "use a prepared statement" on the MCBP path; the gateway prepares/caches on
|
|
118
|
+
// its side, so we only signal intent.
|
|
119
|
+
if (!request.adhoc) {
|
|
120
|
+
proto.set_prepared(true);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (request.scan_consistency.has_value()) {
|
|
124
|
+
switch (*request.scan_consistency) {
|
|
125
|
+
case query_scan_consistency::not_bounded:
|
|
126
|
+
proto.set_scan_consistency(v1::QueryRequest_ScanConsistency_SCAN_CONSISTENCY_NOT_BOUNDED);
|
|
127
|
+
break;
|
|
128
|
+
case query_scan_consistency::request_plus:
|
|
129
|
+
proto.set_scan_consistency(v1::QueryRequest_ScanConsistency_SCAN_CONSISTENCY_REQUEST_PLUS);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// A non-empty mutation_state carries at_plus scan vectors; the gateway takes them as
|
|
134
|
+
// consistent_with mutation tokens.
|
|
135
|
+
for (const auto& token : request.mutation_state) {
|
|
136
|
+
auto* proto_token = proto.add_consistent_with();
|
|
137
|
+
proto_token->set_bucket_name(token.bucket_name());
|
|
138
|
+
proto_token->set_vbucket_id(token.partition_id());
|
|
139
|
+
proto_token->set_vbucket_uuid(token.partition_uuid());
|
|
140
|
+
proto_token->set_seq_no(token.sequence_number());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (request.profile.has_value()) {
|
|
144
|
+
switch (*request.profile) {
|
|
145
|
+
case query_profile::off:
|
|
146
|
+
proto.set_profile_mode(v1::QueryRequest_ProfileMode_PROFILE_MODE_OFF);
|
|
147
|
+
break;
|
|
148
|
+
case query_profile::phases:
|
|
149
|
+
proto.set_profile_mode(v1::QueryRequest_ProfileMode_PROFILE_MODE_PHASES);
|
|
150
|
+
break;
|
|
151
|
+
case query_profile::timings:
|
|
152
|
+
proto.set_profile_mode(v1::QueryRequest_ProfileMode_PROFILE_MODE_TIMINGS);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
for (const auto& parameter : request.positional_parameters) {
|
|
158
|
+
proto.add_positional_parameters(json_payload(parameter));
|
|
159
|
+
}
|
|
160
|
+
for (const auto& [name, value] : request.named_parameters) {
|
|
161
|
+
(*proto.mutable_named_parameters())[name] = json_payload(value);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Tuning options: the SDK's `metrics` flag defaults to off, so disable_metrics is its inverse.
|
|
165
|
+
auto* tuning = proto.mutable_tuning_options();
|
|
166
|
+
tuning->set_disable_metrics(!request.metrics);
|
|
167
|
+
if (request.max_parallelism.has_value()) {
|
|
168
|
+
tuning->set_max_parallelism(static_cast<std::uint32_t>(*request.max_parallelism));
|
|
169
|
+
}
|
|
170
|
+
if (request.pipeline_batch.has_value()) {
|
|
171
|
+
tuning->set_pipeline_batch(static_cast<std::uint32_t>(*request.pipeline_batch));
|
|
172
|
+
}
|
|
173
|
+
if (request.pipeline_cap.has_value()) {
|
|
174
|
+
tuning->set_pipeline_cap(static_cast<std::uint32_t>(*request.pipeline_cap));
|
|
175
|
+
}
|
|
176
|
+
if (request.scan_cap.has_value()) {
|
|
177
|
+
tuning->set_scan_cap(static_cast<std::uint32_t>(*request.scan_cap));
|
|
178
|
+
}
|
|
179
|
+
if (request.scan_wait.has_value()) {
|
|
180
|
+
const auto secs = std::chrono::duration_cast<std::chrono::seconds>(*request.scan_wait);
|
|
181
|
+
const auto nanos =
|
|
182
|
+
std::chrono::duration_cast<std::chrono::nanoseconds>(*request.scan_wait - secs);
|
|
183
|
+
auto* scan_wait = tuning->mutable_scan_wait();
|
|
184
|
+
scan_wait->set_seconds(secs.count());
|
|
185
|
+
scan_wait->set_nanos(static_cast<std::int32_t>(nanos.count()));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return proto;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// google.protobuf.Duration -> nanoseconds.
|
|
192
|
+
[[nodiscard]] inline auto
|
|
193
|
+
to_nanoseconds(const google::protobuf::Duration& duration) -> std::chrono::nanoseconds
|
|
194
|
+
{
|
|
195
|
+
return std::chrono::seconds{ duration.seconds() } + std::chrono::nanoseconds{ duration.nanos() };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
[[nodiscard]] inline auto
|
|
199
|
+
status_to_string(v1::QueryResponse_MetaData_Status status) -> std::string
|
|
200
|
+
{
|
|
201
|
+
switch (status) {
|
|
202
|
+
case v1::QueryResponse_MetaData_Status_STATUS_RUNNING:
|
|
203
|
+
return "running";
|
|
204
|
+
case v1::QueryResponse_MetaData_Status_STATUS_SUCCESS:
|
|
205
|
+
return "success";
|
|
206
|
+
case v1::QueryResponse_MetaData_Status_STATUS_ERRORS:
|
|
207
|
+
return "errors";
|
|
208
|
+
case v1::QueryResponse_MetaData_Status_STATUS_COMPLETED:
|
|
209
|
+
return "completed";
|
|
210
|
+
case v1::QueryResponse_MetaData_Status_STATUS_STOPPED:
|
|
211
|
+
return "stopped";
|
|
212
|
+
case v1::QueryResponse_MetaData_Status_STATUS_TIMEOUT:
|
|
213
|
+
return "timeout";
|
|
214
|
+
case v1::QueryResponse_MetaData_Status_STATUS_CLOSED:
|
|
215
|
+
return "closed";
|
|
216
|
+
case v1::QueryResponse_MetaData_Status_STATUS_FATAL:
|
|
217
|
+
return "fatal";
|
|
218
|
+
case v1::QueryResponse_MetaData_Status_STATUS_ABORTED:
|
|
219
|
+
return "aborted";
|
|
220
|
+
default:
|
|
221
|
+
return "unknown";
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Fill a query_meta_data from the terminal QueryResponse.MetaData message.
|
|
226
|
+
inline void
|
|
227
|
+
decode_meta_data(const v1::QueryResponse_MetaData& proto,
|
|
228
|
+
operations::query_response::query_meta_data& meta)
|
|
229
|
+
{
|
|
230
|
+
meta.request_id = proto.request_id();
|
|
231
|
+
meta.client_context_id = proto.client_context_id();
|
|
232
|
+
meta.status = status_to_string(proto.status());
|
|
233
|
+
if (!proto.signature().empty()) {
|
|
234
|
+
meta.signature = proto.signature();
|
|
235
|
+
}
|
|
236
|
+
if (!proto.profile().empty()) {
|
|
237
|
+
meta.profile = proto.profile();
|
|
238
|
+
}
|
|
239
|
+
if (proto.has_metrics()) {
|
|
240
|
+
const auto& m = proto.metrics();
|
|
241
|
+
operations::query_response::query_metrics metrics;
|
|
242
|
+
metrics.elapsed_time = to_nanoseconds(m.elapsed_time());
|
|
243
|
+
metrics.execution_time = to_nanoseconds(m.execution_time());
|
|
244
|
+
metrics.result_count = m.result_count();
|
|
245
|
+
metrics.result_size = m.result_size();
|
|
246
|
+
metrics.sort_count = m.sort_count();
|
|
247
|
+
metrics.mutation_count = m.mutation_count();
|
|
248
|
+
metrics.error_count = m.error_count();
|
|
249
|
+
metrics.warning_count = m.warning_count();
|
|
250
|
+
meta.metrics = metrics;
|
|
251
|
+
}
|
|
252
|
+
if (proto.warnings_size() > 0) {
|
|
253
|
+
std::vector<operations::query_response::query_problem> warnings;
|
|
254
|
+
warnings.reserve(static_cast<std::size_t>(proto.warnings_size()));
|
|
255
|
+
for (const auto& w : proto.warnings()) {
|
|
256
|
+
operations::query_response::query_problem problem;
|
|
257
|
+
problem.code = w.code();
|
|
258
|
+
problem.message = w.message();
|
|
259
|
+
warnings.push_back(std::move(problem));
|
|
260
|
+
}
|
|
261
|
+
meta.warnings = std::move(warnings);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
} // namespace couchbase::core::protostellar::query
|
|
@@ -0,0 +1,291 @@
|
|
|
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 core query index management requests to and from couchbase.admin.query.v1 (unary
|
|
21
|
+
// admin RPCs). The proto IndexType / IndexState enums have no `unknown` sentinel; they map to the
|
|
22
|
+
// lowercase strings the rest of the SDK uses.
|
|
23
|
+
//
|
|
24
|
+
// The gateway builds the N1QL statement from the request rather than taking one, so the encode
|
|
25
|
+
// side owns everything the statement's shape depends on: which RPC a primary index goes to, and
|
|
26
|
+
// how an index key is escaped.
|
|
27
|
+
|
|
28
|
+
#include "core/operations/management/query_index_build_deferred.hxx"
|
|
29
|
+
#include "core/operations/management/query_index_create.hxx"
|
|
30
|
+
#include "core/operations/management/query_index_drop.hxx"
|
|
31
|
+
#include "core/operations/management/query_index_get_all.hxx"
|
|
32
|
+
#include "couchbase/management/query_index.hxx"
|
|
33
|
+
|
|
34
|
+
#include <couchbase/admin/query/v1/query.pb.h>
|
|
35
|
+
|
|
36
|
+
#include <cstddef>
|
|
37
|
+
#include <string>
|
|
38
|
+
|
|
39
|
+
namespace couchbase::core::protostellar::query_index_admin
|
|
40
|
+
{
|
|
41
|
+
namespace v1 = ::couchbase::admin::query::v1;
|
|
42
|
+
namespace om = ::couchbase::core::operations::management;
|
|
43
|
+
|
|
44
|
+
// Whether the key is already one complete escaped identifier: an opening backtick, a body in which
|
|
45
|
+
// every backslash escapes the character after it and every backtick is escaped or doubled, and the
|
|
46
|
+
// closing backtick at the very end of the key.
|
|
47
|
+
//
|
|
48
|
+
// Ending exactly at the end is the whole question. A key whose identifier closes early -- "`a`,`b`"
|
|
49
|
+
// -- leaves the remainder as loose statement text, and a key ending in a lone backslash -- "`a\" --
|
|
50
|
+
// escapes its own closing backtick and swallows what follows it.
|
|
51
|
+
[[nodiscard]] inline auto
|
|
52
|
+
is_escaped_identifier(const std::string& key) -> bool
|
|
53
|
+
{
|
|
54
|
+
if (key.size() < 2 || key.front() != '`' || key.back() != '`') {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const auto last = key.size() - 1;
|
|
58
|
+
for (std::size_t i = 1; i < last;) {
|
|
59
|
+
if (key[i] == '\\') {
|
|
60
|
+
if (i + 1 >= last) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
i += 2;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (key[i] == '`') {
|
|
67
|
+
if (i + 1 < last && key[i + 1] == '`') {
|
|
68
|
+
i += 2;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
i += 1;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Escapes one index key into exactly one N1QL identifier token.
|
|
79
|
+
//
|
|
80
|
+
// This is the transport's only client-supplied statement text. The gateway builds the statement
|
|
81
|
+
// itself and joins the field list with commas verbatim (gocbcorex cbqueryx), so whatever arrives in
|
|
82
|
+
// `fields` is spliced between the parentheses of CREATE INDEX unchanged. A key that closed its own
|
|
83
|
+
// quoting would add terms to the index -- or change the statement -- rather than name a field.
|
|
84
|
+
//
|
|
85
|
+
// The escape is the one the query parser reads back: a backslash escapes the character after it
|
|
86
|
+
// (parser/n1ql/util.go), so a backtick and a backslash each arrive prefixed by one. Doubling the
|
|
87
|
+
// backtick instead would parse, but reads back as two backticks in the name rather than one, and
|
|
88
|
+
// leaving the backslash bare makes the parser reject the whole statement. Anything else inside the
|
|
89
|
+
// quotes -- spaces, commas, parentheses, newlines -- is part of the identifier and needs no escape,
|
|
90
|
+
// which is why "two words" is a key and not a syntax error.
|
|
91
|
+
//
|
|
92
|
+
// A key that is already one complete identifier is passed through, because that is the form
|
|
93
|
+
// GetAllIndexes reports keys in and the classic query path accepts. "Already" is verified rather
|
|
94
|
+
// than assumed: is_escaped_identifier() is what separates a caller's pre-quoted key from a key
|
|
95
|
+
// carrying quotes that end early.
|
|
96
|
+
[[nodiscard]] inline auto
|
|
97
|
+
encode_index_key(const std::string& key) -> std::string
|
|
98
|
+
{
|
|
99
|
+
if (is_escaped_identifier(key)) {
|
|
100
|
+
return key;
|
|
101
|
+
}
|
|
102
|
+
std::string escaped;
|
|
103
|
+
escaped.reserve(key.size() + 2);
|
|
104
|
+
escaped.push_back('`');
|
|
105
|
+
for (const auto c : key) {
|
|
106
|
+
if (c == '\\' || c == '`') {
|
|
107
|
+
escaped.push_back('\\');
|
|
108
|
+
}
|
|
109
|
+
escaped.push_back(c);
|
|
110
|
+
}
|
|
111
|
+
escaped.push_back('`');
|
|
112
|
+
return escaped;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Copies the keyspace onto a request whose scope/collection fields are `optional string`. An empty
|
|
116
|
+
// name is left unset: the gateway reads an unset scope as "the whole bucket", and a present-but-
|
|
117
|
+
// empty one as a scope literally named "", which it rejects.
|
|
118
|
+
template<typename Proto>
|
|
119
|
+
void
|
|
120
|
+
apply_keyspace(const std::string& bucket_name,
|
|
121
|
+
const std::string& scope_name,
|
|
122
|
+
const std::string& collection_name,
|
|
123
|
+
Proto& proto)
|
|
124
|
+
{
|
|
125
|
+
proto.set_bucket_name(bucket_name);
|
|
126
|
+
if (!scope_name.empty()) {
|
|
127
|
+
proto.set_scope_name(scope_name);
|
|
128
|
+
}
|
|
129
|
+
if (!collection_name.empty()) {
|
|
130
|
+
proto.set_collection_name(collection_name);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// couchbase2 CreateIndexRequest has no condition field, so a secondary index with a WHERE clause
|
|
135
|
+
// cannot be expressed at all -- encoding one would create an index over the whole collection under
|
|
136
|
+
// the name the caller asked for. A primary index has no condition to lose.
|
|
137
|
+
[[nodiscard]] inline auto
|
|
138
|
+
can_encode(const om::query_index_create_request& request) -> bool
|
|
139
|
+
{
|
|
140
|
+
return request.is_primary || !request.condition.has_value();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
[[nodiscard]] inline auto
|
|
144
|
+
encode_get_all(const om::query_index_get_all_request& request) -> v1::GetAllIndexesRequest
|
|
145
|
+
{
|
|
146
|
+
v1::GetAllIndexesRequest proto;
|
|
147
|
+
apply_keyspace(request.bucket_name, request.scope_name, request.collection_name, proto);
|
|
148
|
+
return proto;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
[[nodiscard]] inline auto
|
|
152
|
+
encode_create_primary(const om::query_index_create_request& request)
|
|
153
|
+
-> v1::CreatePrimaryIndexRequest
|
|
154
|
+
{
|
|
155
|
+
v1::CreatePrimaryIndexRequest proto;
|
|
156
|
+
apply_keyspace(request.bucket_name, request.scope_name, request.collection_name, proto);
|
|
157
|
+
// An unset name asks the server for its own default (#primary); an empty one is not a name.
|
|
158
|
+
if (!request.index_name.empty()) {
|
|
159
|
+
proto.set_name(request.index_name);
|
|
160
|
+
}
|
|
161
|
+
if (request.num_replicas.has_value()) {
|
|
162
|
+
proto.set_num_replicas(*request.num_replicas);
|
|
163
|
+
}
|
|
164
|
+
if (request.deferred.has_value()) {
|
|
165
|
+
proto.set_deferred(*request.deferred);
|
|
166
|
+
}
|
|
167
|
+
proto.set_ignore_if_exists(request.ignore_if_exists);
|
|
168
|
+
return proto;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
[[nodiscard]] inline auto
|
|
172
|
+
encode_create(const om::query_index_create_request& request) -> v1::CreateIndexRequest
|
|
173
|
+
{
|
|
174
|
+
v1::CreateIndexRequest proto;
|
|
175
|
+
apply_keyspace(request.bucket_name, request.scope_name, request.collection_name, proto);
|
|
176
|
+
proto.set_name(request.index_name);
|
|
177
|
+
for (const auto& key : request.keys) {
|
|
178
|
+
proto.add_fields(encode_index_key(key));
|
|
179
|
+
}
|
|
180
|
+
if (request.num_replicas.has_value()) {
|
|
181
|
+
proto.set_num_replicas(*request.num_replicas);
|
|
182
|
+
}
|
|
183
|
+
if (request.deferred.has_value()) {
|
|
184
|
+
proto.set_deferred(*request.deferred);
|
|
185
|
+
}
|
|
186
|
+
proto.set_ignore_if_exists(request.ignore_if_exists);
|
|
187
|
+
return proto;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
[[nodiscard]] inline auto
|
|
191
|
+
encode_drop_primary(const om::query_index_drop_request& request) -> v1::DropPrimaryIndexRequest
|
|
192
|
+
{
|
|
193
|
+
v1::DropPrimaryIndexRequest proto;
|
|
194
|
+
apply_keyspace(request.bucket_name, request.scope_name, request.collection_name, proto);
|
|
195
|
+
if (!request.index_name.empty()) {
|
|
196
|
+
proto.set_name(request.index_name);
|
|
197
|
+
}
|
|
198
|
+
proto.set_ignore_if_missing(request.ignore_if_does_not_exist);
|
|
199
|
+
return proto;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
[[nodiscard]] inline auto
|
|
203
|
+
encode_drop(const om::query_index_drop_request& request) -> v1::DropIndexRequest
|
|
204
|
+
{
|
|
205
|
+
v1::DropIndexRequest proto;
|
|
206
|
+
apply_keyspace(request.bucket_name, request.scope_name, request.collection_name, proto);
|
|
207
|
+
proto.set_name(request.index_name);
|
|
208
|
+
proto.set_ignore_if_missing(request.ignore_if_does_not_exist);
|
|
209
|
+
return proto;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
[[nodiscard]] inline auto
|
|
213
|
+
encode_build_deferred(const om::query_index_build_deferred_request& request)
|
|
214
|
+
-> v1::BuildDeferredIndexesRequest
|
|
215
|
+
{
|
|
216
|
+
v1::BuildDeferredIndexesRequest proto;
|
|
217
|
+
apply_keyspace(request.bucket_name,
|
|
218
|
+
request.scope_name.value_or(std::string{}),
|
|
219
|
+
request.collection_name.value_or(std::string{}),
|
|
220
|
+
proto);
|
|
221
|
+
return proto;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
[[nodiscard]] inline auto
|
|
225
|
+
index_type_to_string(v1::IndexType type) -> std::string
|
|
226
|
+
{
|
|
227
|
+
switch (type) {
|
|
228
|
+
case v1::INDEX_TYPE_VIEW:
|
|
229
|
+
return "view";
|
|
230
|
+
case v1::INDEX_TYPE_GSI:
|
|
231
|
+
return "gsi";
|
|
232
|
+
default:
|
|
233
|
+
return "unknown";
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
[[nodiscard]] inline auto
|
|
238
|
+
index_state_to_string(v1::IndexState state) -> std::string
|
|
239
|
+
{
|
|
240
|
+
switch (state) {
|
|
241
|
+
case v1::INDEX_STATE_DEFERRED:
|
|
242
|
+
return "deferred";
|
|
243
|
+
case v1::INDEX_STATE_BUILDING:
|
|
244
|
+
return "building";
|
|
245
|
+
case v1::INDEX_STATE_PENDING:
|
|
246
|
+
return "pending";
|
|
247
|
+
case v1::INDEX_STATE_ONLINE:
|
|
248
|
+
return "online";
|
|
249
|
+
case v1::INDEX_STATE_OFFLINE:
|
|
250
|
+
return "offline";
|
|
251
|
+
case v1::INDEX_STATE_ABRIDGED:
|
|
252
|
+
return "abridged";
|
|
253
|
+
case v1::INDEX_STATE_SCHEDULED:
|
|
254
|
+
return "scheduled";
|
|
255
|
+
default:
|
|
256
|
+
return "unknown";
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
[[nodiscard]] inline auto
|
|
261
|
+
decode_index(const v1::GetAllIndexesResponse_Index& proto) -> couchbase::management::query_index
|
|
262
|
+
{
|
|
263
|
+
couchbase::management::query_index index;
|
|
264
|
+
index.is_primary = proto.is_primary();
|
|
265
|
+
index.name = proto.name();
|
|
266
|
+
index.type = index_type_to_string(proto.type());
|
|
267
|
+
index.state = index_state_to_string(proto.state());
|
|
268
|
+
index.bucket_name = proto.bucket_name();
|
|
269
|
+
if (!proto.scope_name().empty()) {
|
|
270
|
+
index.scope_name = proto.scope_name();
|
|
271
|
+
}
|
|
272
|
+
if (!proto.collection_name().empty()) {
|
|
273
|
+
index.collection_name = proto.collection_name();
|
|
274
|
+
}
|
|
275
|
+
for (const auto& field : proto.fields()) {
|
|
276
|
+
index.index_key.push_back(field);
|
|
277
|
+
}
|
|
278
|
+
// Presence, not emptiness: condition and partition are `optional string`, so an index that has
|
|
279
|
+
// no WHERE clause is a different answer from one whose clause the server reports as empty.
|
|
280
|
+
// scope_name and collection_name above carry no presence, so there an empty name is the only
|
|
281
|
+
// form "not collection-qualified" can arrive in.
|
|
282
|
+
if (proto.has_condition()) {
|
|
283
|
+
index.condition = proto.condition();
|
|
284
|
+
}
|
|
285
|
+
if (proto.has_partition()) {
|
|
286
|
+
index.partition = proto.partition();
|
|
287
|
+
}
|
|
288
|
+
return index;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
} // namespace couchbase::core::protostellar::query_index_admin
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
// The one place the generated couchbase.query.v1 headers are included. Include this instead of
|
|
21
|
+
// <couchbase/query/v1/query.pb.h> or <couchbase/query/v1/query.grpc.pb.h>.
|
|
22
|
+
//
|
|
23
|
+
// protobuf emits a class-scoped alias for every enum value ("static constexpr Status STATUS_TIMEOUT
|
|
24
|
+
// = ..."), and the Windows SDK spells much of that same STATUS_* namespace as object-like macros:
|
|
25
|
+
// <winnt.h> defines STATUS_TIMEOUT as ((DWORD)0x00000102L), and asio and gRPC reach <winnt.h>
|
|
26
|
+
// transitively. On MSVC the alias then expands into a parenthesised constant and the generated
|
|
27
|
+
// header does not parse. No other compiler is affected, so the Linux and macOS legs cannot catch
|
|
28
|
+
// it.
|
|
29
|
+
//
|
|
30
|
+
// The whole QueryResponse.MetaData.Status family is suppressed, not just the one name that collides
|
|
31
|
+
// today: <ntstatus.h> covers far more of the STATUS_* namespace than <winnt.h> does (STATUS_SUCCESS
|
|
32
|
+
// among it) and any dependency may start pulling it in. push_macro/pop_macro keeps the suppression
|
|
33
|
+
// scoped to the includes below, so a translation unit that includes this header does not silently
|
|
34
|
+
// lose a macro it uses elsewhere -- which a bare #undef in a header would do. Pushing and popping a
|
|
35
|
+
// macro that is not defined is a no-op, so this needs no _MSC_VER guard.
|
|
36
|
+
//
|
|
37
|
+
// When the schema pin in cmake/Protostellar.cmake moves, bin/check-proto-macro-collisions reports
|
|
38
|
+
// generated aliases that collide with a Windows macro, including families other than this one.
|
|
39
|
+
|
|
40
|
+
#pragma push_macro("STATUS_ABORTED")
|
|
41
|
+
#pragma push_macro("STATUS_CLOSED")
|
|
42
|
+
#pragma push_macro("STATUS_COMPLETED")
|
|
43
|
+
#pragma push_macro("STATUS_ERRORS")
|
|
44
|
+
#pragma push_macro("STATUS_FATAL")
|
|
45
|
+
#pragma push_macro("STATUS_RUNNING")
|
|
46
|
+
#pragma push_macro("STATUS_STOPPED")
|
|
47
|
+
#pragma push_macro("STATUS_SUCCESS")
|
|
48
|
+
#pragma push_macro("STATUS_TIMEOUT")
|
|
49
|
+
#pragma push_macro("STATUS_UNKNOWN")
|
|
50
|
+
#undef STATUS_ABORTED
|
|
51
|
+
#undef STATUS_CLOSED
|
|
52
|
+
#undef STATUS_COMPLETED
|
|
53
|
+
#undef STATUS_ERRORS
|
|
54
|
+
#undef STATUS_FATAL
|
|
55
|
+
#undef STATUS_RUNNING
|
|
56
|
+
#undef STATUS_STOPPED
|
|
57
|
+
#undef STATUS_SUCCESS
|
|
58
|
+
#undef STATUS_TIMEOUT
|
|
59
|
+
#undef STATUS_UNKNOWN
|
|
60
|
+
|
|
61
|
+
#include <couchbase/query/v1/query.grpc.pb.h>
|
|
62
|
+
#include <couchbase/query/v1/query.pb.h>
|
|
63
|
+
|
|
64
|
+
#pragma pop_macro("STATUS_UNKNOWN")
|
|
65
|
+
#pragma pop_macro("STATUS_TIMEOUT")
|
|
66
|
+
#pragma pop_macro("STATUS_SUCCESS")
|
|
67
|
+
#pragma pop_macro("STATUS_STOPPED")
|
|
68
|
+
#pragma pop_macro("STATUS_RUNNING")
|
|
69
|
+
#pragma pop_macro("STATUS_FATAL")
|
|
70
|
+
#pragma pop_macro("STATUS_ERRORS")
|
|
71
|
+
#pragma pop_macro("STATUS_COMPLETED")
|
|
72
|
+
#pragma pop_macro("STATUS_CLOSED")
|
|
73
|
+
#pragma pop_macro("STATUS_ABORTED")
|