From ebe66a8d4336108d172f4d09712ce21c995226a9 Mon Sep 17 00:00:00 2001 From: Sergey Avseyev Date: Mon, 22 Jul 2024 18:05:00 -0700 Subject: [PATCH] reformat sources according to C++SDK style --- src/php_couchbase.cxx | 5483 ++++++------ src/wrapper/common.cxx | 1047 +-- src/wrapper/common.hxx | 6 +- src/wrapper/connection_handle.cxx | 8139 +++++++++--------- src/wrapper/connection_handle.hxx | 907 +- src/wrapper/conversion_utilities.cxx | 1802 ++-- src/wrapper/conversion_utilities.hxx | 456 +- src/wrapper/core_error_info.hxx | 196 +- src/wrapper/logger.cxx | 204 +- src/wrapper/passthrough_transcoder.hxx | 18 +- src/wrapper/persistent_connections_cache.cxx | 328 +- src/wrapper/persistent_connections_cache.hxx | 4 +- src/wrapper/php_7_api_layer.hxx | 44 +- src/wrapper/scan_result_resource.cxx | 422 +- src/wrapper/scan_result_resource.hxx | 17 +- src/wrapper/transaction_context_resource.cxx | 1432 +-- src/wrapper/transaction_context_resource.hxx | 77 +- src/wrapper/transactions_resource.cxx | 443 +- src/wrapper/transactions_resource.hxx | 19 +- src/wrapper/version.cxx | 34 +- src/wrapper/wrapper.hxx | 3 +- 21 files changed, 10981 insertions(+), 10100 deletions(-) diff --git a/src/php_couchbase.cxx b/src/php_couchbase.cxx index 36dc770a..d0f2a9ee 100644 --- a/src/php_couchbase.cxx +++ b/src/php_couchbase.cxx @@ -33,31 +33,31 @@ ZEND_RSRC_DTOR_FUNC(couchbase_destroy_persistent_connection) { - couchbase::php::destroy_persistent_connection(res); + couchbase::php::destroy_persistent_connection(res); } ZEND_RSRC_DTOR_FUNC(couchbase_destroy_transactions) { - couchbase::php::destroy_transactions_resource(res); + couchbase::php::destroy_transactions_resource(res); } ZEND_RSRC_DTOR_FUNC(couchbase_destroy_transaction_context) { - couchbase::php::destroy_transaction_context_resource(res); + couchbase::php::destroy_transaction_context_resource(res); } ZEND_RSRC_DTOR_FUNC(couchbase_destroy_core_scan_result) { - couchbase::php::destroy_scan_result_resource(res); + couchbase::php::destroy_scan_result_resource(res); } PHP_RSHUTDOWN_FUNCTION(couchbase) { - /* Check persistent connections and do the necessary actions if needed. */ - zend_hash_apply(&EG(persistent_list), couchbase::php::check_persistent_connection); + /* Check persistent connections and do the necessary actions if needed. */ + zend_hash_apply(&EG(persistent_list), couchbase::php::check_persistent_connection); - couchbase::php::flush_logger(); - return SUCCESS; + couchbase::php::flush_logger(); + return SUCCESS; } ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(ai_Exception_getContext, IS_ARRAY, 0) @@ -72,56 +72,61 @@ ZEND_END_ARG_INFO() PHP_METHOD(CouchbaseException, getContext) { - if (zend_parse_parameters_none_throw() == FAILURE) { - return; - } - - zval *prop, rv; - prop = couchbase_read_property(couchbase::php::couchbase_exception(), getThis(), "context", 0, &rv); - ZVAL_COPY_DEREF(return_value, prop); + if (zend_parse_parameters_none_throw() == FAILURE) { + return; + } + + zval *prop, rv; + prop = + couchbase_read_property(couchbase::php::couchbase_exception(), getThis(), "context", 0, &rv); + ZVAL_COPY_DEREF(return_value, prop); } PHP_METHOD(CouchbaseException, __construct) { - zend_string* message = NULL; - zend_long code = 0; - zval tmp, *object, *previous = NULL, *context = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|SlO!a", &message, &code, &previous, zend_ce_throwable, &context) == FAILURE) { - RETURN_THROWS(); - } - - object = ZEND_THIS; - - if (message) { - ZVAL_STR_COPY(&tmp, message); - zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp); - zval_ptr_dtor(&tmp); - } - - if (code) { - ZVAL_LONG(&tmp, code); - zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_CODE), &tmp); - } - - if (previous) { - zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_PREVIOUS), previous); - } - - if (context) { - zend_string* property_context_name = zend_string_init(ZEND_STRL("context"), 1); - zend_update_property_ex(couchbase::php::couchbase_exception(), Z_OBJ_P(object), property_context_name, context); - zend_string_release(property_context_name); - } + zend_string* message = NULL; + zend_long code = 0; + zval tmp, *object, *previous = NULL, *context = NULL; + + if (zend_parse_parameters( + ZEND_NUM_ARGS(), "|SlO!a", &message, &code, &previous, zend_ce_throwable, &context) == + FAILURE) { + RETURN_THROWS(); + } + + object = ZEND_THIS; + + if (message) { + ZVAL_STR_COPY(&tmp, message); + zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp); + zval_ptr_dtor(&tmp); + } + + if (code) { + ZVAL_LONG(&tmp, code); + zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_CODE), &tmp); + } + + if (previous) { + zend_update_property_ex( + zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_PREVIOUS), previous); + } + + if (context) { + zend_string* property_context_name = zend_string_init(ZEND_STRL("context"), 1); + zend_update_property_ex( + couchbase::php::couchbase_exception(), Z_OBJ_P(object), property_context_name, context); + zend_string_release(property_context_name); + } } PHP_RINIT_FUNCTION(couchbase) { - if (!COUCHBASE_G(initialized)) { - couchbase::php::initialize_logger(); - COUCHBASE_G(initialized) = 1; - } - return SUCCESS; + if (!COUCHBASE_G(initialized)) { + couchbase::php::initialize_logger(); + COUCHBASE_G(initialized) = 1; + } + return SUCCESS; } // clang-format off @@ -145,3098 +150,3196 @@ PHP_INI_END() PHP_MINIT_FUNCTION(couchbase) { - (void)type; - REGISTER_INI_ENTRIES(); - - couchbase::php::initialize_exceptions(exception_functions); - - couchbase::php::set_persistent_connection_destructor_id(zend_register_list_destructors_ex( - nullptr, couchbase_destroy_persistent_connection, "couchbase_persistent_connection", module_number)); - couchbase::php::set_transactions_destructor_id( - zend_register_list_destructors_ex(couchbase_destroy_transactions, nullptr, "couchbase_transactions", module_number)); - couchbase::php::set_transaction_context_destructor_id( - zend_register_list_destructors_ex(couchbase_destroy_transaction_context, nullptr, "couchbase_transaction_context", module_number)); - couchbase::php::set_scan_result_destructor_id( - zend_register_list_destructors_ex(couchbase_destroy_core_scan_result, nullptr, "couchbase_scan_result", module_number)); - - return SUCCESS; + (void)type; + REGISTER_INI_ENTRIES(); + + couchbase::php::initialize_exceptions(exception_functions); + + couchbase::php::set_persistent_connection_destructor_id( + zend_register_list_destructors_ex(nullptr, + couchbase_destroy_persistent_connection, + "couchbase_persistent_connection", + module_number)); + couchbase::php::set_transactions_destructor_id(zend_register_list_destructors_ex( + couchbase_destroy_transactions, nullptr, "couchbase_transactions", module_number)); + couchbase::php::set_transaction_context_destructor_id( + zend_register_list_destructors_ex(couchbase_destroy_transaction_context, + nullptr, + "couchbase_transaction_context", + module_number)); + couchbase::php::set_scan_result_destructor_id(zend_register_list_destructors_ex( + couchbase_destroy_core_scan_result, nullptr, "couchbase_scan_result", module_number)); + + return SUCCESS; } struct logger_flusher { - logger_flusher() = default; - ~logger_flusher() - { - couchbase::php::flush_logger(); - } + logger_flusher() = default; + ~logger_flusher() + { + couchbase::php::flush_logger(); + } }; static void couchbase_throw_exception(const couchbase::php::core_error_info& error_info) { - if (!error_info.ec) { - return; // success - } + if (!error_info.ec) { + return; // success + } - zval ex; - couchbase::php::create_exception(&ex, error_info); - zend_throw_exception_object(&ex); + zval ex; + couchbase::php::create_exception(&ex, error_info); + zend_throw_exception_object(&ex); } PHP_MSHUTDOWN_FUNCTION(couchbase) { - couchbase::php::shutdown_logger(); + couchbase::php::shutdown_logger(); - (void)type; - (void)module_number; - return SUCCESS; + (void)type; + (void)module_number; + return SUCCESS; } PHP_FUNCTION(version) { - if (zend_parse_parameters_none_throw() == FAILURE) { - RETURN_NULL(); - } - couchbase::php::core_version(return_value); + if (zend_parse_parameters_none_throw() == FAILURE) { + RETURN_NULL(); + } + couchbase::php::core_version(return_value); } PHP_FUNCTION(notifyFork) { - zend_string* fork_event = nullptr; + zend_string* fork_event = nullptr; - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(fork_event) - ZEND_PARSE_PARAMETERS_END(); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(fork_event) + ZEND_PARSE_PARAMETERS_END(); - if (auto e = couchbase::php::notify_fork(fork_event); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + if (auto e = couchbase::php::notify_fork(fork_event); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } - RETURN_NULL(); + RETURN_NULL(); } PHP_FUNCTION(createConnection) { - zend_string* connection_hash = nullptr; - zend_string* connection_string = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_STR(connection_hash) - Z_PARAM_STR(connection_string) - Z_PARAM_ARRAY(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto [resource, e] = couchbase::php::create_persistent_connection(connection_hash, connection_string, options); - if (e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - - RETURN_RES(resource); + zend_string* connection_hash = nullptr; + zend_string* connection_string = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_STR(connection_hash) + Z_PARAM_STR(connection_string) + Z_PARAM_ARRAY(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto [resource, e] = + couchbase::php::create_persistent_connection(connection_hash, connection_string, options); + if (e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + + RETURN_RES(resource); } static inline couchbase::php::connection_handle* fetch_couchbase_connection_from_resource(zval* resource) { - return static_cast( - zend_fetch_resource(Z_RES_P(resource), "couchbase_persistent_connection", couchbase::php::get_persistent_connection_destructor_id())); + return static_cast( + zend_fetch_resource(Z_RES_P(resource), + "couchbase_persistent_connection", + couchbase::php::get_persistent_connection_destructor_id())); } PHP_FUNCTION(clusterVersion) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - auto version = handle->cluster_version(name); - if (version.empty()) { - RETURN_NULL(); - } - RETURN_STRINGL(version.data(), version.size()); + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + auto version = handle->cluster_version(name); + if (version.empty()) { + RETURN_NULL(); + } + RETURN_STRINGL(version.data(), version.size()); } PHP_FUNCTION(replicasConfiguredForBucket) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (handle->replicas_configured_for_bucket(name)) { - RETURN_TRUE; - } - RETURN_FALSE; + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (handle->replicas_configured_for_bucket(name)) { + RETURN_TRUE; + } + RETURN_FALSE; } PHP_FUNCTION(openBucket) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->bucket_open(name); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->bucket_open(name); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(closeBucket) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->bucket_close(name); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->bucket_close(name); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentUpsert) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_string* value = nullptr; - zend_long flags = 0; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(7, 8) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_STR(value) - Z_PARAM_LONG(flags) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_upsert(return_value, bucket, scope, collection, id, value, flags, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_string* value = nullptr; + zend_long flags = 0; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(7, 8) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_STR(value) + Z_PARAM_LONG(flags) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_upsert(return_value, bucket, scope, collection, id, value, flags, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentInsert) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_string* value = nullptr; - zend_long flags = 0; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(7, 8) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_STR(value) - Z_PARAM_LONG(flags) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_insert(return_value, bucket, scope, collection, id, value, flags, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_string* value = nullptr; + zend_long flags = 0; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(7, 8) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_STR(value) + Z_PARAM_LONG(flags) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_insert(return_value, bucket, scope, collection, id, value, flags, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentReplace) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_string* value = nullptr; - zend_long flags = 0; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(7, 8) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_STR(value) - Z_PARAM_LONG(flags) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_replace(return_value, bucket, scope, collection, id, value, flags, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_string* value = nullptr; + zend_long flags = 0; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(7, 8) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_STR(value) + Z_PARAM_LONG(flags) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_replace( + return_value, bucket, scope, collection, id, value, flags, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentAppend) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_string* value = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_STR(value) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_append(return_value, bucket, scope, collection, id, value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_string* value = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_STR(value) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_append(return_value, bucket, scope, collection, id, value, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentPrepend) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_string* value = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_STR(value) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_prepend(return_value, bucket, scope, collection, id, value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_string* value = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_STR(value) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_prepend(return_value, bucket, scope, collection, id, value, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentIncrement) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_increment(return_value, bucket, scope, collection, id, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_increment(return_value, bucket, scope, collection, id, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentDecrement) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_decrement(return_value, bucket, scope, collection, id, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_decrement(return_value, bucket, scope, collection, id, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentGet) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_get(return_value, bucket, scope, collection, id, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_get(return_value, bucket, scope, collection, id, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentGetAnyReplica) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_get_any_replica(return_value, bucket, scope, collection, id, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_get_any_replica(return_value, bucket, scope, collection, id, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentGetAllReplicas) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_get_all_replicas(return_value, bucket, scope, collection, id, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_get_all_replicas(return_value, bucket, scope, collection, id, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentGetAndLock) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_long lock_time; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_LONG(lock_time) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_get_and_lock(return_value, bucket, scope, collection, id, lock_time, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_long lock_time; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_LONG(lock_time) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_get_and_lock( + return_value, bucket, scope, collection, id, lock_time, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentUnlock) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_string* cas = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_STR(cas) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_unlock(return_value, bucket, scope, collection, id, cas, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_string* cas = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_STR(cas) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_unlock(return_value, bucket, scope, collection, id, cas, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentRemove) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_remove(return_value, bucket, scope, collection, id, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_remove(return_value, bucket, scope, collection, id, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentGetAndTouch) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_long expiry; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_LONG(expiry) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_get_and_touch(return_value, bucket, scope, collection, id, expiry, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_long expiry; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_LONG(expiry) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_get_and_touch( + return_value, bucket, scope, collection, id, expiry, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentTouch) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_long expiry; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_LONG(expiry) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_touch(return_value, bucket, scope, collection, id, expiry, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_long expiry; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_LONG(expiry) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_touch(return_value, bucket, scope, collection, id, expiry, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentExists) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_exists(return_value, bucket, scope, collection, id, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_exists(return_value, bucket, scope, collection, id, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentMutateIn) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* specs = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_ARRAY(specs) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_mutate_in(return_value, bucket, scope, collection, id, specs, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* specs = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_ARRAY(specs) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_mutate_in(return_value, bucket, scope, collection, id, specs, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentLookupIn) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* specs = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_ARRAY(specs) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_lookup_in(return_value, bucket, scope, collection, id, specs, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* specs = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_ARRAY(specs) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_lookup_in(return_value, bucket, scope, collection, id, specs, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentLookupInAnyReplica) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* specs = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_ARRAY(specs) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_lookup_in_any_replica(return_value, bucket, scope, collection, id, specs, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* specs = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_ARRAY(specs) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_lookup_in_any_replica( + return_value, bucket, scope, collection, id, specs, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentLookupInAllReplicas) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zval* specs = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_ARRAY(specs) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_lookup_in_all_replicas(return_value, bucket, scope, collection, id, specs, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zval* specs = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_ARRAY(specs) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_lookup_in_all_replicas( + return_value, bucket, scope, collection, id, specs, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } static inline couchbase::php::scan_result_resource* fetch_couchbase_scan_result_from_resource(zval* resource) { - return static_cast( - zend_fetch_resource(Z_RES_P(resource), "couchbase_scan_result", couchbase::php::get_scan_result_destructor_id())); + return static_cast(zend_fetch_resource( + Z_RES_P(resource), "couchbase_scan_result", couchbase::php::get_scan_result_destructor_id())); } PHP_FUNCTION(createDocumentScanResult) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zval* scan_type = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_ARRAY(scan_type) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - auto [resource, e] = couchbase::php::create_scan_result_resource(handle, bucket, scope, collection, scan_type, options); - if (e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_RES(resource); + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zval* scan_type = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_ARRAY(scan_type) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + auto [resource, e] = couchbase::php::create_scan_result_resource( + handle, bucket, scope, collection, scan_type, options); + if (e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_RES(resource); } PHP_FUNCTION(documentScanNextItem) { - zval* scan_result = nullptr; + zval* scan_result = nullptr; - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(scan_result) - ZEND_PARSE_PARAMETERS_END(); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(scan_result) + ZEND_PARSE_PARAMETERS_END(); - logger_flusher guard; + logger_flusher guard; - auto* scan_res = fetch_couchbase_scan_result_from_resource(scan_result); - if (scan_res == nullptr) { - RETURN_THROWS(); - } - if (auto e = scan_res->next_item(return_value); e.ec) { + auto* scan_res = fetch_couchbase_scan_result_from_resource(scan_result); + if (scan_res == nullptr) { + RETURN_THROWS(); + } + if (auto e = scan_res->next_item(return_value); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentGetMulti) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zval* ids = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_ARRAY(ids) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_get_multi(return_value, bucket, scope, collection, ids, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zval* ids = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_ARRAY(ids) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->document_get_multi(return_value, bucket, scope, collection, ids, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentRemoveMulti) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zval* entries = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_ARRAY(entries) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_remove_multi(return_value, bucket, scope, collection, entries, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zval* entries = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_ARRAY(entries) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_remove_multi(return_value, bucket, scope, collection, entries, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(documentUpsertMulti) { - zval* connection = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zval* entries = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_ARRAY(entries) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->document_upsert_multi(return_value, bucket, scope, collection, entries, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zval* entries = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_ARRAY(entries) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->document_upsert_multi(return_value, bucket, scope, collection, entries, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(query) { - zval* connection = nullptr; - zend_string* statement = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(statement) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->query(return_value, statement, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* statement = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(statement) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->query(return_value, statement, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(analyticsQuery) { - zval* connection = nullptr; - zend_string* statement = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(statement) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->analytics_query(return_value, statement, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* statement = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(statement) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->analytics_query(return_value, statement, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(viewQuery) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* design_document_name = nullptr; - zend_string* view_name = nullptr; - zend_long name_space = 0; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(design_document_name) - Z_PARAM_STR(view_name) - Z_PARAM_LONG(name_space) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->view_query(return_value, bucket_name, design_document_name, view_name, name_space, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* design_document_name = nullptr; + zend_string* view_name = nullptr; + zend_long name_space = 0; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(design_document_name) + Z_PARAM_STR(view_name) + Z_PARAM_LONG(name_space) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->view_query( + return_value, bucket_name, design_document_name, view_name, name_space, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchQuery) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zend_string* query = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_STR(query) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->search_query(return_value, index_name, query, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zend_string* query = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_STR(query) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->search_query(return_value, index_name, query, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(vectorSearch) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zend_string* query = nullptr; - zend_string* vector_search = nullptr; - zval* options = nullptr; - zval* vector_options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_STR(query) - Z_PARAM_STR(vector_search) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - Z_PARAM_ARRAY_OR_NULL(vector_options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->search(return_value, index_name, query, options, vector_search, vector_options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zend_string* query = nullptr; + zend_string* vector_search = nullptr; + zval* options = nullptr; + zval* vector_options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_STR(query) + Z_PARAM_STR(vector_search) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + Z_PARAM_ARRAY_OR_NULL(vector_options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = + handle->search(return_value, index_name, query, options, vector_search, vector_options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(ping) { - zval* connection = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->ping(return_value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->ping(return_value, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(diagnostics) { - zval* connection = nullptr; - zend_string* reportId = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(reportId) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->diagnostics(return_value, reportId, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* reportId = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(reportId) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->diagnostics(return_value, reportId, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexGet) { - zval* connection = nullptr; - zend_string* index_name; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->search_index_get(return_value, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->search_index_get(return_value, index_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexGetAll) { - zval* connection = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->search_index_get_all(return_value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->search_index_get_all(return_value, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexUpsert) { - zval* connection = nullptr; - zval* index = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_ARRAY(index) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_upsert(return_value, index, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* index = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_ARRAY(index) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_upsert(return_value, index, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexDrop) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_drop(return_value, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_drop(return_value, index_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexGetDocumentsCount) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_get_documents_count(return_value, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_get_documents_count(return_value, index_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexIngestPause) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_control_ingest(return_value, index_name, true, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_control_ingest(return_value, index_name, true, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexIngestResume) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_control_ingest(return_value, index_name, false, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_control_ingest(return_value, index_name, false, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexQueryingAllow) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_control_query(return_value, index_name, true, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_control_query(return_value, index_name, true, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexQueryingDisallow) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_control_query(return_value, index_name, false, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_control_query(return_value, index_name, false, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexPlanFreeze) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_control_plan_freeze(return_value, index_name, true, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_control_plan_freeze(return_value, index_name, true, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexPlanUnfreeze) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_control_plan_freeze(return_value, index_name, false, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_control_plan_freeze(return_value, index_name, false, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(searchIndexDocumentAnalyze) { - zval* connection = nullptr; - zend_string* index_name = nullptr; - zend_string* document = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(index_name) - Z_PARAM_STR(document) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->search_index_analyze_document(return_value, index_name, document, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* index_name = nullptr; + zend_string* document = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(index_name) + Z_PARAM_STR(document) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->search_index_analyze_document(return_value, index_name, document, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexGet) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->scope_search_index_get(return_value, bucket_name, scope_name, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = + handle->scope_search_index_get(return_value, bucket_name, scope_name, index_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexGetAll) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->scope_search_index_get_all(return_value, bucket_name, scope_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->scope_search_index_get_all(return_value, bucket_name, scope_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexUpsert) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zval* index = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_ARRAY(index) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_upsert(return_value, bucket_name, scope_name, index, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zval* index = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_ARRAY(index) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->scope_search_index_upsert(return_value, bucket_name, scope_name, index, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexDrop) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_drop(return_value, bucket_name, scope_name, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->scope_search_index_drop(return_value, bucket_name, scope_name, index_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexGetDocumentsCount) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_get_documents_count(return_value, bucket_name, scope_name, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_get_documents_count( + return_value, bucket_name, scope_name, index_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexIngestPause) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_control_ingest(return_value, bucket_name, scope_name, index_name, true, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_control_ingest( + return_value, bucket_name, scope_name, index_name, true, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexIngestResume) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_control_ingest(return_value, bucket_name, scope_name, index_name, false, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_control_ingest( + return_value, bucket_name, scope_name, index_name, false, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexQueryingAllow) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_control_query(return_value, bucket_name, scope_name, index_name, true, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_control_query( + return_value, bucket_name, scope_name, index_name, true, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexQueryingDisallow) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_control_query(return_value, bucket_name, scope_name, index_name, false, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_control_query( + return_value, bucket_name, scope_name, index_name, false, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexPlanFreeze) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_control_plan_freeze(return_value, bucket_name, scope_name, index_name, true, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_control_plan_freeze( + return_value, bucket_name, scope_name, index_name, true, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexPlanUnfreeze) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_control_plan_freeze(return_value, bucket_name, scope_name, index_name, false, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_control_plan_freeze( + return_value, bucket_name, scope_name, index_name, false, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeSearchIndexDocumentAnalyze) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* index_name = nullptr; - zend_string* document = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(index_name) - Z_PARAM_STR(document) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options); - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_search_index_analyze_document(return_value, bucket_name, scope_name, index_name, document, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* index_name = nullptr; + zend_string* document = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(index_name) + Z_PARAM_STR(document) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options); + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_search_index_analyze_document( + return_value, bucket_name, scope_name, index_name, document, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(viewIndexUpsert) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zval* index = nullptr; - zend_long name_space = 0; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_ARRAY(index) - Z_PARAM_LONG(name_space) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->view_index_upsert(return_value, bucket_name, index, name_space, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zval* index = nullptr; + zend_long name_space = 0; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_ARRAY(index) + Z_PARAM_LONG(name_space) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->view_index_upsert(return_value, bucket_name, index, name_space, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(bucketCreate) { - zval* connection = nullptr; - zval* bucket_settings = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_ARRAY(bucket_settings) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->bucket_create(return_value, bucket_settings, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* bucket_settings = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_ARRAY(bucket_settings) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->bucket_create(return_value, bucket_settings, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(bucketGet) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->bucket_get(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->bucket_get(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(bucketGetAll) { - zval* connection = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->bucket_get_all(return_value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->bucket_get_all(return_value, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(bucketDrop) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->bucket_drop(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->bucket_drop(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(bucketFlush) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->bucket_flush(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->bucket_flush(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(bucketUpdate) { - zval* connection = nullptr; - zval* bucket_settings = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_ARRAY(bucket_settings) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->bucket_update(return_value, bucket_settings, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* bucket_settings = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_ARRAY(bucket_settings) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->bucket_update(return_value, bucket_settings, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeGetAll) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_get_all(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_get_all(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeCreate) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_create(return_value, bucket_name, scope_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_create(return_value, bucket_name, scope_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(scopeDrop) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->scope_drop(return_value, bucket_name, scope_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->scope_drop(return_value, bucket_name, scope_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(collectionCreate) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zval* settings = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(settings) - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->collection_create(return_value, bucket_name, scope_name, collection_name, settings, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zval* settings = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(settings) + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->collection_create( + return_value, bucket_name, scope_name, collection_name, settings, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(collectionDrop) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->collection_drop(return_value, bucket_name, scope_name, collection_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = + handle->collection_drop(return_value, bucket_name, scope_name, collection_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(collectionUpdate) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zval* settings = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_ARRAY(settings) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - - if (auto e = handle->collection_update(return_value, bucket_name, scope_name, collection_name, settings, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zval* settings = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_ARRAY(settings) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + + if (auto e = handle->collection_update( + return_value, bucket_name, scope_name, collection_name, settings, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } static inline couchbase::php::transactions_resource* fetch_couchbase_transactions_from_resource(zval* resource) { - return static_cast( - zend_fetch_resource(Z_RES_P(resource), "couchbase_transactions", couchbase::php::get_transactions_destructor_id())); + return static_cast(zend_fetch_resource( + Z_RES_P(resource), "couchbase_transactions", couchbase::php::get_transactions_destructor_id())); } PHP_FUNCTION(createTransactions) { - zval* connection = nullptr; - zval* configuration = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(configuration) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - auto [resource, e] = couchbase::php::create_transactions_resource(handle, configuration); - if (e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_RES(resource); + zval* connection = nullptr; + zval* configuration = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(configuration) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + auto [resource, e] = couchbase::php::create_transactions_resource(handle, configuration); + if (e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_RES(resource); } static inline couchbase::php::transaction_context_resource* fetch_couchbase_transaction_context_from_resource(zval* resource) { - return static_cast( - zend_fetch_resource(Z_RES_P(resource), "couchbase_transaction_context", couchbase::php::get_transaction_context_destructor_id())); + return static_cast( + zend_fetch_resource(Z_RES_P(resource), + "couchbase_transaction_context", + couchbase::php::get_transaction_context_destructor_id())); } PHP_FUNCTION(createTransactionContext) { - zval* transactions = nullptr; - zval* configuration = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(transactions) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(configuration) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_transactions_from_resource(transactions); - if (handle == nullptr) { - RETURN_THROWS(); - } - auto [resource, e] = couchbase::php::create_transaction_context_resource(handle, configuration); - if (e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_RES(resource); + zval* transactions = nullptr; + zval* configuration = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(transactions) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(configuration) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_transactions_from_resource(transactions); + if (handle == nullptr) { + RETURN_THROWS(); + } + auto [resource, e] = couchbase::php::create_transaction_context_resource(handle, configuration); + if (e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_RES(resource); } PHP_FUNCTION(transactionNewAttempt) { - zval* transaction = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(transaction) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->new_attempt(); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* transaction = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(transaction) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->new_attempt(); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(transactionCommit) { - zval* transaction = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(transaction) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->commit(return_value); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* transaction = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(transaction) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->commit(return_value); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(transactionRollback) { - zval* transaction = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(transaction) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->rollback(); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* transaction = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(transaction) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->rollback(); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(transactionGet) { - zval* transaction = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 5) - Z_PARAM_RESOURCE(transaction) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->get(return_value, bucket, scope, collection, id); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* transaction = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 5) + Z_PARAM_RESOURCE(transaction) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->get(return_value, bucket, scope, collection, id); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(transactionInsert) { - zval* transaction = nullptr; - zend_string* bucket = nullptr; - zend_string* scope = nullptr; - zend_string* collection = nullptr; - zend_string* id = nullptr; - zend_string* value = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 6) - Z_PARAM_RESOURCE(transaction) - Z_PARAM_STR(bucket) - Z_PARAM_STR(scope) - Z_PARAM_STR(collection) - Z_PARAM_STR(id) - Z_PARAM_STR(value) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->insert(return_value, bucket, scope, collection, id, value); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* transaction = nullptr; + zend_string* bucket = nullptr; + zend_string* scope = nullptr; + zend_string* collection = nullptr; + zend_string* id = nullptr; + zend_string* value = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 6) + Z_PARAM_RESOURCE(transaction) + Z_PARAM_STR(bucket) + Z_PARAM_STR(scope) + Z_PARAM_STR(collection) + Z_PARAM_STR(id) + Z_PARAM_STR(value) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->insert(return_value, bucket, scope, collection, id, value); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(transactionReplace) { - zval* transaction = nullptr; - zval* document = nullptr; - zend_string* value = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_RESOURCE(transaction) - Z_PARAM_ARRAY(document) - Z_PARAM_STR(value) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->replace(return_value, document, value); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* transaction = nullptr; + zval* document = nullptr; + zend_string* value = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_RESOURCE(transaction) + Z_PARAM_ARRAY(document) + Z_PARAM_STR(value) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->replace(return_value, document, value); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(transactionRemove) { - zval* transaction = nullptr; - zval* document = nullptr; - zend_string* value = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(transaction) - Z_PARAM_ARRAY(document) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->remove(document); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* transaction = nullptr; + zval* document = nullptr; + zend_string* value = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(transaction) + Z_PARAM_ARRAY(document) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->remove(document); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(transactionQuery) { - zval* transaction = nullptr; - zend_string* statement = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(transaction) - Z_PARAM_STR(statement) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* context = fetch_couchbase_transaction_context_from_resource(transaction); - if (context == nullptr) { - RETURN_THROWS(); - } - if (auto e = context->query(return_value, statement, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* transaction = nullptr; + zend_string* statement = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(transaction) + Z_PARAM_STR(statement) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* context = fetch_couchbase_transaction_context_from_resource(transaction); + if (context == nullptr) { + RETURN_THROWS(); + } + if (auto e = context->query(return_value, statement, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(userUpsert) { - zval* connection = nullptr; - zval* user = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_ARRAY(user) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->user_upsert(return_value, user, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* user = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_ARRAY(user) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->user_upsert(return_value, user, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(userGet) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->user_get(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->user_get(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(userGetAll) { - zval* connection = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->user_get_all(return_value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->user_get_all(return_value, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(userDrop) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->user_drop(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->user_drop(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(passwordChange) { - zval* connection = nullptr; - zend_string* new_password = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(new_password) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->change_password(return_value, new_password, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* new_password = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(new_password) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->change_password(return_value, new_password, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(groupUpsert) { - zval* connection = nullptr; - zval* group = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_ARRAY(group) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->group_upsert(return_value, group, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* group = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_ARRAY(group) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->group_upsert(return_value, group, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(groupGet) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->group_get(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->group_get(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(groupGetAll) { - zval* connection = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->group_get_all(return_value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->group_get_all(return_value, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(groupDrop) { - zval* connection = nullptr; - zend_string* name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->group_drop(return_value, name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->group_drop(return_value, name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(roleGetAll) { - zval* connection = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(connection) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->role_get_all(return_value, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(connection) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->role_get_all(return_value, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(queryIndexGetAll) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->query_index_get_all(return_value, bucket_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->query_index_get_all(return_value, bucket_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(queryIndexCreate) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* index_name = nullptr; - zval* keys = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(index_name) - Z_PARAM_ARRAY(keys) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->query_index_create(bucket_name, index_name, keys, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* index_name = nullptr; + zval* keys = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(index_name) + Z_PARAM_ARRAY(keys) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->query_index_create(bucket_name, index_name, keys, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(queryIndexCreatePrimary) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->query_index_create_primary(bucket_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->query_index_create_primary(bucket_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(queryIndexDrop) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->query_index_drop(bucket_name, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->query_index_drop(bucket_name, index_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(queryIndexDropPrimary) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->query_index_drop_primary(bucket_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->query_index_drop_primary(bucket_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(queryIndexBuildDeferred) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->query_index_build_deferred(return_value, bucket_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->query_index_build_deferred(return_value, bucket_name, options); e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(collectionQueryIndexGetAll) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->collection_query_index_get_all(return_value, bucket_name, scope_name, collection_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->collection_query_index_get_all( + return_value, bucket_name, scope_name, collection_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } PHP_FUNCTION(collectionQueryIndexCreate) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zend_string* index_name = nullptr; - zval* keys = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(6, 7) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_STR(index_name) - Z_PARAM_ARRAY(keys) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->collection_query_index_create(bucket_name, scope_name, collection_name, index_name, keys, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zend_string* index_name = nullptr; + zval* keys = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(6, 7) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_STR(index_name) + Z_PARAM_ARRAY(keys) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->collection_query_index_create( + bucket_name, scope_name, collection_name, index_name, keys, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(collectionQueryIndexCreatePrimary) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->collection_query_index_create_primary(bucket_name, scope_name, collection_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->collection_query_index_create_primary( + bucket_name, scope_name, collection_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(collectionQueryIndexDrop) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(5, 6) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_STR(index_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->collection_query_index_drop(bucket_name, scope_name, collection_name, index_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(5, 6) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_STR(index_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->collection_query_index_drop( + bucket_name, scope_name, collection_name, index_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(collectionQueryIndexDropPrimary) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zend_string* index_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->collection_query_index_drop_primary(bucket_name, scope_name, collection_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } - RETURN_NULL(); + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zend_string* index_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->collection_query_index_drop_primary( + bucket_name, scope_name, collection_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } + RETURN_NULL(); } PHP_FUNCTION(collectionQueryIndexBuildDeferred) { - zval* connection = nullptr; - zend_string* bucket_name = nullptr; - zend_string* scope_name = nullptr; - zend_string* collection_name = nullptr; - zval* options = nullptr; - - ZEND_PARSE_PARAMETERS_START(4, 5) - Z_PARAM_RESOURCE(connection) - Z_PARAM_STR(bucket_name) - Z_PARAM_STR(scope_name) - Z_PARAM_STR(collection_name) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - - logger_flusher guard; - - auto* handle = fetch_couchbase_connection_from_resource(connection); - if (handle == nullptr) { - RETURN_THROWS(); - } - if (auto e = handle->collection_query_index_build_deferred(return_value, bucket_name, scope_name, collection_name, options); e.ec) { - couchbase_throw_exception(e); - RETURN_THROWS(); - } + zval* connection = nullptr; + zend_string* bucket_name = nullptr; + zend_string* scope_name = nullptr; + zend_string* collection_name = nullptr; + zval* options = nullptr; + + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_RESOURCE(connection) + Z_PARAM_STR(bucket_name) + Z_PARAM_STR(scope_name) + Z_PARAM_STR(collection_name) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + + logger_flusher guard; + + auto* handle = fetch_couchbase_connection_from_resource(connection); + if (handle == nullptr) { + RETURN_THROWS(); + } + if (auto e = handle->collection_query_index_build_deferred( + return_value, bucket_name, scope_name, collection_name, options); + e.ec) { + couchbase_throw_exception(e); + RETURN_THROWS(); + } } static PHP_MINFO_FUNCTION(couchbase) { - php_info_print_table_start(); - php_info_print_table_row(2, "couchbase", "enabled"); - php_info_print_table_row(2, "couchbase_extension_version", PHP_COUCHBASE_VERSION); - php_info_print_table_row(2, "couchbase_extension_revision", couchbase::php::extension_revision()); - php_info_print_table_row(2, "couchbase_client_revision", couchbase::php::cxx_client_revision()); - php_info_print_table_end(); - DISPLAY_INI_ENTRIES(); + php_info_print_table_start(); + php_info_print_table_row(2, "couchbase", "enabled"); + php_info_print_table_row(2, "couchbase_extension_version", PHP_COUCHBASE_VERSION); + php_info_print_table_row(2, "couchbase_extension_revision", couchbase::php::extension_revision()); + php_info_print_table_row(2, "couchbase_client_revision", couchbase::php::cxx_client_revision()); + php_info_print_table_end(); + DISPLAY_INI_ENTRIES(); } ZEND_BEGIN_ARG_INFO_EX(ai_CouchbaseExtension_version, 0, 0, 0) @@ -3468,7 +3571,11 @@ ZEND_ARG_TYPE_INFO(0, specs, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, options, IS_ARRAY, 1) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_CouchbaseExtension_createDocumentScanResult, 0, 0, IS_RESOURCE, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_CouchbaseExtension_createDocumentScanResult, + 0, + 0, + IS_RESOURCE, + 1) ZEND_ARG_INFO(0, connection) ZEND_ARG_TYPE_INFO(0, bucket, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, scope, IS_STRING, 0) @@ -3813,12 +3920,20 @@ ZEND_ARG_TYPE_INFO(0, settings, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, options, IS_ARRAY, 1) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_CouchbaseExtension_createTransactions, 0, 0, IS_RESOURCE, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_CouchbaseExtension_createTransactions, + 0, + 0, + IS_RESOURCE, + 1) ZEND_ARG_INFO(0, connection) ZEND_ARG_TYPE_INFO(0, configuration, IS_ARRAY, 1) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_CouchbaseExtension_createTransactionContext, 0, 0, IS_RESOURCE, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_CouchbaseExtension_createTransactionContext, + 0, + 0, + IS_RESOURCE, + 1) ZEND_ARG_INFO(0, transactions) ZEND_ARG_TYPE_INFO(0, configuration, IS_ARRAY, 1) ZEND_END_ARG_INFO() @@ -4139,22 +4254,22 @@ static zend_module_dep php_couchbase_deps[] = { // clang-format on zend_module_entry couchbase_module_entry = { - STANDARD_MODULE_HEADER_EX, - nullptr, - php_couchbase_deps, - PHP_COUCHBASE_EXTENSION_NAME, - couchbase_functions, /* extension function list */ - PHP_MINIT(couchbase), /* extension-wide startup function */ - PHP_MSHUTDOWN(couchbase), /* extension-wide shutdown function */ - PHP_RINIT(couchbase), /* per-request startup function */ - PHP_RSHUTDOWN(couchbase), /* per-request shutdown function */ - PHP_MINFO(couchbase), /* information function */ - PHP_COUCHBASE_VERSION, - PHP_MODULE_GLOBALS(couchbase), /* globals descriptor */ - nullptr, /* globals ctor */ - nullptr, /* globals dtor */ - nullptr, /* post deactivate */ - STANDARD_MODULE_PROPERTIES_EX, + STANDARD_MODULE_HEADER_EX, + nullptr, + php_couchbase_deps, + PHP_COUCHBASE_EXTENSION_NAME, + couchbase_functions, /* extension function list */ + PHP_MINIT(couchbase), /* extension-wide startup function */ + PHP_MSHUTDOWN(couchbase), /* extension-wide shutdown function */ + PHP_RINIT(couchbase), /* per-request startup function */ + PHP_RSHUTDOWN(couchbase), /* per-request shutdown function */ + PHP_MINFO(couchbase), /* information function */ + PHP_COUCHBASE_VERSION, + PHP_MODULE_GLOBALS(couchbase), /* globals descriptor */ + nullptr, /* globals ctor */ + nullptr, /* globals dtor */ + nullptr, /* post deactivate */ + STANDARD_MODULE_PROPERTIES_EX, }; #ifdef ZTS diff --git a/src/wrapper/common.cxx b/src/wrapper/common.cxx index b7fc2e8e..7c8cc771 100644 --- a/src/wrapper/common.cxx +++ b/src/wrapper/common.cxx @@ -113,565 +113,638 @@ COUCHBASE_API zend_class_entry* couchbase_exception() { - return couchbase_exception_ce; + return couchbase_exception_ce; } COUCHBASE_API void initialize_exceptions(const zend_function_entry* exception_functions) { - zend_class_entry ce; - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CouchbaseException", exception_functions); - couchbase_exception_ce = zend_register_internal_class_ex(&ce, zend_ce_exception); - zend_declare_property_null(couchbase_exception_ce, ZEND_STRL("context"), ZEND_ACC_PRIVATE); + zend_class_entry ce; + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CouchbaseException", exception_functions); + couchbase_exception_ce = zend_register_internal_class_ex(&ce, zend_ce_exception); + zend_declare_property_null(couchbase_exception_ce, ZEND_STRL("context"), ZEND_ACC_PRIVATE); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TimeoutException", nullptr); - timeout_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UnambiguousTimeoutException", nullptr); - unambiguous_timeout_exception_ce = zend_register_internal_class_ex(&ce, timeout_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "AmbiguousTimeoutException", nullptr); - ambiguous_timeout_exception_ce = zend_register_internal_class_ex(&ce, timeout_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "AuthenticationFailureException", nullptr); - authentication_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "BucketExistsException", nullptr); - bucket_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "BucketNotFlushableException", nullptr); - bucket_not_flushable_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "BucketNotFoundException", nullptr); - bucket_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CasMismatchException", nullptr); - cas_mismatch_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CollectionExistsException", nullptr); - collection_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CollectionNotFoundException", nullptr); - collection_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CompilationFailureException", nullptr); - compilation_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ConsistencyMismatchException", nullptr); - consistency_mismatch_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DatasetExistsException", nullptr); - dataset_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DatasetNotFoundException", nullptr); - dataset_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DataverseExistsException", nullptr); - dataverse_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DataverseNotFoundException", nullptr); - dataverse_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DecodingFailureException", nullptr); - decoding_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DeltaInvalidException", nullptr); - delta_invalid_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DesignDocumentNotFoundException", nullptr); - design_document_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentExistsException", nullptr); - document_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentIrretrievableException", nullptr); - document_irretrievable_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentLockedException", nullptr); - document_locked_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentNotFoundException", nullptr); - document_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentNotLockedException", nullptr); - document_not_locked_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentNotJsonException", nullptr); - document_not_json_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurabilityAmbiguousException", nullptr); - durability_ambiguous_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurabilityImpossibleException", nullptr); - durability_impossible_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurabilityLevelNotAvailableException", nullptr); - durability_level_not_available_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurableWriteInProgressException", nullptr); - durable_write_in_progress_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurableWriteReCommitInProgressException", nullptr); - durable_write_re_commit_in_progress_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "EncodingFailureException", nullptr); - encoding_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "FeatureNotAvailableException", nullptr); - feature_not_available_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "GroupNotFoundException", nullptr); - group_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexExistsException", nullptr); - index_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexFailureException", nullptr); - index_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexNotFoundException", nullptr); - index_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexNotReadyException", nullptr); - index_not_ready_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "InternalServerFailureException", nullptr); - internal_server_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "InvalidArgumentException", nullptr); - invalid_argument_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "JobQueueFullException", nullptr); - job_queue_full_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "LinkExistsException", nullptr); - link_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "LinkNotFoundException", nullptr); - link_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "NumberTooBigException", nullptr); - number_too_big_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ParsingFailureException", nullptr); - parsing_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathExistsException", nullptr); - path_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathInvalidException", nullptr); - path_invalid_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathMismatchException", nullptr); - path_mismatch_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathNotFoundException", nullptr); - path_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathTooBigException", nullptr); - path_too_big_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathTooDeepException", nullptr); - path_too_deep_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PermissionDeniedException", nullptr); - permission_denied_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PlanningFailureException", nullptr); - planning_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PreparedStatementFailureException", nullptr); - prepared_statement_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "RequestCanceledException", nullptr); - request_canceled_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ScopeExistsException", nullptr); - scope_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ScopeNotFoundException", nullptr); - scope_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ServiceNotAvailableException", nullptr); - service_not_available_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TemporaryFailureException", nullptr); - temporary_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UnsupportedOperationException", nullptr); - unsupported_operation_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UserExistsException", nullptr); - user_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UserNotFoundException", nullptr); - user_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ValueInvalidException", nullptr); - value_invalid_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ValueTooDeepException", nullptr); - value_too_deep_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ValueTooLargeException", nullptr); - value_too_large_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ViewNotFoundException", nullptr); - view_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "XattrCannotModifyVirtualAttributeException", nullptr); - xattr_cannot_modify_virtual_attribute_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "XattrInvalidKeyComboException", nullptr); - xattr_invalid_key_combo_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "XattrUnknownMacroException", nullptr); - xattr_unknown_macro_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "XattrUnknownVirtualAttributeException", nullptr); - xattr_unknown_virtual_attribute_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TimeoutException", nullptr); + timeout_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UnambiguousTimeoutException", nullptr); + unambiguous_timeout_exception_ce = zend_register_internal_class_ex(&ce, timeout_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "AmbiguousTimeoutException", nullptr); + ambiguous_timeout_exception_ce = zend_register_internal_class_ex(&ce, timeout_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "AuthenticationFailureException", nullptr); + authentication_failure_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "BucketExistsException", nullptr); + bucket_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "BucketNotFlushableException", nullptr); + bucket_not_flushable_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "BucketNotFoundException", nullptr); + bucket_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CasMismatchException", nullptr); + cas_mismatch_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CollectionExistsException", nullptr); + collection_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CollectionNotFoundException", nullptr); + collection_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "CompilationFailureException", nullptr); + compilation_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ConsistencyMismatchException", nullptr); + consistency_mismatch_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DatasetExistsException", nullptr); + dataset_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DatasetNotFoundException", nullptr); + dataset_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DataverseExistsException", nullptr); + dataverse_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DataverseNotFoundException", nullptr); + dataverse_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DecodingFailureException", nullptr); + decoding_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DeltaInvalidException", nullptr); + delta_invalid_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DesignDocumentNotFoundException", nullptr); + design_document_not_found_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentExistsException", nullptr); + document_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentIrretrievableException", nullptr); + document_irretrievable_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentLockedException", nullptr); + document_locked_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentNotFoundException", nullptr); + document_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentNotLockedException", nullptr); + document_not_locked_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DocumentNotJsonException", nullptr); + document_not_json_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurabilityAmbiguousException", nullptr); + durability_ambiguous_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurabilityImpossibleException", nullptr); + durability_impossible_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurabilityLevelNotAvailableException", nullptr); + durability_level_not_available_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "DurableWriteInProgressException", nullptr); + durable_write_in_progress_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY( + ce, "Couchbase\\Exception", "DurableWriteReCommitInProgressException", nullptr); + durable_write_re_commit_in_progress_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "EncodingFailureException", nullptr); + encoding_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "FeatureNotAvailableException", nullptr); + feature_not_available_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "GroupNotFoundException", nullptr); + group_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexExistsException", nullptr); + index_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexFailureException", nullptr); + index_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexNotFoundException", nullptr); + index_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "IndexNotReadyException", nullptr); + index_not_ready_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "InternalServerFailureException", nullptr); + internal_server_failure_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "InvalidArgumentException", nullptr); + invalid_argument_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "JobQueueFullException", nullptr); + job_queue_full_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "LinkExistsException", nullptr); + link_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "LinkNotFoundException", nullptr); + link_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "NumberTooBigException", nullptr); + number_too_big_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ParsingFailureException", nullptr); + parsing_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathExistsException", nullptr); + path_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathInvalidException", nullptr); + path_invalid_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathMismatchException", nullptr); + path_mismatch_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathNotFoundException", nullptr); + path_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathTooBigException", nullptr); + path_too_big_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PathTooDeepException", nullptr); + path_too_deep_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PermissionDeniedException", nullptr); + permission_denied_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PlanningFailureException", nullptr); + planning_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "PreparedStatementFailureException", nullptr); + prepared_statement_failure_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "RequestCanceledException", nullptr); + request_canceled_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ScopeExistsException", nullptr); + scope_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ScopeNotFoundException", nullptr); + scope_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ServiceNotAvailableException", nullptr); + service_not_available_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TemporaryFailureException", nullptr); + temporary_failure_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UnsupportedOperationException", nullptr); + unsupported_operation_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UserExistsException", nullptr); + user_exists_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "UserNotFoundException", nullptr); + user_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ValueInvalidException", nullptr); + value_invalid_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ValueTooDeepException", nullptr); + value_too_deep_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ValueTooLargeException", nullptr); + value_too_large_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "ViewNotFoundException", nullptr); + view_not_found_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY( + ce, "Couchbase\\Exception", "XattrCannotModifyVirtualAttributeException", nullptr); + xattr_cannot_modify_virtual_attribute_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "XattrInvalidKeyComboException", nullptr); + xattr_invalid_key_combo_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "XattrUnknownMacroException", nullptr); + xattr_unknown_macro_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "XattrUnknownVirtualAttributeException", nullptr); + xattr_unknown_virtual_attribute_exception_ce = + zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionException", nullptr); - transaction_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionOperationFailedException", nullptr); - transaction_operation_failed_exception_ce = zend_register_internal_class_ex(&ce, transaction_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionFailedException", nullptr); - transaction_failed_exception_ce = zend_register_internal_class_ex(&ce, transaction_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionExpiredException", nullptr); - transaction_expired_exception_ce = zend_register_internal_class_ex(&ce, transaction_exception_ce); - INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionCommitAmbiguousException", nullptr); - transaction_commit_ambiguous_exception_ce = zend_register_internal_class_ex(&ce, transaction_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionException", nullptr); + transaction_exception_ce = zend_register_internal_class_ex(&ce, couchbase_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionOperationFailedException", nullptr); + transaction_operation_failed_exception_ce = + zend_register_internal_class_ex(&ce, transaction_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionFailedException", nullptr); + transaction_failed_exception_ce = zend_register_internal_class_ex(&ce, transaction_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionExpiredException", nullptr); + transaction_expired_exception_ce = zend_register_internal_class_ex(&ce, transaction_exception_ce); + INIT_NS_CLASS_ENTRY(ce, "Couchbase\\Exception", "TransactionCommitAmbiguousException", nullptr); + transaction_commit_ambiguous_exception_ce = + zend_register_internal_class_ex(&ce, transaction_exception_ce); } COUCHBASE_API zend_class_entry* map_error_to_exception(const core_error_info& info) { - if (info.ec.category() == couchbase::core::impl::common_category()) { - switch (static_cast(info.ec.value())) { - case couchbase::errc::common::service_not_available: - return service_not_available_exception_ce; - case couchbase::errc::common::unsupported_operation: - return unsupported_operation_exception_ce; - case couchbase::errc::common::temporary_failure: - return temporary_failure_exception_ce; - case couchbase::errc::common::invalid_argument: - return invalid_argument_exception_ce; - case couchbase::errc::common::internal_server_failure: - return internal_server_failure_exception_ce; - case couchbase::errc::common::authentication_failure: - return authentication_failure_exception_ce; - case couchbase::errc::common::parsing_failure: - return parsing_failure_exception_ce; - case couchbase::errc::common::cas_mismatch: - return cas_mismatch_exception_ce; - case couchbase::errc::common::request_canceled: - return request_canceled_exception_ce; - case couchbase::errc::common::bucket_not_found: - return bucket_not_found_exception_ce; - case couchbase::errc::common::collection_not_found: - return collection_not_found_exception_ce; - case couchbase::errc::common::ambiguous_timeout: - return ambiguous_timeout_exception_ce; - case couchbase::errc::common::unambiguous_timeout: - return unambiguous_timeout_exception_ce; - case couchbase::errc::common::feature_not_available: - return feature_not_available_exception_ce; - case couchbase::errc::common::index_not_found: - return index_not_found_exception_ce; - case couchbase::errc::common::index_exists: - return index_exists_exception_ce; - case couchbase::errc::common::encoding_failure: - return encoding_failure_exception_ce; - case couchbase::errc::common::decoding_failure: - return decoding_failure_exception_ce; - case couchbase::errc::common::scope_not_found: - return scope_not_found_exception_ce; - default: - break; - } - } else if (info.ec.category() == couchbase::core::impl::analytics_category()) { - switch (static_cast(info.ec.value())) { - case couchbase::errc::analytics::compilation_failure: - return compilation_failure_exception_ce; - case couchbase::errc::analytics::job_queue_full: - return job_queue_full_exception_ce; - case couchbase::errc::analytics::dataset_not_found: - return dataset_not_found_exception_ce; - case couchbase::errc::analytics::dataverse_not_found: - return dataverse_not_found_exception_ce; - case couchbase::errc::analytics::dataset_exists: - return dataset_exists_exception_ce; - case couchbase::errc::analytics::dataverse_exists: - return dataverse_exists_exception_ce; - case couchbase::errc::analytics::link_not_found: - return link_not_found_exception_ce; - case couchbase::errc::analytics::link_exists: - return link_exists_exception_ce; - default: - break; - } - } else if (info.ec.category() == couchbase::core::impl::key_value_category()) { - switch (static_cast(info.ec.value())) { - case couchbase::errc::key_value::document_not_found: - return document_not_found_exception_ce; - case couchbase::errc::key_value::document_not_locked: - return document_not_locked_exception_ce; - case couchbase::errc::key_value::document_irretrievable: - return document_irretrievable_exception_ce; - case couchbase::errc::key_value::document_locked: - return document_locked_exception_ce; - case couchbase::errc::key_value::document_exists: - return document_exists_exception_ce; - case couchbase::errc::key_value::durability_level_not_available: - return durability_level_not_available_exception_ce; - case couchbase::errc::key_value::durability_impossible: - return durability_impossible_exception_ce; - case couchbase::errc::key_value::durability_ambiguous: - return durability_ambiguous_exception_ce; - case couchbase::errc::key_value::durable_write_in_progress: - return durable_write_in_progress_exception_ce; - case couchbase::errc::key_value::durable_write_re_commit_in_progress: - return durable_write_re_commit_in_progress_exception_ce; - case couchbase::errc::key_value::path_not_found: - return path_not_found_exception_ce; - case couchbase::errc::key_value::path_mismatch: - return path_mismatch_exception_ce; - case couchbase::errc::key_value::path_invalid: - return path_invalid_exception_ce; - case couchbase::errc::key_value::path_too_big: - return path_too_big_exception_ce; - case couchbase::errc::key_value::path_too_deep: - return path_too_deep_exception_ce; - case couchbase::errc::key_value::document_not_json: - return document_not_json_exception_ce; - case couchbase::errc::key_value::number_too_big: - return number_too_big_exception_ce; - case couchbase::errc::key_value::delta_invalid: - return delta_invalid_exception_ce; - case couchbase::errc::key_value::path_exists: - return path_exists_exception_ce; - case couchbase::errc::key_value::value_invalid: - return value_invalid_exception_ce; - case couchbase::errc::key_value::value_too_deep: - return value_too_deep_exception_ce; - case couchbase::errc::key_value::value_too_large: - return value_too_large_exception_ce; - case couchbase::errc::key_value::xattr_cannot_modify_virtual_attribute: - return xattr_cannot_modify_virtual_attribute_exception_ce; - case couchbase::errc::key_value::xattr_invalid_key_combo: - return xattr_invalid_key_combo_exception_ce; - case couchbase::errc::key_value::xattr_unknown_macro: - return xattr_unknown_macro_exception_ce; - case couchbase::errc::key_value::xattr_unknown_virtual_attribute: - return xattr_unknown_virtual_attribute_exception_ce; - default: - break; - } - } else if (info.ec.category() == couchbase::core::impl::management_category()) { - switch (static_cast(info.ec.value())) { - case couchbase::errc::management::collection_exists: - return collection_exists_exception_ce; - case couchbase::errc::management::group_not_found: - return group_not_found_exception_ce; - case couchbase::errc::management::bucket_exists: - return bucket_exists_exception_ce; - case couchbase::errc::management::bucket_not_flushable: - return bucket_not_flushable_exception_ce; - case couchbase::errc::management::scope_exists: - return scope_exists_exception_ce; - case couchbase::errc::management::user_exists: - return user_exists_exception_ce; - case couchbase::errc::management::user_not_found: - return user_not_found_exception_ce; - default: - break; - } - } else if (info.ec.category() == couchbase::core::impl::query_category()) { - switch (static_cast(info.ec.value())) { - case couchbase::errc::query::planning_failure: - return planning_failure_exception_ce; - case couchbase::errc::query::index_failure: - return index_failure_exception_ce; - case couchbase::errc::query::prepared_statement_failure: - return prepared_statement_failure_exception_ce; - default: - break; - } - } else if (info.ec.category() == couchbase::core::impl::search_category()) { - switch (static_cast(info.ec.value())) { - case couchbase::errc::search::index_not_ready: - return index_not_ready_exception_ce; - case couchbase::errc::search::consistency_mismatch: - return consistency_mismatch_exception_ce; - default: - break; - } - } else if (info.ec.category() == couchbase::core::impl::view_category()) { - switch (static_cast(info.ec.value())) { - case couchbase::errc::view::design_document_not_found: - return design_document_not_found_exception_ce; - case couchbase::errc::view::view_not_found: - return view_not_found_exception_ce; - default: - break; - } - } else if (info.ec.category() == detail::get_transactions_category()) { - switch (static_cast(info.ec.value())) { - case transactions_errc::operation_failed: - return transaction_operation_failed_exception_ce; - case transactions_errc::failed: - return transaction_failed_exception_ce; - case transactions_errc::expired: - return transaction_expired_exception_ce; - case transactions_errc::commit_ambiguous: - return transaction_commit_ambiguous_exception_ce; - case transactions_errc::std_exception: - case transactions_errc::unexpected_exception: - return transaction_exception_ce; - default: - break; - } + if (info.ec.category() == couchbase::core::impl::common_category()) { + switch (static_cast(info.ec.value())) { + case couchbase::errc::common::service_not_available: + return service_not_available_exception_ce; + case couchbase::errc::common::unsupported_operation: + return unsupported_operation_exception_ce; + case couchbase::errc::common::temporary_failure: + return temporary_failure_exception_ce; + case couchbase::errc::common::invalid_argument: + return invalid_argument_exception_ce; + case couchbase::errc::common::internal_server_failure: + return internal_server_failure_exception_ce; + case couchbase::errc::common::authentication_failure: + return authentication_failure_exception_ce; + case couchbase::errc::common::parsing_failure: + return parsing_failure_exception_ce; + case couchbase::errc::common::cas_mismatch: + return cas_mismatch_exception_ce; + case couchbase::errc::common::request_canceled: + return request_canceled_exception_ce; + case couchbase::errc::common::bucket_not_found: + return bucket_not_found_exception_ce; + case couchbase::errc::common::collection_not_found: + return collection_not_found_exception_ce; + case couchbase::errc::common::ambiguous_timeout: + return ambiguous_timeout_exception_ce; + case couchbase::errc::common::unambiguous_timeout: + return unambiguous_timeout_exception_ce; + case couchbase::errc::common::feature_not_available: + return feature_not_available_exception_ce; + case couchbase::errc::common::index_not_found: + return index_not_found_exception_ce; + case couchbase::errc::common::index_exists: + return index_exists_exception_ce; + case couchbase::errc::common::encoding_failure: + return encoding_failure_exception_ce; + case couchbase::errc::common::decoding_failure: + return decoding_failure_exception_ce; + case couchbase::errc::common::scope_not_found: + return scope_not_found_exception_ce; + default: + break; } - return couchbase_exception_ce; + } else if (info.ec.category() == couchbase::core::impl::analytics_category()) { + switch (static_cast(info.ec.value())) { + case couchbase::errc::analytics::compilation_failure: + return compilation_failure_exception_ce; + case couchbase::errc::analytics::job_queue_full: + return job_queue_full_exception_ce; + case couchbase::errc::analytics::dataset_not_found: + return dataset_not_found_exception_ce; + case couchbase::errc::analytics::dataverse_not_found: + return dataverse_not_found_exception_ce; + case couchbase::errc::analytics::dataset_exists: + return dataset_exists_exception_ce; + case couchbase::errc::analytics::dataverse_exists: + return dataverse_exists_exception_ce; + case couchbase::errc::analytics::link_not_found: + return link_not_found_exception_ce; + case couchbase::errc::analytics::link_exists: + return link_exists_exception_ce; + default: + break; + } + } else if (info.ec.category() == couchbase::core::impl::key_value_category()) { + switch (static_cast(info.ec.value())) { + case couchbase::errc::key_value::document_not_found: + return document_not_found_exception_ce; + case couchbase::errc::key_value::document_not_locked: + return document_not_locked_exception_ce; + case couchbase::errc::key_value::document_irretrievable: + return document_irretrievable_exception_ce; + case couchbase::errc::key_value::document_locked: + return document_locked_exception_ce; + case couchbase::errc::key_value::document_exists: + return document_exists_exception_ce; + case couchbase::errc::key_value::durability_level_not_available: + return durability_level_not_available_exception_ce; + case couchbase::errc::key_value::durability_impossible: + return durability_impossible_exception_ce; + case couchbase::errc::key_value::durability_ambiguous: + return durability_ambiguous_exception_ce; + case couchbase::errc::key_value::durable_write_in_progress: + return durable_write_in_progress_exception_ce; + case couchbase::errc::key_value::durable_write_re_commit_in_progress: + return durable_write_re_commit_in_progress_exception_ce; + case couchbase::errc::key_value::path_not_found: + return path_not_found_exception_ce; + case couchbase::errc::key_value::path_mismatch: + return path_mismatch_exception_ce; + case couchbase::errc::key_value::path_invalid: + return path_invalid_exception_ce; + case couchbase::errc::key_value::path_too_big: + return path_too_big_exception_ce; + case couchbase::errc::key_value::path_too_deep: + return path_too_deep_exception_ce; + case couchbase::errc::key_value::document_not_json: + return document_not_json_exception_ce; + case couchbase::errc::key_value::number_too_big: + return number_too_big_exception_ce; + case couchbase::errc::key_value::delta_invalid: + return delta_invalid_exception_ce; + case couchbase::errc::key_value::path_exists: + return path_exists_exception_ce; + case couchbase::errc::key_value::value_invalid: + return value_invalid_exception_ce; + case couchbase::errc::key_value::value_too_deep: + return value_too_deep_exception_ce; + case couchbase::errc::key_value::value_too_large: + return value_too_large_exception_ce; + case couchbase::errc::key_value::xattr_cannot_modify_virtual_attribute: + return xattr_cannot_modify_virtual_attribute_exception_ce; + case couchbase::errc::key_value::xattr_invalid_key_combo: + return xattr_invalid_key_combo_exception_ce; + case couchbase::errc::key_value::xattr_unknown_macro: + return xattr_unknown_macro_exception_ce; + case couchbase::errc::key_value::xattr_unknown_virtual_attribute: + return xattr_unknown_virtual_attribute_exception_ce; + default: + break; + } + } else if (info.ec.category() == couchbase::core::impl::management_category()) { + switch (static_cast(info.ec.value())) { + case couchbase::errc::management::collection_exists: + return collection_exists_exception_ce; + case couchbase::errc::management::group_not_found: + return group_not_found_exception_ce; + case couchbase::errc::management::bucket_exists: + return bucket_exists_exception_ce; + case couchbase::errc::management::bucket_not_flushable: + return bucket_not_flushable_exception_ce; + case couchbase::errc::management::scope_exists: + return scope_exists_exception_ce; + case couchbase::errc::management::user_exists: + return user_exists_exception_ce; + case couchbase::errc::management::user_not_found: + return user_not_found_exception_ce; + default: + break; + } + } else if (info.ec.category() == couchbase::core::impl::query_category()) { + switch (static_cast(info.ec.value())) { + case couchbase::errc::query::planning_failure: + return planning_failure_exception_ce; + case couchbase::errc::query::index_failure: + return index_failure_exception_ce; + case couchbase::errc::query::prepared_statement_failure: + return prepared_statement_failure_exception_ce; + default: + break; + } + } else if (info.ec.category() == couchbase::core::impl::search_category()) { + switch (static_cast(info.ec.value())) { + case couchbase::errc::search::index_not_ready: + return index_not_ready_exception_ce; + case couchbase::errc::search::consistency_mismatch: + return consistency_mismatch_exception_ce; + default: + break; + } + } else if (info.ec.category() == couchbase::core::impl::view_category()) { + switch (static_cast(info.ec.value())) { + case couchbase::errc::view::design_document_not_found: + return design_document_not_found_exception_ce; + case couchbase::errc::view::view_not_found: + return view_not_found_exception_ce; + default: + break; + } + } else if (info.ec.category() == detail::get_transactions_category()) { + switch (static_cast(info.ec.value())) { + case transactions_errc::operation_failed: + return transaction_operation_failed_exception_ce; + case transactions_errc::failed: + return transaction_failed_exception_ce; + case transactions_errc::expired: + return transaction_expired_exception_ce; + case transactions_errc::commit_ambiguous: + return transaction_commit_ambiguous_exception_ce; + case transactions_errc::std_exception: + case transactions_errc::unexpected_exception: + return transaction_exception_ce; + default: + break; + } + } + return couchbase_exception_ce; } static void -common_error_context_to_zval(const common_error_context& ctx, zval* return_value, const std::string& /* enhanced_error_message */) +common_error_context_to_zval(const common_error_context& ctx, + zval* return_value, + const std::string& /* enhanced_error_message */) { - if (ctx.last_dispatched_to) { - add_assoc_stringl(return_value, "lastDispatchedTo", ctx.last_dispatched_to.value().data(), ctx.last_dispatched_to.value().size()); - } - if (ctx.last_dispatched_from) { - add_assoc_stringl( - return_value, "lastDispatchedFrom", ctx.last_dispatched_from.value().data(), ctx.last_dispatched_from.value().size()); - } - if (ctx.retry_attempts > 0) { - add_assoc_long(return_value, "retryAttempts", ctx.retry_attempts); - } - if (!ctx.retry_reasons.empty()) { - zval reasons; - array_init_size(&reasons, ctx.retry_reasons.size()); - for (const auto& reason : ctx.retry_reasons) { - add_next_index_string(&reasons, reason.c_str()); - } - add_assoc_zval(return_value, "retryReasons", &reasons); + if (ctx.last_dispatched_to) { + add_assoc_stringl(return_value, + "lastDispatchedTo", + ctx.last_dispatched_to.value().data(), + ctx.last_dispatched_to.value().size()); + } + if (ctx.last_dispatched_from) { + add_assoc_stringl(return_value, + "lastDispatchedFrom", + ctx.last_dispatched_from.value().data(), + ctx.last_dispatched_from.value().size()); + } + if (ctx.retry_attempts > 0) { + add_assoc_long(return_value, "retryAttempts", ctx.retry_attempts); + } + if (!ctx.retry_reasons.empty()) { + zval reasons; + array_init_size(&reasons, ctx.retry_reasons.size()); + for (const auto& reason : ctx.retry_reasons) { + add_next_index_string(&reasons, reason.c_str()); } + add_assoc_zval(return_value, "retryReasons", &reasons); + } } static void -common_http_error_context_to_zval(const common_http_error_context& ctx, zval* return_value, const std::string& enhanced_error_message) +common_http_error_context_to_zval(const common_http_error_context& ctx, + zval* return_value, + const std::string& enhanced_error_message) { - add_assoc_stringl(return_value, "clientContextId", ctx.client_context_id.data(), ctx.client_context_id.size()); - add_assoc_long(return_value, "httpStatus", ctx.http_status); - add_assoc_stringl(return_value, "httpBody", ctx.http_body.data(), ctx.http_body.size()); - common_error_context_to_zval(ctx, return_value, enhanced_error_message); + add_assoc_stringl( + return_value, "clientContextId", ctx.client_context_id.data(), ctx.client_context_id.size()); + add_assoc_long(return_value, "httpStatus", ctx.http_status); + add_assoc_stringl(return_value, "httpBody", ctx.http_body.data(), ctx.http_body.size()); + common_error_context_to_zval(ctx, return_value, enhanced_error_message); } static void -error_context_to_zval(const key_value_error_context& ctx, zval* return_value, std::string& enhanced_error_message) +error_context_to_zval(const key_value_error_context& ctx, + zval* return_value, + std::string& enhanced_error_message) { - add_assoc_stringl(return_value, "bucketName", ctx.bucket.data(), ctx.bucket.size()); - add_assoc_stringl(return_value, "collection", ctx.collection.data(), ctx.collection.size()); - add_assoc_stringl(return_value, "scope", ctx.scope.data(), ctx.scope.size()); - add_assoc_stringl(return_value, "id", ctx.id.data(), ctx.id.size()); - add_assoc_long(return_value, "opaque", ctx.opaque); - if (ctx.cas > 0) { - auto cas = fmt::format("{:x}", ctx.cas); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - } - if (ctx.status_code) { - add_assoc_long(return_value, "statusCode", ctx.status_code.value_or(0xffff)); - } - if (ctx.error_map_name) { - add_assoc_stringl(return_value, "errorMapName", ctx.error_map_name.value().data(), ctx.error_map_name.value().size()); - } - if (ctx.error_map_description) { - add_assoc_stringl( - return_value, "errorMapDescription", ctx.error_map_description.value().data(), ctx.error_map_description.value().size()); - } - if (ctx.enhanced_error_reference) { - add_assoc_stringl( - return_value, "enhancedErrorReference", ctx.enhanced_error_reference.value().data(), ctx.enhanced_error_reference.value().size()); - enhanced_error_message.append(fmt::format("ref=\"{}\"", ctx.enhanced_error_reference.value())); - } - if (ctx.enhanced_error_context) { - add_assoc_stringl( - return_value, "enhancedErrorContext", ctx.enhanced_error_context.value().data(), ctx.enhanced_error_context.value().size()); - enhanced_error_message.append( - fmt::format("{}ctx=\"{}\"", ctx.enhanced_error_reference ? ", " : "", ctx.enhanced_error_context.value())); - } - common_error_context_to_zval(ctx, return_value, enhanced_error_message); + add_assoc_stringl(return_value, "bucketName", ctx.bucket.data(), ctx.bucket.size()); + add_assoc_stringl(return_value, "collection", ctx.collection.data(), ctx.collection.size()); + add_assoc_stringl(return_value, "scope", ctx.scope.data(), ctx.scope.size()); + add_assoc_stringl(return_value, "id", ctx.id.data(), ctx.id.size()); + add_assoc_long(return_value, "opaque", ctx.opaque); + if (ctx.cas > 0) { + auto cas = fmt::format("{:x}", ctx.cas); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + } + if (ctx.status_code) { + add_assoc_long(return_value, "statusCode", ctx.status_code.value_or(0xffff)); + } + if (ctx.error_map_name) { + add_assoc_stringl(return_value, + "errorMapName", + ctx.error_map_name.value().data(), + ctx.error_map_name.value().size()); + } + if (ctx.error_map_description) { + add_assoc_stringl(return_value, + "errorMapDescription", + ctx.error_map_description.value().data(), + ctx.error_map_description.value().size()); + } + if (ctx.enhanced_error_reference) { + add_assoc_stringl(return_value, + "enhancedErrorReference", + ctx.enhanced_error_reference.value().data(), + ctx.enhanced_error_reference.value().size()); + enhanced_error_message.append(fmt::format("ref=\"{}\"", ctx.enhanced_error_reference.value())); + } + if (ctx.enhanced_error_context) { + add_assoc_stringl(return_value, + "enhancedErrorContext", + ctx.enhanced_error_context.value().data(), + ctx.enhanced_error_context.value().size()); + enhanced_error_message.append(fmt::format("{}ctx=\"{}\"", + ctx.enhanced_error_reference ? ", " : "", + ctx.enhanced_error_context.value())); + } + common_error_context_to_zval(ctx, return_value, enhanced_error_message); } static void -error_context_to_zval(const query_error_context& ctx, zval* return_value, std::string& enhanced_error_message) +error_context_to_zval(const query_error_context& ctx, + zval* return_value, + std::string& enhanced_error_message) { - add_assoc_long(return_value, "firstErrorCode", ctx.first_error_code); - add_assoc_stringl(return_value, "firstErrorMessage", ctx.first_error_message.data(), ctx.first_error_message.size()); - enhanced_error_message = fmt::format("serverError={}, \"{}\"", ctx.first_error_code, ctx.first_error_message); - add_assoc_stringl(return_value, "statement", ctx.statement.data(), ctx.statement.size()); - if (ctx.parameters) { - add_assoc_stringl(return_value, "parameters", ctx.parameters.value().data(), ctx.parameters.value().size()); - } - common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); + add_assoc_long(return_value, "firstErrorCode", ctx.first_error_code); + add_assoc_stringl(return_value, + "firstErrorMessage", + ctx.first_error_message.data(), + ctx.first_error_message.size()); + enhanced_error_message = + fmt::format("serverError={}, \"{}\"", ctx.first_error_code, ctx.first_error_message); + add_assoc_stringl(return_value, "statement", ctx.statement.data(), ctx.statement.size()); + if (ctx.parameters) { + add_assoc_stringl( + return_value, "parameters", ctx.parameters.value().data(), ctx.parameters.value().size()); + } + common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); } static void -error_context_to_zval(const analytics_error_context& ctx, zval* return_value, std::string& enhanced_error_message) +error_context_to_zval(const analytics_error_context& ctx, + zval* return_value, + std::string& enhanced_error_message) { - add_assoc_long(return_value, "firstErrorCode", ctx.first_error_code); - add_assoc_stringl(return_value, "firstErrorMessage", ctx.first_error_message.data(), ctx.first_error_message.size()); - enhanced_error_message = fmt::format("serverError={}, \"{}\"", ctx.first_error_code, ctx.first_error_message); - add_assoc_stringl(return_value, "statement", ctx.statement.data(), ctx.statement.size()); - if (ctx.parameters) { - add_assoc_stringl(return_value, "parameters", ctx.parameters.value().data(), ctx.parameters.value().size()); - } - common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); + add_assoc_long(return_value, "firstErrorCode", ctx.first_error_code); + add_assoc_stringl(return_value, + "firstErrorMessage", + ctx.first_error_message.data(), + ctx.first_error_message.size()); + enhanced_error_message = + fmt::format("serverError={}, \"{}\"", ctx.first_error_code, ctx.first_error_message); + add_assoc_stringl(return_value, "statement", ctx.statement.data(), ctx.statement.size()); + if (ctx.parameters) { + add_assoc_stringl( + return_value, "parameters", ctx.parameters.value().data(), ctx.parameters.value().size()); + } + common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); } static void -error_context_to_zval(const view_query_error_context& ctx, zval* return_value, std::string& enhanced_error_message) +error_context_to_zval(const view_query_error_context& ctx, + zval* return_value, + std::string& enhanced_error_message) { - add_assoc_stringl(return_value, "designDocumentName", ctx.design_document_name.data(), ctx.design_document_name.size()); - add_assoc_stringl(return_value, "viewName", ctx.view_name.data(), ctx.view_name.size()); - common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); + add_assoc_stringl(return_value, + "designDocumentName", + ctx.design_document_name.data(), + ctx.design_document_name.size()); + add_assoc_stringl(return_value, "viewName", ctx.view_name.data(), ctx.view_name.size()); + common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); } static void -error_context_to_zval(const search_error_context& ctx, zval* return_value, std::string& enhanced_error_message) +error_context_to_zval(const search_error_context& ctx, + zval* return_value, + std::string& enhanced_error_message) { - add_assoc_stringl(return_value, "indexName", ctx.index_name.data(), ctx.index_name.size()); - if (ctx.query) { - add_assoc_stringl(return_value, "query", ctx.query.value().data(), ctx.query.value().size()); - } - if (ctx.parameters) { - add_assoc_stringl(return_value, "parameters", ctx.parameters.value().data(), ctx.parameters.value().size()); - } - common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); + add_assoc_stringl(return_value, "indexName", ctx.index_name.data(), ctx.index_name.size()); + if (ctx.query) { + add_assoc_stringl(return_value, "query", ctx.query.value().data(), ctx.query.value().size()); + } + if (ctx.parameters) { + add_assoc_stringl( + return_value, "parameters", ctx.parameters.value().data(), ctx.parameters.value().size()); + } + common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); } COUCHBASE_API void -error_context_to_zval(const http_error_context& ctx, zval* return_value, std::string& enhanced_error_message) +error_context_to_zval(const http_error_context& ctx, + zval* return_value, + std::string& enhanced_error_message) { - add_assoc_stringl(return_value, "method", ctx.method.data(), ctx.method.size()); - add_assoc_stringl(return_value, "path", ctx.path.data(), ctx.path.size()); - try { - if (auto json_body = core::utils::json::parse(ctx.http_body); json_body.is_object()) { - if (const auto* errors = json_body.find("errors"); errors != nullptr) { - enhanced_error_message = "errors=" + core::utils::json::generate(*errors); - } - } - } catch (const tao::pegtl::parse_error&) { - /* http body is not a JSON */ + add_assoc_stringl(return_value, "method", ctx.method.data(), ctx.method.size()); + add_assoc_stringl(return_value, "path", ctx.path.data(), ctx.path.size()); + try { + if (auto json_body = core::utils::json::parse(ctx.http_body); json_body.is_object()) { + if (const auto* errors = json_body.find("errors"); errors != nullptr) { + enhanced_error_message = "errors=" + core::utils::json::generate(*errors); + } } - common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); + } catch (const tao::pegtl::parse_error&) { + /* http body is not a JSON */ + } + common_http_error_context_to_zval(ctx, return_value, enhanced_error_message); } COUCHBASE_API void -error_context_to_zval(const transactions_error_context& ctx, zval* return_value, std::string& /* enhanced_error_message */) +error_context_to_zval(const transactions_error_context& ctx, + zval* return_value, + std::string& /* enhanced_error_message */) { - if (ctx.cause) { - add_assoc_stringl(return_value, "cause", ctx.cause->data(), ctx.cause->size()); - } - if (ctx.type) { - add_assoc_stringl(return_value, "type", ctx.type->data(), ctx.type->size()); - } - if (ctx.result) { - zval result; - array_init(&result); - add_assoc_stringl(&result, "transactionId", ctx.result->transaction_id.data(), ctx.result->transaction_id.size()); - add_assoc_bool(&result, "unstagingComplete", ctx.result->unstaging_complete); - add_assoc_zval(return_value, "result", &result); - } - if (ctx.should_not_rollback) { - add_assoc_bool(return_value, "shouldNotRollback", ctx.should_not_rollback.value()); - } - if (ctx.should_not_retry) { - add_assoc_bool(return_value, "shouldNotRetry", ctx.should_not_retry.value()); - } + if (ctx.cause) { + add_assoc_stringl(return_value, "cause", ctx.cause->data(), ctx.cause->size()); + } + if (ctx.type) { + add_assoc_stringl(return_value, "type", ctx.type->data(), ctx.type->size()); + } + if (ctx.result) { + zval result; + array_init(&result); + add_assoc_stringl(&result, + "transactionId", + ctx.result->transaction_id.data(), + ctx.result->transaction_id.size()); + add_assoc_bool(&result, "unstagingComplete", ctx.result->unstaging_complete); + add_assoc_zval(return_value, "result", &result); + } + if (ctx.should_not_rollback) { + add_assoc_bool(return_value, "shouldNotRollback", ctx.should_not_rollback.value()); + } + if (ctx.should_not_retry) { + add_assoc_bool(return_value, "shouldNotRetry", ctx.should_not_retry.value()); + } } COUCHBASE_API void -error_context_to_zval(const empty_error_context& /* ctx */, zval* /* return_value */, std::string& /* enhanced_error_message */) +error_context_to_zval(const empty_error_context& /* ctx */, + zval* /* return_value */, + std::string& /* enhanced_error_message */) { - /* nothing to do */ + /* nothing to do */ } COUCHBASE_API void -error_context_to_zval(const core_error_info& info, zval* return_value, std::string& enhanced_error_message) +error_context_to_zval(const core_error_info& info, + zval* return_value, + std::string& enhanced_error_message) { - array_init(return_value); - add_assoc_stringl(return_value, "error", info.message.data(), info.message.size()); - std::visit( - [return_value, &enhanced_error_message](const auto& ctx) { error_context_to_zval(ctx, return_value, enhanced_error_message); }, - info.error_context); + array_init(return_value); + add_assoc_stringl(return_value, "error", info.message.data(), info.message.size()); + std::visit( + [return_value, &enhanced_error_message](const auto& ctx) { + error_context_to_zval(ctx, return_value, enhanced_error_message); + }, + info.error_context); } COUCHBASE_API void create_exception(zval* return_value, const core_error_info& error_info) { - if (!error_info.ec) { - return; // success - } + if (!error_info.ec) { + return; // success + } - zval context; - std::string enhanced_error_message; - couchbase::php::error_context_to_zval(error_info, &context, enhanced_error_message); + zval context; + std::string enhanced_error_message; + couchbase::php::error_context_to_zval(error_info, &context, enhanced_error_message); - zend_class_entry* ex_ce = couchbase::php::map_error_to_exception(error_info); - object_init_ex(return_value, ex_ce); - std::stringstream message; - message << error_info.ec.message(); - if (!error_info.message.empty()) { - message << ": \"" << error_info.message << "\""; - } - if (!enhanced_error_message.empty()) { - message << ", " << enhanced_error_message; - } - couchbase_update_property_string(ex_ce, return_value, "message", message.str().c_str()); - couchbase_update_property_string(ex_ce, return_value, "file", error_info.location.file_name.c_str()); - couchbase_update_property_long(ex_ce, return_value, "line", error_info.location.line); - couchbase_update_property_long(ex_ce, return_value, "code", error_info.ec.value()); - couchbase_update_property(couchbase_exception_ce, return_value, "context", &context); - Z_DELREF(context); + zend_class_entry* ex_ce = couchbase::php::map_error_to_exception(error_info); + object_init_ex(return_value, ex_ce); + std::stringstream message; + message << error_info.ec.message(); + if (!error_info.message.empty()) { + message << ": \"" << error_info.message << "\""; + } + if (!enhanced_error_message.empty()) { + message << ", " << enhanced_error_message; + } + couchbase_update_property_string(ex_ce, return_value, "message", message.str().c_str()); + couchbase_update_property_string( + ex_ce, return_value, "file", error_info.location.file_name.c_str()); + couchbase_update_property_long(ex_ce, return_value, "line", error_info.location.line); + couchbase_update_property_long(ex_ce, return_value, "code", error_info.ec.value()); + couchbase_update_property(couchbase_exception_ce, return_value, "context", &context); + Z_DELREF(context); } } // namespace couchbase::php diff --git a/src/wrapper/common.hxx b/src/wrapper/common.hxx index c45cb218..538ffdce 100644 --- a/src/wrapper/common.hxx +++ b/src/wrapper/common.hxx @@ -33,8 +33,10 @@ char* log_level{ nullptr }; char* log_path{ nullptr }; bool log_php_log_err{ 1 }; bool log_stderr{ 0 }; -zend_long max_persistent{ -1 }; /* maximum number of persistent connections per process */ -zend_long persistent_timeout{ -1 }; /* time period after which idle persistent connection is considered expired */ +zend_long max_persistent{ -1 }; /* maximum number of persistent connections per process */ +zend_long persistent_timeout{ + -1 +}; /* time period after which idle persistent connection is considered expired */ /* module variables */ bool initialized{ 0 }; zend_long num_persistent{ 0 }; /* number of existing persistent connections */ diff --git a/src/wrapper/connection_handle.cxx b/src/wrapper/connection_handle.cxx index d36b32b4..df073e4e 100644 --- a/src/wrapper/connection_handle.cxx +++ b/src/wrapper/connection_handle.cxx @@ -58,558 +58,606 @@ namespace couchbase::php static std::string retry_reason_to_string(retry_reason reason) { - switch (reason) { - case retry_reason::do_not_retry: - return "do_not_retry"; - case retry_reason::socket_not_available: - return "socket_not_available"; - case retry_reason::service_not_available: - return "service_not_available"; - case retry_reason::node_not_available: - return "node_not_available"; - case retry_reason::key_value_not_my_vbucket: - return "key_value_not_my_vbucket"; - case retry_reason::key_value_collection_outdated: - return "key_value_collection_outdated"; - case retry_reason::key_value_error_map_retry_indicated: - return "key_value_error_map_retry_indicated"; - case retry_reason::key_value_locked: - return "key_value_locked"; - case retry_reason::key_value_temporary_failure: - return "key_value_temporary_failure"; - case retry_reason::key_value_sync_write_in_progress: - return "key_value_sync_write_in_progress"; - case retry_reason::key_value_sync_write_re_commit_in_progress: - return "key_value_sync_write_re_commit_in_progress"; - case retry_reason::service_response_code_indicated: - return "service_response_code_indicated"; - case retry_reason::socket_closed_while_in_flight: - return "socket_closed_while_in_flight"; - case retry_reason::circuit_breaker_open: - return "circuit_breaker_open"; - case retry_reason::query_prepared_statement_failure: - return "query_prepared_statement_failure"; - case retry_reason::query_index_not_found: - return "query_index_not_found"; - case retry_reason::analytics_temporary_failure: - return "analytics_temporary_failure"; - case retry_reason::search_too_many_requests: - return "search_too_many_requests"; - case retry_reason::views_temporary_failure: - return "views_temporary_failure"; - case retry_reason::views_no_active_partition: - return "views_no_active_partition"; - case retry_reason::unknown: - return "unknown"; - } - return "unexpected"; + switch (reason) { + case retry_reason::do_not_retry: + return "do_not_retry"; + case retry_reason::socket_not_available: + return "socket_not_available"; + case retry_reason::service_not_available: + return "service_not_available"; + case retry_reason::node_not_available: + return "node_not_available"; + case retry_reason::key_value_not_my_vbucket: + return "key_value_not_my_vbucket"; + case retry_reason::key_value_collection_outdated: + return "key_value_collection_outdated"; + case retry_reason::key_value_error_map_retry_indicated: + return "key_value_error_map_retry_indicated"; + case retry_reason::key_value_locked: + return "key_value_locked"; + case retry_reason::key_value_temporary_failure: + return "key_value_temporary_failure"; + case retry_reason::key_value_sync_write_in_progress: + return "key_value_sync_write_in_progress"; + case retry_reason::key_value_sync_write_re_commit_in_progress: + return "key_value_sync_write_re_commit_in_progress"; + case retry_reason::service_response_code_indicated: + return "service_response_code_indicated"; + case retry_reason::socket_closed_while_in_flight: + return "socket_closed_while_in_flight"; + case retry_reason::circuit_breaker_open: + return "circuit_breaker_open"; + case retry_reason::query_prepared_statement_failure: + return "query_prepared_statement_failure"; + case retry_reason::query_index_not_found: + return "query_index_not_found"; + case retry_reason::analytics_temporary_failure: + return "analytics_temporary_failure"; + case retry_reason::search_too_many_requests: + return "search_too_many_requests"; + case retry_reason::views_temporary_failure: + return "views_temporary_failure"; + case retry_reason::views_no_active_partition: + return "views_no_active_partition"; + case retry_reason::unknown: + return "unknown"; + } + return "unexpected"; } static const char* subdoc_opcode_to_string(core::protocol::subdoc_opcode opcode) { - switch (opcode) { - case core::protocol::subdoc_opcode::get_doc: - return "getDocument"; - case core::protocol::subdoc_opcode::set_doc: - return "setDocument"; - case core::protocol::subdoc_opcode::remove_doc: - return "removeDocument"; - case core::protocol::subdoc_opcode::get: - return "get"; - case core::protocol::subdoc_opcode::exists: - return "exists"; - case core::protocol::subdoc_opcode::dict_add: - return "dictionaryAdd"; - case core::protocol::subdoc_opcode::dict_upsert: - return "dictionaryUpsert"; - case core::protocol::subdoc_opcode::remove: - return "remove"; - case core::protocol::subdoc_opcode::replace: - return "replace"; - case core::protocol::subdoc_opcode::array_push_last: - return "arrayPushLast"; - case core::protocol::subdoc_opcode::array_push_first: - return "arrayPushFirst"; - case core::protocol::subdoc_opcode::array_insert: - return "arrayInsert"; - case core::protocol::subdoc_opcode::array_add_unique: - return "arrayAddUnique"; - case core::protocol::subdoc_opcode::counter: - return "counter"; - case core::protocol::subdoc_opcode::get_count: - return "getCount"; - case core::protocol::subdoc_opcode::replace_body_with_xattr: - return "replaceBodyWithXattr"; - } - return "unexpected"; + switch (opcode) { + case core::protocol::subdoc_opcode::get_doc: + return "getDocument"; + case core::protocol::subdoc_opcode::set_doc: + return "setDocument"; + case core::protocol::subdoc_opcode::remove_doc: + return "removeDocument"; + case core::protocol::subdoc_opcode::get: + return "get"; + case core::protocol::subdoc_opcode::exists: + return "exists"; + case core::protocol::subdoc_opcode::dict_add: + return "dictionaryAdd"; + case core::protocol::subdoc_opcode::dict_upsert: + return "dictionaryUpsert"; + case core::protocol::subdoc_opcode::remove: + return "remove"; + case core::protocol::subdoc_opcode::replace: + return "replace"; + case core::protocol::subdoc_opcode::array_push_last: + return "arrayPushLast"; + case core::protocol::subdoc_opcode::array_push_first: + return "arrayPushFirst"; + case core::protocol::subdoc_opcode::array_insert: + return "arrayInsert"; + case core::protocol::subdoc_opcode::array_add_unique: + return "arrayAddUnique"; + case core::protocol::subdoc_opcode::counter: + return "counter"; + case core::protocol::subdoc_opcode::get_count: + return "getCount"; + case core::protocol::subdoc_opcode::replace_body_with_xattr: + return "replaceBodyWithXattr"; + } + return "unexpected"; } static std::pair decode_lookup_subdoc_opcode(const zval* spec) { - if (spec == nullptr || Z_TYPE_P(spec) != IS_ARRAY) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "expected that spec will be represented as an array" } }; - } - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(spec), ZEND_STRL("opcode")); - if (value == nullptr && Z_TYPE_P(value) != IS_STRING) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "missing opcode field of the spec" } }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("getDocument")) == 0) { - return { { core::protocol::subdoc_opcode::get_doc }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("get")) == 0) { - return { { core::protocol::subdoc_opcode::get }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("exists")) == 0) { - return { { core::protocol::subdoc_opcode::exists }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("getCount")) == 0) { - return { { core::protocol::subdoc_opcode::get_count }, {} }; - } + if (spec == nullptr || Z_TYPE_P(spec) != IS_ARRAY) { return { {}, { errc::common::invalid_argument, ERROR_LOCATION, - fmt::format("unexpected opcode field of the spec: \"{}\"", std::string(Z_STRVAL_P(value), Z_STRLEN_P(value))) } }; + "expected that spec will be represented as an array" } }; + } + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(spec), ZEND_STRL("opcode")); + if (value == nullptr && Z_TYPE_P(value) != IS_STRING) { + return { + {}, { errc::common::invalid_argument, ERROR_LOCATION, "missing opcode field of the spec" } + }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("getDocument")) == 0) { + return { { core::protocol::subdoc_opcode::get_doc }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("get")) == 0) { + return { { core::protocol::subdoc_opcode::get }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("exists")) == 0) { + return { { core::protocol::subdoc_opcode::exists }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("getCount")) == 0) { + return { { core::protocol::subdoc_opcode::get_count }, {} }; + } + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unexpected opcode field of the spec: \"{}\"", + std::string(Z_STRVAL_P(value), Z_STRLEN_P(value))) } }; } static std::pair decode_mutation_subdoc_opcode(const zval* spec) { - if (spec == nullptr || Z_TYPE_P(spec) != IS_ARRAY) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "expected that spec will be represented as an array" } }; - } - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(spec), ZEND_STRL("opcode")); - if (value == nullptr && Z_TYPE_P(value) != IS_STRING) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "missing opcode field of the spec" } }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("setDocument")) == 0) { - return { { core::protocol::subdoc_opcode::set_doc }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("removeDocument")) == 0) { - return { { core::protocol::subdoc_opcode::remove_doc }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("dictionaryAdd")) == 0) { - return { { core::protocol::subdoc_opcode::dict_add }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("dictionaryUpsert")) == 0) { - return { { core::protocol::subdoc_opcode::dict_upsert }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("remove")) == 0) { - return { { core::protocol::subdoc_opcode::remove }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("replace")) == 0) { - return { { core::protocol::subdoc_opcode::replace }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayPushLast")) == 0) { - return { { core::protocol::subdoc_opcode::array_push_last }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayPushFirst")) == 0) { - return { { core::protocol::subdoc_opcode::array_push_first }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayInsert")) == 0) { - return { { core::protocol::subdoc_opcode::array_insert }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayAddUnique")) == 0) { - return { { core::protocol::subdoc_opcode::array_add_unique }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("counter")) == 0) { - return { { core::protocol::subdoc_opcode::counter }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("replaceBodyWithXattr")) == 0) { - return { { core::protocol::subdoc_opcode::replace_body_with_xattr }, {} }; - } + if (spec == nullptr || Z_TYPE_P(spec) != IS_ARRAY) { return { {}, { errc::common::invalid_argument, ERROR_LOCATION, - fmt::format("unexpected opcode field of the spec: \"{}\"", std::string(Z_STRVAL_P(value), Z_STRLEN_P(value))) } }; + "expected that spec will be represented as an array" } }; + } + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(spec), ZEND_STRL("opcode")); + if (value == nullptr && Z_TYPE_P(value) != IS_STRING) { + return { + {}, { errc::common::invalid_argument, ERROR_LOCATION, "missing opcode field of the spec" } + }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("setDocument")) == 0) { + return { { core::protocol::subdoc_opcode::set_doc }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("removeDocument")) == 0) { + return { { core::protocol::subdoc_opcode::remove_doc }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("dictionaryAdd")) == 0) { + return { { core::protocol::subdoc_opcode::dict_add }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("dictionaryUpsert")) == + 0) { + return { { core::protocol::subdoc_opcode::dict_upsert }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("remove")) == 0) { + return { { core::protocol::subdoc_opcode::remove }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("replace")) == 0) { + return { { core::protocol::subdoc_opcode::replace }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayPushLast")) == 0) { + return { { core::protocol::subdoc_opcode::array_push_last }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayPushFirst")) == 0) { + return { { core::protocol::subdoc_opcode::array_push_first }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayInsert")) == 0) { + return { { core::protocol::subdoc_opcode::array_insert }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("arrayAddUnique")) == 0) { + return { { core::protocol::subdoc_opcode::array_add_unique }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("counter")) == 0) { + return { { core::protocol::subdoc_opcode::counter }, {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("replaceBodyWithXattr")) == + 0) { + return { { core::protocol::subdoc_opcode::replace_body_with_xattr }, {} }; + } + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unexpected opcode field of the spec: \"{}\"", + std::string(Z_STRVAL_P(value), Z_STRLEN_P(value))) } }; } static void build_error_context(const couchbase::key_value_error_context& ctx, key_value_error_context& out) { - out.bucket = ctx.bucket(); - out.scope = ctx.scope(); - out.collection = ctx.collection(); - out.id = ctx.id(); - out.opaque = ctx.opaque(); - out.cas = ctx.cas().value(); - if (ctx.status_code()) { - out.status_code = static_cast(ctx.status_code().value()); - } - if (ctx.error_map_info()) { - out.error_map_name = ctx.error_map_info()->name(); - out.error_map_description = ctx.error_map_info()->description(); - } - if (ctx.extended_error_info()) { - out.enhanced_error_reference = ctx.extended_error_info()->reference(); - out.enhanced_error_context = ctx.extended_error_info()->context(); - } - out.last_dispatched_to = ctx.last_dispatched_to(); - out.last_dispatched_from = ctx.last_dispatched_from(); - out.retry_attempts = ctx.retry_attempts(); - if (!ctx.retry_reasons().empty()) { - for (const auto& reason : ctx.retry_reasons()) { - out.retry_reasons.insert(retry_reason_to_string(reason)); - } - } + out.bucket = ctx.bucket(); + out.scope = ctx.scope(); + out.collection = ctx.collection(); + out.id = ctx.id(); + out.opaque = ctx.opaque(); + out.cas = ctx.cas().value(); + if (ctx.status_code()) { + out.status_code = static_cast(ctx.status_code().value()); + } + if (ctx.error_map_info()) { + out.error_map_name = ctx.error_map_info()->name(); + out.error_map_description = ctx.error_map_info()->description(); + } + if (ctx.extended_error_info()) { + out.enhanced_error_reference = ctx.extended_error_info()->reference(); + out.enhanced_error_context = ctx.extended_error_info()->context(); + } + out.last_dispatched_to = ctx.last_dispatched_to(); + out.last_dispatched_from = ctx.last_dispatched_from(); + out.retry_attempts = ctx.retry_attempts(); + if (!ctx.retry_reasons().empty()) { + for (const auto& reason : ctx.retry_reasons()) { + out.retry_reasons.insert(retry_reason_to_string(reason)); + } + } } static key_value_error_context build_error_context(const couchbase::key_value_error_context& ctx) { - key_value_error_context out; - build_error_context(ctx, out); - return out; + key_value_error_context out; + build_error_context(ctx, out); + return out; } static subdocument_error_context build_error_context(const couchbase::subdocument_error_context& ctx) { - subdocument_error_context out; - build_error_context(ctx, out); - out.deleted = ctx.deleted(); - out.first_error_index = ctx.first_error_index(); - out.first_error_path = ctx.first_error_path(); - return out; + subdocument_error_context out; + build_error_context(ctx, out); + out.deleted = ctx.deleted(); + out.first_error_index = ctx.first_error_index(); + out.first_error_path = ctx.first_error_path(); + return out; } static query_error_context build_error_context(const core::error_context::query& ctx) { - query_error_context out; - out.client_context_id = ctx.client_context_id; - out.statement = ctx.statement; - out.parameters = ctx.parameters; - out.first_error_message = ctx.first_error_message; - out.first_error_code = ctx.first_error_code; - out.http_status = ctx.http_status; - out.http_body = ctx.http_body; - out.retry_attempts = ctx.retry_attempts; - out.last_dispatched_to = ctx.last_dispatched_to; - out.last_dispatched_from = ctx.last_dispatched_from; - if (!ctx.retry_reasons.empty()) { - for (const auto& reason : ctx.retry_reasons) { - out.retry_reasons.insert(retry_reason_to_string(reason)); - } - } - return out; + query_error_context out; + out.client_context_id = ctx.client_context_id; + out.statement = ctx.statement; + out.parameters = ctx.parameters; + out.first_error_message = ctx.first_error_message; + out.first_error_code = ctx.first_error_code; + out.http_status = ctx.http_status; + out.http_body = ctx.http_body; + out.retry_attempts = ctx.retry_attempts; + out.last_dispatched_to = ctx.last_dispatched_to; + out.last_dispatched_from = ctx.last_dispatched_from; + if (!ctx.retry_reasons.empty()) { + for (const auto& reason : ctx.retry_reasons) { + out.retry_reasons.insert(retry_reason_to_string(reason)); + } + } + return out; } static analytics_error_context build_error_context(const core::error_context::analytics& ctx) { - analytics_error_context out; - out.client_context_id = ctx.client_context_id; - out.statement = ctx.statement; - out.parameters = ctx.parameters; - out.first_error_message = ctx.first_error_message; - out.first_error_code = ctx.first_error_code; - out.http_status = ctx.http_status; - out.http_body = ctx.http_body; - out.retry_attempts = ctx.retry_attempts; - out.last_dispatched_to = ctx.last_dispatched_to; - out.last_dispatched_from = ctx.last_dispatched_from; - if (!ctx.retry_reasons.empty()) { - for (const auto& reason : ctx.retry_reasons) { - out.retry_reasons.insert(retry_reason_to_string(reason)); - } - } - return out; + analytics_error_context out; + out.client_context_id = ctx.client_context_id; + out.statement = ctx.statement; + out.parameters = ctx.parameters; + out.first_error_message = ctx.first_error_message; + out.first_error_code = ctx.first_error_code; + out.http_status = ctx.http_status; + out.http_body = ctx.http_body; + out.retry_attempts = ctx.retry_attempts; + out.last_dispatched_to = ctx.last_dispatched_to; + out.last_dispatched_from = ctx.last_dispatched_from; + if (!ctx.retry_reasons.empty()) { + for (const auto& reason : ctx.retry_reasons) { + out.retry_reasons.insert(retry_reason_to_string(reason)); + } + } + return out; } static view_query_error_context build_error_context(const core::error_context::view& ctx) { - view_query_error_context out; - out.client_context_id = ctx.client_context_id; - out.design_document_name = ctx.design_document_name; - out.view_name = ctx.view_name; - out.query_string = ctx.query_string; - out.http_status = ctx.http_status; - out.http_body = ctx.http_body; - out.retry_attempts = ctx.retry_attempts; - out.last_dispatched_to = ctx.last_dispatched_to; - out.last_dispatched_from = ctx.last_dispatched_from; - if (!ctx.retry_reasons.empty()) { - for (const auto& reason : ctx.retry_reasons) { - out.retry_reasons.insert(retry_reason_to_string(reason)); - } - } - return out; + view_query_error_context out; + out.client_context_id = ctx.client_context_id; + out.design_document_name = ctx.design_document_name; + out.view_name = ctx.view_name; + out.query_string = ctx.query_string; + out.http_status = ctx.http_status; + out.http_body = ctx.http_body; + out.retry_attempts = ctx.retry_attempts; + out.last_dispatched_to = ctx.last_dispatched_to; + out.last_dispatched_from = ctx.last_dispatched_from; + if (!ctx.retry_reasons.empty()) { + for (const auto& reason : ctx.retry_reasons) { + out.retry_reasons.insert(retry_reason_to_string(reason)); + } + } + return out; } static search_error_context build_error_context(const core::error_context::search& ctx) { - search_error_context out; - out.client_context_id = ctx.client_context_id; - out.index_name = ctx.index_name; - out.query = ctx.query; - out.parameters = ctx.parameters; - out.http_status = ctx.http_status; - out.http_body = ctx.http_body; - out.retry_attempts = ctx.retry_attempts; - out.last_dispatched_to = ctx.last_dispatched_to; - out.last_dispatched_from = ctx.last_dispatched_from; - if (!ctx.retry_reasons.empty()) { - for (const auto& reason : ctx.retry_reasons) { - out.retry_reasons.insert(retry_reason_to_string(reason)); - } - } - return out; + search_error_context out; + out.client_context_id = ctx.client_context_id; + out.index_name = ctx.index_name; + out.query = ctx.query; + out.parameters = ctx.parameters; + out.http_status = ctx.http_status; + out.http_body = ctx.http_body; + out.retry_attempts = ctx.retry_attempts; + out.last_dispatched_to = ctx.last_dispatched_to; + out.last_dispatched_from = ctx.last_dispatched_from; + if (!ctx.retry_reasons.empty()) { + for (const auto& reason : ctx.retry_reasons) { + out.retry_reasons.insert(retry_reason_to_string(reason)); + } + } + return out; } static http_error_context build_error_context(const core::error_context::http& ctx) { - http_error_context out; - out.client_context_id = ctx.client_context_id; - out.method = ctx.method; - out.path = ctx.path; - out.http_status = ctx.http_status; - out.http_body = ctx.http_body; - out.retry_attempts = ctx.retry_attempts; - if (!ctx.retry_reasons.empty()) { - for (const auto& reason : ctx.retry_reasons) { - out.retry_reasons.insert(retry_reason_to_string(reason)); - } - } - out.last_dispatched_from = ctx.last_dispatched_from; - out.last_dispatched_to = ctx.last_dispatched_to; - - return out; + http_error_context out; + out.client_context_id = ctx.client_context_id; + out.method = ctx.method; + out.path = ctx.path; + out.http_status = ctx.http_status; + out.http_body = ctx.http_body; + out.retry_attempts = ctx.retry_attempts; + if (!ctx.retry_reasons.empty()) { + for (const auto& reason : ctx.retry_reasons) { + out.retry_reasons.insert(retry_reason_to_string(reason)); + } + } + out.last_dispatched_from = ctx.last_dispatched_from; + out.last_dispatched_to = ctx.last_dispatched_to; + + return out; } class connection_handle::impl : public std::enable_shared_from_this { - public: - explicit impl(couchbase::core::origin origin) - : origin_(std::move(origin)) - { - } - - impl(impl&& other) = delete; - - impl(const impl& other) = delete; - - const impl& operator=(impl&& other) = delete; - - const impl& operator=(const impl& other) = delete; - - ~impl() - { - stop(); - } - - [[nodiscard]] std::shared_ptr cluster() const - { - return cluster_; - } - - void start() - { - worker_ = std::thread([self = shared_from_this()]() { self->ctx_.run(); }); - } - - void stop() - { - if (cluster_) { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->close([barrier]() { barrier->set_value(); }); - f.wait(); - cluster_.reset(); - if (worker_.joinable()) { - worker_.join(); - } - } - } - - std::string cluster_version(const std::string& bucket_name = "") - { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->execute( - couchbase::core::operations::management::cluster_describe_request{}, - [barrier](couchbase::core::operations::management::cluster_describe_response&& resp) { barrier->set_value(std::move(resp)); }); - auto resp = f.get(); - if (resp.ctx.ec == couchbase::errc::common::service_not_available && !bucket_name.empty()) { - if (auto e = bucket_open(bucket_name); e.ec) { - return {}; - } - return cluster_version(); - } - if (resp.ctx.ec || resp.info.nodes.empty()) { - return {}; - } - return resp.info.nodes.front().version; - } - - bool replicas_configured_for_bucket(const std::string& bucket_name) - { - if (auto e = bucket_open(bucket_name); e.ec) { - return false; - } - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - cluster_->with_bucket_configuration(bucket_name, [barrier](std::error_code ec, const core::topology::configuration& config) { - barrier->set_value({ ec, config }); - }); - auto [ec, config] = f.get(); - return !ec && config.num_replicas && config.num_replicas > 0 && config.nodes.size() > config.num_replicas; - } - - core_error_info open() - { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->open(origin_, [barrier](std::error_code ec) { barrier->set_value(ec); }); - if (auto ec = f.get()) { - stop(); - return { ec, { __LINE__, __FILE__, __func__ } }; - } - return {}; - } - - core_error_info bucket_open(const std::string& name) - { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->open_bucket(name, [barrier](std::error_code ec) { barrier->set_value(ec); }); - if (auto ec = f.get()) { - return { ec, { __LINE__, __FILE__, __func__ } }; - } - return {}; - } - - core_error_info bucket_close(const std::string& name) - { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->close_bucket(name, [barrier](std::error_code ec) { barrier->set_value(ec); }); - if (auto ec = f.get()) { - return { ec, { __LINE__, __FILE__, __func__ } }; - } +public: + explicit impl(couchbase::core::origin origin) + : origin_(std::move(origin)) + { + } + + impl(impl&& other) = delete; + + impl(const impl& other) = delete; + + const impl& operator=(impl&& other) = delete; + + const impl& operator=(const impl& other) = delete; + + ~impl() + { + stop(); + } + + [[nodiscard]] std::shared_ptr cluster() const + { + return cluster_; + } + + void start() + { + worker_ = std::thread([self = shared_from_this()]() { + self->ctx_.run(); + }); + } + + void stop() + { + if (cluster_) { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->close([barrier]() { + barrier->set_value(); + }); + f.wait(); + cluster_.reset(); + if (worker_.joinable()) { + worker_.join(); + } + } + } + + std::string cluster_version(const std::string& bucket_name = "") + { + auto barrier = std::make_shared< + std::promise>(); + auto f = barrier->get_future(); + cluster_->execute( + couchbase::core::operations::management::cluster_describe_request{}, + [barrier](couchbase::core::operations::management::cluster_describe_response&& resp) { + barrier->set_value(std::move(resp)); + }); + auto resp = f.get(); + if (resp.ctx.ec == couchbase::errc::common::service_not_available && !bucket_name.empty()) { + if (auto e = bucket_open(bucket_name); e.ec) { return {}; + } + return cluster_version(); + } + if (resp.ctx.ec || resp.info.nodes.empty()) { + return {}; + } + return resp.info.nodes.front().version; + } + + bool replicas_configured_for_bucket(const std::string& bucket_name) + { + if (auto e = bucket_open(bucket_name); e.ec) { + return false; + } + auto barrier = + std::make_shared>>(); + auto f = barrier->get_future(); + cluster_->with_bucket_configuration( + bucket_name, [barrier](std::error_code ec, const core::topology::configuration& config) { + barrier->set_value({ ec, config }); + }); + auto [ec, config] = f.get(); + return !ec && config.num_replicas && config.num_replicas > 0 && + config.nodes.size() > config.num_replicas; + } + + core_error_info open() + { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->open(origin_, [barrier](std::error_code ec) { + barrier->set_value(ec); + }); + if (auto ec = f.get()) { + stop(); + return { ec, { __LINE__, __FILE__, __func__ } }; } - - template - std::pair key_value_execute(const char* operation, Request request) - { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->execute(std::move(request), [barrier](Response&& resp) { barrier->set_value(std::move(resp)); }); - auto resp = f.get(); - if (resp.ctx.ec()) { - return { std::move(resp), - { resp.ctx.ec(), - ERROR_LOCATION, - fmt::format(R"(unable to execute KV operation "{}")", operation), - build_error_context(resp.ctx) } }; - } - return { std::move(resp), {} }; - } - - template - std::pair http_execute(const char* operation, Request request) - { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->execute(std::move(request), [barrier](Response&& resp) { barrier->set_value(std::move(resp)); }); - auto resp = f.get(); - if (resp.ctx.ec) { - return { std::move(resp), - { resp.ctx.ec, - ERROR_LOCATION, - fmt::format(R"(unable to execute HTTP operation "{}")", operation), - build_error_context(resp.ctx) } }; - } - return { std::move(resp), {} }; - } - - template - std::vector key_value_execute_multi(std::vector requests) - { - std::vector>> barriers; - barriers.reserve(requests.size()); - for (auto&& request : requests) { - auto barrier = std::make_shared>(); - cluster_->execute(request, [barrier](Response&& resp) { barrier->set_value(std::move(resp)); }); - barriers.emplace_back(barrier); - } - std::vector responses; - responses.reserve(requests.size()); - for (const auto& barrier : barriers) { - responses.emplace_back(barrier->get_future().get()); - } - return responses; - } - - std::pair ping(std::optional report_id, - std::optional bucket_name, - std::set services) - { - std::optional timeout{}; // not exposing timeout atm - - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->ping( - std::move(report_id), std::move(bucket_name), std::move(services), timeout, [barrier](core::diag::ping_result&& resp) { - barrier->set_value(std::move(resp)); - }); - auto resp = f.get(); - return { {}, std::move(resp) }; + return {}; + } + + core_error_info bucket_open(const std::string& name) + { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->open_bucket(name, [barrier](std::error_code ec) { + barrier->set_value(ec); + }); + if (auto ec = f.get()) { + return { ec, { __LINE__, __FILE__, __func__ } }; } - - std::pair diagnostics(std::string report_id) - { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - cluster_->diagnostics(report_id, [barrier](core::diag::diagnostics_result&& resp) { barrier->set_value(std::move(resp)); }); - auto resp = f.get(); - return { {}, std::move(resp) }; + return {}; + } + + core_error_info bucket_close(const std::string& name) + { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->close_bucket(name, [barrier](std::error_code ec) { + barrier->set_value(ec); + }); + if (auto ec = f.get()) { + return { ec, { __LINE__, __FILE__, __func__ } }; } - - couchbase::collection collection(std::string_view bucket, std::string_view scope, std::string_view collection) - { - return couchbase::cluster(*cluster_).bucket(bucket).scope(scope).collection(collection); + return {}; + } + + template + std::pair key_value_execute(const char* operation, Request request) + { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->execute(std::move(request), [barrier](Response&& resp) { + barrier->set_value(std::move(resp)); + }); + auto resp = f.get(); + if (resp.ctx.ec()) { + return { std::move(resp), + { resp.ctx.ec(), + ERROR_LOCATION, + fmt::format(R"(unable to execute KV operation "{}")", operation), + build_error_context(resp.ctx) } }; + } + return { std::move(resp), {} }; + } + + template + std::pair http_execute(const char* operation, Request request) + { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->execute(std::move(request), [barrier](Response&& resp) { + barrier->set_value(std::move(resp)); + }); + auto resp = f.get(); + if (resp.ctx.ec) { + return { std::move(resp), + { resp.ctx.ec, + ERROR_LOCATION, + fmt::format(R"(unable to execute HTTP operation "{}")", operation), + build_error_context(resp.ctx) } }; } + return { std::move(resp), {} }; + } - void notify_fork(fork_event event) - { - switch (event) { - case fork_event::prepare: - ctx_.stop(); - worker_.join(); - ctx_.notify_fork(asio::execution_context::fork_prepare); - CB_LOG_INFO("Prepare for fork()"); - shutdown_logger(); - break; - - case fork_event::parent: - initialize_logger(); - CB_LOG_INFO("Resume parent after fork()"); - ctx_.notify_fork(asio::execution_context::fork_parent); - ctx_.restart(); - worker_ = std::thread([self = shared_from_this()]() { self->ctx_.run(); }); - break; - - case fork_event::child: - initialize_logger(); - CB_LOG_INFO("Resume child after fork()"); - ctx_.notify_fork(asio::execution_context::fork_child); - ctx_.restart(); - worker_ = std::thread([self = shared_from_this()]() { self->ctx_.run(); }); - break; - } + template + std::vector key_value_execute_multi(std::vector requests) + { + std::vector>> barriers; + barriers.reserve(requests.size()); + for (auto&& request : requests) { + auto barrier = std::make_shared>(); + cluster_->execute(request, [barrier](Response&& resp) { + barrier->set_value(std::move(resp)); + }); + barriers.emplace_back(barrier); + } + std::vector responses; + responses.reserve(requests.size()); + for (const auto& barrier : barriers) { + responses.emplace_back(barrier->get_future().get()); + } + return responses; + } + + std::pair ping(std::optional report_id, + std::optional bucket_name, + std::set services) + { + std::optional timeout{}; // not exposing timeout atm + + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->ping(std::move(report_id), + std::move(bucket_name), + std::move(services), + timeout, + [barrier](core::diag::ping_result&& resp) { + barrier->set_value(std::move(resp)); + }); + auto resp = f.get(); + return { {}, std::move(resp) }; + } + + std::pair diagnostics(std::string report_id) + { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + cluster_->diagnostics(report_id, [barrier](core::diag::diagnostics_result&& resp) { + barrier->set_value(std::move(resp)); + }); + auto resp = f.get(); + return { {}, std::move(resp) }; + } + + couchbase::collection collection(std::string_view bucket, + std::string_view scope, + std::string_view collection) + { + return couchbase::cluster(*cluster_).bucket(bucket).scope(scope).collection(collection); + } + + void notify_fork(fork_event event) + { + switch (event) { + case fork_event::prepare: + ctx_.stop(); + worker_.join(); + ctx_.notify_fork(asio::execution_context::fork_prepare); + CB_LOG_INFO("Prepare for fork()"); + shutdown_logger(); + break; + + case fork_event::parent: + initialize_logger(); + CB_LOG_INFO("Resume parent after fork()"); + ctx_.notify_fork(asio::execution_context::fork_parent); + ctx_.restart(); + worker_ = std::thread([self = shared_from_this()]() { + self->ctx_.run(); + }); + break; + + case fork_event::child: + initialize_logger(); + CB_LOG_INFO("Resume child after fork()"); + ctx_.notify_fork(asio::execution_context::fork_child); + ctx_.restart(); + worker_ = std::thread([self = shared_from_this()]() { + self->ctx_.run(); + }); + break; } + } - private: - asio::io_context ctx_{}; - std::shared_ptr cluster_{ std::make_shared(ctx_) }; - std::thread worker_; - core::origin origin_; +private: + asio::io_context ctx_{}; + std::shared_ptr cluster_{ std::make_shared( + ctx_) }; + std::thread worker_; + core::origin origin_; }; COUCHBASE_API @@ -622,113 +670,119 @@ connection_handle::connection_handle(std::string connection_string, , connection_string_(std::move(connection_string)) , connection_hash_(std::move(connection_hash)) { - impl_->start(); + impl_->start(); } connection_handle::~connection_handle() { - impl_->stop(); + impl_->stop(); } COUCHBASE_API core_error_info connection_handle::open() { - return impl_->open(); + return impl_->open(); } COUCHBASE_API std::string connection_handle::cluster_version(const zend_string* bucket_name) { - return impl_->cluster_version(cb_string_new(bucket_name)); + return impl_->cluster_version(cb_string_new(bucket_name)); } COUCHBASE_API bool connection_handle::replicas_configured_for_bucket(const zend_string* bucket_name) { - return impl_->replicas_configured_for_bucket(cb_string_new(bucket_name)); + return impl_->replicas_configured_for_bucket(cb_string_new(bucket_name)); } void connection_handle::notify_fork(fork_event event) const { - return impl_->notify_fork(event); + return impl_->notify_fork(event); } COUCHBASE_API core_error_info connection_handle::bucket_open(const std::string& name) { - return impl_->bucket_open(name); + return impl_->bucket_open(name); } COUCHBASE_API core_error_info connection_handle::bucket_open(const zend_string* name) { - return impl_->bucket_open(cb_string_new(name)); + return impl_->bucket_open(cb_string_new(name)); } COUCHBASE_API core_error_info connection_handle::bucket_close(const zend_string* name) { - return impl_->bucket_close(cb_string_new(name)); + return impl_->bucket_close(cb_string_new(name)); } template static core_error_info cb_assign_user_domain(Request& req, const zval* options) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }; - } + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected array for options argument" }; + } - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("domain")); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_STRING: - break; - default: - return { errc::common::invalid_argument, ERROR_LOCATION, "expected domain to be a string in the options" }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("local")) == 0) { - req.domain = couchbase::core::management::rbac::auth_domain::local; - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("external")) == 0) { - req.domain = couchbase::core::management::rbac::auth_domain::external; - } else { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("unknown domain: {}", std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }; - } + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("domain")); + if (value == nullptr) { return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_STRING: + break; + default: + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected domain to be a string in the options" }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("local")) == 0) { + req.domain = couchbase::core::management::rbac::auth_domain::local; + } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("external")) == 0) { + req.domain = couchbase::core::management::rbac::auth_domain::external; + } else { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unknown domain: {}", + std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }; + } + return {}; } static inline void mutation_token_to_zval(const mutation_token& token, zval* return_value) { - array_init(return_value); - add_assoc_stringl(return_value, "bucketName", token.bucket_name().data(), token.bucket_name().size()); - add_assoc_long(return_value, "partitionId", token.partition_id()); - auto val = fmt::format("{:x}", token.partition_uuid()); - add_assoc_stringl(return_value, "partitionUuid", val.data(), val.size()); - val = fmt::format("{:x}", token.sequence_number()); - add_assoc_stringl(return_value, "sequenceNumber", val.data(), val.size()); + array_init(return_value); + add_assoc_stringl( + return_value, "bucketName", token.bucket_name().data(), token.bucket_name().size()); + add_assoc_long(return_value, "partitionId", token.partition_id()); + auto val = fmt::format("{:x}", token.partition_uuid()); + add_assoc_stringl(return_value, "partitionUuid", val.data(), val.size()); + val = fmt::format("{:x}", token.sequence_number()); + add_assoc_stringl(return_value, "sequenceNumber", val.data(), val.size()); } static inline bool is_mutation_token_valid(const mutation_token& token) { - return !token.bucket_name().empty() && token.partition_uuid() > 0; + return !token.bucket_name().empty() && token.partition_uuid() > 0; } COUCHBASE_API @@ -742,38 +796,40 @@ connection_handle::document_upsert(zval* return_value, zend_long flags, const zval* options) { - couchbase::upsert_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_expiry(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_preserve_expiry(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = - impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .upsert( - cb_string_new(id), couchbase::codec::encoded_value{ cb_binary_new(value), static_cast(flags) }, opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute upsert", build_error_context(ctx) }; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::upsert_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_expiry(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_preserve_expiry(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .upsert( + cb_string_new(id), + couchbase::codec::encoded_value{ cb_binary_new(value), static_cast(flags) }, + opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute upsert", build_error_context(ctx) }; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -787,34 +843,37 @@ connection_handle::document_insert(zval* return_value, zend_long flags, const zval* options) { - couchbase::insert_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_expiry(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = - impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .insert(cb_string_new(id), couchbase::codec::encoded_value{ cb_binary_new(value), static_cast(flags) }, opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute insert", build_error_context(ctx) }; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::insert_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_expiry(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .insert( + cb_string_new(id), + couchbase::codec::encoded_value{ cb_binary_new(value), static_cast(flags) }, + opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute insert", build_error_context(ctx) }; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -828,40 +887,43 @@ connection_handle::document_replace(zval* return_value, zend_long flags, const zval* options) { - couchbase::replace_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_expiry(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_preserve_expiry(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_cas(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = - impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .replace(cb_string_new(id), couchbase::codec::encoded_value{ cb_binary_new(value), static_cast(flags) }, opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute replace", build_error_context(ctx) }; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::replace_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_expiry(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_preserve_expiry(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_cas(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .replace( + cb_string_new(id), + couchbase::codec::encoded_value{ cb_binary_new(value), static_cast(flags) }, + opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute replace", build_error_context(ctx) }; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -874,31 +936,32 @@ connection_handle::document_append(zval* return_value, const zend_string* value, const zval* options) { - couchbase::append_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .binary() - .append(cb_string_new(id), cb_binary_new(value), opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute append", build_error_context(ctx) }; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::append_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .binary() + .append(cb_string_new(id), cb_binary_new(value), opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute append", build_error_context(ctx) }; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -911,31 +974,32 @@ connection_handle::document_prepend(zval* return_value, const zend_string* value, const zval* options) { - couchbase::prepend_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .binary() - .prepend(cb_string_new(id), cb_binary_new(value), opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute prepend", build_error_context(ctx) }; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::prepend_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .binary() + .prepend(cb_string_new(id), cb_binary_new(value), opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute prepend", build_error_context(ctx) }; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -947,44 +1011,45 @@ connection_handle::document_increment(zval* return_value, const zend_string* id, const zval* options) { - couchbase::increment_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_delta(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_initial_value(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_expiry(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .binary() - .increment(cb_string_new(id), opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute increment", build_error_context(ctx) }; - } - - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - add_assoc_long(return_value, "value", resp.content()); - auto value_str = fmt::format("{}", resp.content()); - add_assoc_stringl(return_value, "valueString", value_str.data(), value_str.size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::increment_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_delta(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_initial_value(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_expiry(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .binary() + .increment(cb_string_new(id), opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute increment", build_error_context(ctx) }; + } + + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + add_assoc_long(return_value, "value", resp.content()); + auto value_str = fmt::format("{}", resp.content()); + add_assoc_stringl(return_value, "valueString", value_str.data(), value_str.size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -996,44 +1061,45 @@ connection_handle::document_decrement(zval* return_value, const zend_string* id, const zval* options) { - couchbase::decrement_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_delta(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_initial_value(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_expiry(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .binary() - .decrement(cb_string_new(id), opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute decrement", build_error_context(ctx) }; - } - - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - add_assoc_long(return_value, "value", resp.content()); - auto value_str = fmt::format("{}", resp.content()); - add_assoc_stringl(return_value, "valueString", value_str.data(), value_str.size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::decrement_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_delta(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_initial_value(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_expiry(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .binary() + .decrement(cb_string_new(id), opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute decrement", build_error_context(ctx) }; + } + + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + add_assoc_long(return_value, "value", resp.content()); + auto value_str = fmt::format("{}", resp.content()); + add_assoc_stringl(return_value, "valueString", value_str.data(), value_str.size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -1045,59 +1111,61 @@ connection_handle::document_get(zval* return_value, const zend_string* id, const zval* options) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - bool with_expiry = false; - if (auto e = cb_assign_boolean(with_expiry, options, "withExpiry"); e.ec) { - return e; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + bool with_expiry = false; + if (auto e = cb_assign_boolean(with_expiry, options, "withExpiry"); e.ec) { + return e; + } + std::vector projections{}; + if (auto e = cb_assign_vector_of_strings(projections, options, "projections"); e.ec) { + return e; + } + if (!with_expiry && projections.empty()) { + couchbase::core::operations::get_request request{ doc_id }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; } - std::vector projections{}; - if (auto e = cb_assign_vector_of_strings(projections, options, "projections"); e.ec) { - return e; - } - if (!with_expiry && projections.empty()) { - couchbase::core::operations::get_request request{ doc_id }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas.value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - add_assoc_long(return_value, "flags", resp.flags); - add_assoc_stringl(return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); - return {}; - } - couchbase::core::operations::get_projected_request request{ doc_id }; - request.with_expiry = with_expiry; - request.projections = projections; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); if (err.ec) { - return err; + return err; } array_init(return_value); add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); auto cas = fmt::format("{:x}", resp.cas.value()); add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); add_assoc_long(return_value, "flags", resp.flags); - add_assoc_stringl(return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); - if (resp.expiry) { - add_assoc_long(return_value, "expiry", resp.expiry.value()); - } + add_assoc_stringl( + return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); return {}; + } + couchbase::core::operations::get_projected_request request{ doc_id }; + request.with_expiry = with_expiry; + request.projections = projections; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas.value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + add_assoc_long(return_value, "flags", resp.flags); + add_assoc_stringl( + return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); + if (resp.expiry) { + add_assoc_long(return_value, "expiry", resp.expiry.value()); + } + return {}; } COUCHBASE_API @@ -1109,24 +1177,29 @@ connection_handle::document_get_any_replica(zval* return_value, const zend_string* id, const zval* options) { - couchbase::get_any_replica_options o; - if (auto e = cb_set_timeout(o, options); e.ec) { - return e; - } - auto c = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); - auto [ctx, resp] = c.get_any_replica(cb_string_new(id), o).get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, fmt::format(R"(unable to execute KV operation "get_any_replica")"), build_error_context(ctx) }; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - auto encoded = resp.content_as(); - add_assoc_long(return_value, "flags", encoded.flags); - add_assoc_bool(return_value, "isReplica", resp.is_replica()); - add_assoc_stringl(return_value, "value", reinterpret_cast(encoded.data.data()), encoded.data.size()); - return {}; + couchbase::get_any_replica_options o; + if (auto e = cb_set_timeout(o, options); e.ec) { + return e; + } + auto c = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); + auto [ctx, resp] = c.get_any_replica(cb_string_new(id), o).get(); + if (ctx.ec()) { + return { ctx.ec(), + ERROR_LOCATION, + fmt::format(R"(unable to execute KV operation "get_any_replica")"), + build_error_context(ctx) }; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + auto encoded = resp.content_as(); + add_assoc_long(return_value, "flags", encoded.flags); + add_assoc_bool(return_value, "isReplica", resp.is_replica()); + add_assoc_stringl( + return_value, "value", reinterpret_cast(encoded.data.data()), encoded.data.size()); + return {}; } COUCHBASE_API @@ -1138,29 +1211,34 @@ connection_handle::document_get_all_replicas(zval* return_value, const zend_string* id, const zval* options) { - couchbase::get_all_replicas_options o; - if (auto e = cb_set_timeout(o, options); e.ec) { - return e; - } - auto c = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); - auto [ctx, responses] = c.get_all_replicas(cb_string_new(id), o).get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, fmt::format(R"(unable to execute KV operation "get_all_replicas")"), build_error_context(ctx) }; - } - array_init_size(return_value, responses.size()); - for (const auto& resp : responses) { - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); - add_assoc_bool(&entry, "isReplica", resp.is_replica()); - auto encoded = resp.content_as(); - add_assoc_long(&entry, "flags", encoded.flags); - add_assoc_stringl(&entry, "value", reinterpret_cast(encoded.data.data()), encoded.data.size()); - add_next_index_zval(return_value, &entry); - } - return {}; + couchbase::get_all_replicas_options o; + if (auto e = cb_set_timeout(o, options); e.ec) { + return e; + } + auto c = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); + auto [ctx, responses] = c.get_all_replicas(cb_string_new(id), o).get(); + if (ctx.ec()) { + return { ctx.ec(), + ERROR_LOCATION, + fmt::format(R"(unable to execute KV operation "get_all_replicas")"), + build_error_context(ctx) }; + } + array_init_size(return_value, responses.size()); + for (const auto& resp : responses) { + zval entry; + array_init(&entry); + add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); + add_assoc_bool(&entry, "isReplica", resp.is_replica()); + auto encoded = resp.content_as(); + add_assoc_long(&entry, "flags", encoded.flags); + add_assoc_stringl( + &entry, "value", reinterpret_cast(encoded.data.data()), encoded.data.size()); + add_next_index_zval(return_value, &entry); + } + return {}; } COUCHBASE_API @@ -1173,30 +1251,31 @@ connection_handle::document_get_and_lock(zval* return_value, zend_long lock_time, const zval* options) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - couchbase::core::operations::get_and_lock_request request{ doc_id }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.lock_time = static_cast(lock_time); - - auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas.value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - add_assoc_long(return_value, "flags", resp.flags); - add_assoc_stringl(return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); - return {}; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + couchbase::core::operations::get_and_lock_request request{ doc_id }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.lock_time = static_cast(lock_time); + + auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas.value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + add_assoc_long(return_value, "flags", resp.flags); + add_assoc_stringl( + return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); + return {}; } COUCHBASE_API @@ -1209,30 +1288,31 @@ connection_handle::document_get_and_touch(zval* return_value, zend_long expiry, const zval* options) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - couchbase::core::operations::get_and_touch_request request{ doc_id }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.expiry = static_cast(expiry); - - auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas.value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - add_assoc_long(return_value, "flags", resp.flags); - add_assoc_stringl(return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); - return {}; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + couchbase::core::operations::get_and_touch_request request{ doc_id }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.expiry = static_cast(expiry); + + auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas.value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + add_assoc_long(return_value, "flags", resp.flags); + add_assoc_stringl( + return_value, "value", reinterpret_cast(resp.value.data()), resp.value.size()); + return {}; } COUCHBASE_API @@ -1245,28 +1325,28 @@ connection_handle::document_touch(zval* return_value, zend_long expiry, const zval* options) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - couchbase::core::operations::touch_request request{ doc_id }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.expiry = static_cast(expiry); - - auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas.value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - return {}; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + couchbase::core::operations::touch_request request{ doc_id }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.expiry = static_cast(expiry); + + auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas.value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + return {}; } COUCHBASE_API @@ -1279,30 +1359,32 @@ connection_handle::document_unlock(zval* return_value, const zend_string* locked_cas, const zval* options) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - couchbase::core::operations::unlock_request request{ doc_id }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - if (auto e = cb_string_to_cas(std::string(ZSTR_VAL(locked_cas), ZSTR_LEN(locked_cas)), request.cas); e.ec) { - return e; - } - - auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas.value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - return {}; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + couchbase::core::operations::unlock_request request{ doc_id }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + if (auto e = + cb_string_to_cas(std::string(ZSTR_VAL(locked_cas), ZSTR_LEN(locked_cas)), request.cas); + e.ec) { + return e; + } + + auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas.value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + return {}; } COUCHBASE_API @@ -1314,32 +1396,34 @@ connection_handle::document_remove(zval* return_value, const zend_string* id, const zval* options) { - couchbase::remove_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_cas(opts, options); e.ec) { - return e; - } - - auto [ctx, resp] = - impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)).remove(cb_string_new(id), opts).get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute remove", build_error_context(ctx) }; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - return {}; + couchbase::remove_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_cas(opts, options); e.ec) { + return e; + } + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .remove(cb_string_new(id), opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute remove", build_error_context(ctx) }; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + return {}; } COUCHBASE_API @@ -1351,33 +1435,33 @@ connection_handle::document_exists(zval* return_value, const zend_string* id, const zval* options) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - couchbase::core::operations::exists_request request{ doc_id }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); - if (err.ec && resp.ctx.ec() != errc::key_value::document_not_found) { - return err; - } - array_init(return_value); - add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); - add_assoc_bool(return_value, "exists", resp.exists()); - add_assoc_bool(return_value, "deleted", resp.deleted); - auto cas = fmt::format("{:x}", resp.cas.value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - add_assoc_long(return_value, "flags", resp.flags); - add_assoc_long(return_value, "datatype", resp.datatype); - add_assoc_long(return_value, "expiry", resp.expiry); - auto sequence_number = fmt::format("{:x}", resp.sequence_number); - add_assoc_stringl(return_value, "sequenceNumber", sequence_number.data(), sequence_number.size()); - return {}; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + couchbase::core::operations::exists_request request{ doc_id }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + auto [resp, err] = impl_->key_value_execute(__func__, std::move(request)); + if (err.ec && resp.ctx.ec() != errc::key_value::document_not_found) { + return err; + } + array_init(return_value); + add_assoc_stringl(return_value, "id", resp.ctx.id().data(), resp.ctx.id().size()); + add_assoc_bool(return_value, "exists", resp.exists()); + add_assoc_bool(return_value, "deleted", resp.deleted); + auto cas = fmt::format("{:x}", resp.cas.value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + add_assoc_long(return_value, "flags", resp.flags); + add_assoc_long(return_value, "datatype", resp.datatype); + add_assoc_long(return_value, "expiry", resp.expiry); + auto sequence_number = fmt::format("{:x}", resp.sequence_number); + add_assoc_stringl(return_value, "sequenceNumber", sequence_number.data(), sequence_number.size()); + return {}; } COUCHBASE_API @@ -1390,154 +1474,171 @@ connection_handle::document_mutate_in(zval* return_value, const zval* specs, const zval* options) { - couchbase::mutate_in_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_access_deleted(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_create_as_deleted(opts, options); e.ec) { - return e; + couchbase::mutate_in_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_access_deleted(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_create_as_deleted(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_expiry(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_cas(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_store_semantics(opts, options); e.ec) { + return e; + } + + if (Z_TYPE_P(specs) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; + } + couchbase::mutate_in_specs cxx_specs; + const zval* item = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) + { + auto [operation, e] = decode_mutation_subdoc_opcode(item); + if (e.ec) { + return e; } - if (auto e = cb_set_expiry(opts, options); e.ec) { - return e; + bool xattr = false; + if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { + return e; } - if (auto e = cb_set_cas(opts, options); e.ec) { - return e; + bool create_path = false; + if (e = cb_assign_boolean(create_path, item, "createPath"); e.ec) { + return e; } - if (auto e = cb_set_store_semantics(opts, options); e.ec) { - return e; + bool expand_macros = false; + if (e = cb_assign_boolean(expand_macros, item, "expandMacros"); e.ec) { + return e; } - - if (Z_TYPE_P(specs) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; + std::string path; + if (e = cb_assign_string(path, item, "path"); e.ec) { + return e; } - couchbase::mutate_in_specs cxx_specs; - const zval* item = nullptr; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) - { - auto [operation, e] = decode_mutation_subdoc_opcode(item); - if (e.ec) { - return e; + switch (operation) { + case core::protocol::subdoc_opcode::counter: { + std::int64_t delta = 0; + if (e = cb_assign_integer(delta, item, "value"); e.ec) { + return e; } - bool xattr = false; - if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { - return e; + if (delta < 0) { + cxx_specs.push_back( + mutate_in_specs::decrement(path, -1 * delta).xattr(xattr).create_path(create_path)); + } else { + cxx_specs.push_back( + mutate_in_specs::increment(path, delta).xattr(xattr).create_path(create_path)); } - bool create_path = false; - if (e = cb_assign_boolean(create_path, item, "createPath"); e.ec) { - return e; - } - bool expand_macros = false; - if (e = cb_assign_boolean(expand_macros, item, "expandMacros"); e.ec) { - return e; + } break; + case core::protocol::subdoc_opcode::remove: + case core::protocol::subdoc_opcode::remove_doc: + cxx_specs.push_back(mutate_in_specs::remove(path).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::set_doc: + case core::protocol::subdoc_opcode::dict_upsert: + case core::protocol::subdoc_opcode::dict_add: + case core::protocol::subdoc_opcode::replace: + case core::protocol::subdoc_opcode::array_push_last: + case core::protocol::subdoc_opcode::array_push_first: + case core::protocol::subdoc_opcode::array_insert: + case core::protocol::subdoc_opcode::array_add_unique: { + auto [err, value] = cb_get_binary(item, "value"); + if (err.ec) { + return e; } - std::string path; - if (e = cb_assign_string(path, item, "path"); e.ec) { - return e; + if (!value) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unexpected value for \"{}\" spec", path) }; } switch (operation) { - case core::protocol::subdoc_opcode::counter: { - std::int64_t delta = 0; - if (e = cb_assign_integer(delta, item, "value"); e.ec) { - return e; - } - if (delta < 0) { - cxx_specs.push_back(mutate_in_specs::decrement(path, -1 * delta).xattr(xattr).create_path(create_path)); - } else { - cxx_specs.push_back(mutate_in_specs::increment(path, delta).xattr(xattr).create_path(create_path)); - } - } break; - case core::protocol::subdoc_opcode::remove: - case core::protocol::subdoc_opcode::remove_doc: - cxx_specs.push_back(mutate_in_specs::remove(path).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::set_doc: - case core::protocol::subdoc_opcode::dict_upsert: - case core::protocol::subdoc_opcode::dict_add: - case core::protocol::subdoc_opcode::replace: - case core::protocol::subdoc_opcode::array_push_last: - case core::protocol::subdoc_opcode::array_push_first: - case core::protocol::subdoc_opcode::array_insert: - case core::protocol::subdoc_opcode::array_add_unique: { - auto [err, value] = cb_get_binary(item, "value"); - if (err.ec) { - return e; - } - if (!value) { - return { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("unexpected value for \"{}\" spec", path) }; - } - switch (operation) { - case core::protocol::subdoc_opcode::set_doc: - case core::protocol::subdoc_opcode::dict_upsert: - cxx_specs.push_back(mutate_in_specs::upsert_raw(path, value.value()).xattr(xattr).create_path(create_path)); - break; - case core::protocol::subdoc_opcode::dict_add: - cxx_specs.push_back(mutate_in_specs::insert_raw(path, value.value()).xattr(xattr).create_path(create_path)); - break; - case core::protocol::subdoc_opcode::replace: - cxx_specs.push_back(mutate_in_specs::replace_raw(path, value.value()).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::array_add_unique: - cxx_specs.push_back( - mutate_in_specs::array_add_unique_raw(path, value.value()).xattr(xattr).create_path(create_path)); - break; - case core::protocol::subdoc_opcode::array_push_last: - cxx_specs.push_back(mutate_in_specs::array_append_raw(path, value.value()).xattr(xattr).create_path(create_path)); - break; - case core::protocol::subdoc_opcode::array_push_first: - cxx_specs.push_back(mutate_in_specs::array_prepend_raw(path, value.value()).xattr(xattr).create_path(create_path)); - break; - case core::protocol::subdoc_opcode::array_insert: - cxx_specs.push_back(mutate_in_specs::array_insert_raw(path, value.value()).xattr(xattr).create_path(create_path)); - break; - default: - break; - } - } break; - default: - break; - } - } - ZEND_HASH_FOREACH_END(); - - auto [ctx, resp] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .mutate_in(cb_string_new(id), cxx_specs, opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute mutate_in", build_error_context(ctx) }; - } - - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - add_assoc_bool(return_value, "deleted", resp.is_deleted()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(return_value, "mutationToken", &token_val); - } - - zval fields; - array_init_size(&fields, cxx_specs.specs().size()); - for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); - if (resp.has_value(idx)) { - auto value = resp.content_as(idx); - auto str = core::utils::json::generate(value); - add_assoc_stringl(&entry, "value", str.data(), str.size()); + case core::protocol::subdoc_opcode::set_doc: + case core::protocol::subdoc_opcode::dict_upsert: + cxx_specs.push_back(mutate_in_specs::upsert_raw(path, value.value()) + .xattr(xattr) + .create_path(create_path)); + break; + case core::protocol::subdoc_opcode::dict_add: + cxx_specs.push_back(mutate_in_specs::insert_raw(path, value.value()) + .xattr(xattr) + .create_path(create_path)); + break; + case core::protocol::subdoc_opcode::replace: + cxx_specs.push_back(mutate_in_specs::replace_raw(path, value.value()).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::array_add_unique: + cxx_specs.push_back(mutate_in_specs::array_add_unique_raw(path, value.value()) + .xattr(xattr) + .create_path(create_path)); + break; + case core::protocol::subdoc_opcode::array_push_last: + cxx_specs.push_back(mutate_in_specs::array_append_raw(path, value.value()) + .xattr(xattr) + .create_path(create_path)); + break; + case core::protocol::subdoc_opcode::array_push_first: + cxx_specs.push_back(mutate_in_specs::array_prepend_raw(path, value.value()) + .xattr(xattr) + .create_path(create_path)); + break; + case core::protocol::subdoc_opcode::array_insert: + cxx_specs.push_back(mutate_in_specs::array_insert_raw(path, value.value()) + .xattr(xattr) + .create_path(create_path)); + break; + default: + break; } - add_next_index_zval(&fields, &entry); - } - add_assoc_zval(return_value, "fields", &fields); - return {}; + } break; + default: + break; + } + } + ZEND_HASH_FOREACH_END(); + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .mutate_in(cb_string_new(id), cxx_specs, opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute mutate_in", build_error_context(ctx) }; + } + + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + add_assoc_bool(return_value, "deleted", resp.is_deleted()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(return_value, "mutationToken", &token_val); + } + + zval fields; + array_init_size(&fields, cxx_specs.specs().size()); + for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { + zval entry; + array_init(&entry); + add_assoc_stringl( + &entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); + if (resp.has_value(idx)) { + auto value = resp.content_as(idx); + auto str = core::utils::json::generate(value); + add_assoc_stringl(&entry, "value", str.data(), str.size()); + } + add_next_index_zval(&fields, &entry); + } + add_assoc_zval(return_value, "fields", &fields); + return {}; } COUCHBASE_API @@ -1550,79 +1651,81 @@ connection_handle::document_lookup_in(zval* return_value, const zval* specs, const zval* options) { - couchbase::lookup_in_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_access_deleted(opts, options); e.ec) { - return e; - } - - if (Z_TYPE_P(specs) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; - } - couchbase::lookup_in_specs cxx_specs; - - const zval* item = nullptr; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) - { - auto [operation, e] = decode_lookup_subdoc_opcode(item); - if (e.ec) { - return e; - } - bool xattr = false; - if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { - return e; - } - std::string path; - if (e = cb_assign_string(path, item, "path"); e.ec) { - return e; - } - switch (operation) { - case core::protocol::subdoc_opcode::get_doc: - case core::protocol::subdoc_opcode::get: - cxx_specs.push_back(lookup_in_specs::get(path).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::exists: - cxx_specs.push_back(lookup_in_specs::exists(path).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::get_count: - cxx_specs.push_back(lookup_in_specs::count(path).xattr(xattr)); - break; - default: - break; - } - } - ZEND_HASH_FOREACH_END(); - - auto [ctx, resp] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .lookup_in(cb_string_new(id), cxx_specs, opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute lookup_in", build_error_context(ctx) }; - } - - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - add_assoc_bool(return_value, "deleted", resp.is_deleted()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - zval fields; - array_init_size(&fields, cxx_specs.specs().size()); - for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); - add_assoc_bool(&entry, "exists", resp.exists(idx)); - if (resp.has_value(idx)) { - auto value = resp.content_as(idx); - auto str = core::utils::json::generate(value); - add_assoc_stringl(&entry, "value", str.data(), str.size()); - } - add_next_index_zval(&fields, &entry); - } - add_assoc_zval(return_value, "fields", &fields); - return {}; + couchbase::lookup_in_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_access_deleted(opts, options); e.ec) { + return e; + } + + if (Z_TYPE_P(specs) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; + } + couchbase::lookup_in_specs cxx_specs; + + const zval* item = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) + { + auto [operation, e] = decode_lookup_subdoc_opcode(item); + if (e.ec) { + return e; + } + bool xattr = false; + if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { + return e; + } + std::string path; + if (e = cb_assign_string(path, item, "path"); e.ec) { + return e; + } + switch (operation) { + case core::protocol::subdoc_opcode::get_doc: + case core::protocol::subdoc_opcode::get: + cxx_specs.push_back(lookup_in_specs::get(path).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::exists: + cxx_specs.push_back(lookup_in_specs::exists(path).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::get_count: + cxx_specs.push_back(lookup_in_specs::count(path).xattr(xattr)); + break; + default: + break; + } + } + ZEND_HASH_FOREACH_END(); + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .lookup_in(cb_string_new(id), cxx_specs, opts) + .get(); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to execute lookup_in", build_error_context(ctx) }; + } + + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + add_assoc_bool(return_value, "deleted", resp.is_deleted()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + zval fields; + array_init_size(&fields, cxx_specs.specs().size()); + for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { + zval entry; + array_init(&entry); + add_assoc_stringl( + &entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); + add_assoc_bool(&entry, "exists", resp.exists(idx)); + if (resp.has_value(idx)) { + auto value = resp.content_as(idx); + auto str = core::utils::json::generate(value); + add_assoc_stringl(&entry, "value", str.data(), str.size()); + } + add_next_index_zval(&fields, &entry); + } + add_assoc_zval(return_value, "fields", &fields); + return {}; } COUCHBASE_API @@ -1635,77 +1738,81 @@ connection_handle::document_lookup_in_any_replica(zval* return_value, const zval* specs, const zval* options) { - couchbase::lookup_in_any_replica_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - - if (Z_TYPE_P(specs) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; - } - couchbase::lookup_in_specs cxx_specs; - - const zval* item = nullptr; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) - { - auto [operation, e] = decode_lookup_subdoc_opcode(item); - if (e.ec) { - return e; - } - bool xattr = false; - if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { - return e; - } - std::string path; - if (e = cb_assign_string(path, item, "path"); e.ec) { - return e; - } - switch (operation) { - case core::protocol::subdoc_opcode::get_doc: - case core::protocol::subdoc_opcode::get: - cxx_specs.push_back(lookup_in_specs::get(path).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::exists: - cxx_specs.push_back(lookup_in_specs::exists(path).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::get_count: - cxx_specs.push_back(lookup_in_specs::count(path).xattr(xattr)); - break; - default: - break; - } - } - ZEND_HASH_FOREACH_END(); - - auto [ctx, resp] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .lookup_in_any_replica(cb_string_new(id), cxx_specs, opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute lookup_in_any_replica", build_error_context(ctx) }; - } - - array_init(return_value); - add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); - add_assoc_bool(return_value, "deleted", resp.is_deleted()); - add_assoc_bool(return_value, "isReplica", resp.is_replica()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - zval fields; - array_init_size(&fields, cxx_specs.specs().size()); - for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); - add_assoc_bool(&entry, "exists", resp.exists(idx)); - if (resp.has_value(idx)) { - auto value = resp.content_as(idx); - auto str = core::utils::json::generate(value); - add_assoc_stringl(&entry, "value", str.data(), str.size()); - } - add_next_index_zval(&fields, &entry); - } - add_assoc_zval(return_value, "fields", &fields); - return {}; + couchbase::lookup_in_any_replica_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + + if (Z_TYPE_P(specs) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; + } + couchbase::lookup_in_specs cxx_specs; + + const zval* item = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) + { + auto [operation, e] = decode_lookup_subdoc_opcode(item); + if (e.ec) { + return e; + } + bool xattr = false; + if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { + return e; + } + std::string path; + if (e = cb_assign_string(path, item, "path"); e.ec) { + return e; + } + switch (operation) { + case core::protocol::subdoc_opcode::get_doc: + case core::protocol::subdoc_opcode::get: + cxx_specs.push_back(lookup_in_specs::get(path).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::exists: + cxx_specs.push_back(lookup_in_specs::exists(path).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::get_count: + cxx_specs.push_back(lookup_in_specs::count(path).xattr(xattr)); + break; + default: + break; + } + } + ZEND_HASH_FOREACH_END(); + + auto [ctx, resp] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .lookup_in_any_replica(cb_string_new(id), cxx_specs, opts) + .get(); + if (ctx.ec()) { + return { + ctx.ec(), ERROR_LOCATION, "unable to execute lookup_in_any_replica", build_error_context(ctx) + }; + } + + array_init(return_value); + add_assoc_stringl(return_value, "id", ctx.id().data(), ctx.id().size()); + add_assoc_bool(return_value, "deleted", resp.is_deleted()); + add_assoc_bool(return_value, "isReplica", resp.is_replica()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + zval fields; + array_init_size(&fields, cxx_specs.specs().size()); + for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { + zval entry; + array_init(&entry); + add_assoc_stringl( + &entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); + add_assoc_bool(&entry, "exists", resp.exists(idx)); + if (resp.has_value(idx)) { + auto value = resp.content_as(idx); + auto str = core::utils::json::generate(value); + add_assoc_stringl(&entry, "value", str.data(), str.size()); + } + add_next_index_zval(&fields, &entry); + } + add_assoc_zval(return_value, "fields", &fields); + return {}; } COUCHBASE_API @@ -1718,82 +1825,86 @@ connection_handle::document_lookup_in_all_replicas(zval* return_value, const zval* specs, const zval* options) { - couchbase::lookup_in_all_replicas_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - - if (Z_TYPE_P(specs) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; - } - couchbase::lookup_in_specs cxx_specs; - - const zval* item = nullptr; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) - { - auto [operation, e] = decode_lookup_subdoc_opcode(item); - if (e.ec) { - return e; - } - bool xattr = false; - if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { - return e; - } - std::string path; - if (e = cb_assign_string(path, item, "path"); e.ec) { - return e; - } - switch (operation) { - case core::protocol::subdoc_opcode::get_doc: - case core::protocol::subdoc_opcode::get: - cxx_specs.push_back(lookup_in_specs::get(path).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::exists: - cxx_specs.push_back(lookup_in_specs::exists(path).xattr(xattr)); - break; - case core::protocol::subdoc_opcode::get_count: - cxx_specs.push_back(lookup_in_specs::count(path).xattr(xattr)); - break; - default: - break; - } - } - ZEND_HASH_FOREACH_END(); - - auto [ctx, responses] = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) - .lookup_in_all_replicas(cb_string_new(id), cxx_specs, opts) - .get(); - if (ctx.ec()) { - return { ctx.ec(), ERROR_LOCATION, "unable to execute lookup_in_all_replicas", build_error_context(ctx) }; - } - - array_init_size(return_value, responses.size()); - for (const auto& resp : responses) { - zval lookup_in_entry; - array_init(&lookup_in_entry); - add_assoc_stringl(&lookup_in_entry, "id", ctx.id().data(), ctx.id().size()); - add_assoc_bool(&lookup_in_entry, "deleted", resp.is_deleted()); - add_assoc_bool(&lookup_in_entry, "isReplica", resp.is_replica()); - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(&lookup_in_entry, "cas", cas.data(), cas.size()); - zval fields; - array_init_size(&fields, cxx_specs.specs().size()); - for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); - add_assoc_bool(&entry, "exists", resp.exists(idx)); - if (resp.has_value(idx)) { - auto value = resp.content_as(idx); - auto str = core::utils::json::generate(value); - add_assoc_stringl(&entry, "value", str.data(), str.size()); - } - add_next_index_zval(&fields, &entry); - } - add_assoc_zval(&lookup_in_entry, "fields", &fields); - add_next_index_zval(return_value, &lookup_in_entry); - } - return {}; + couchbase::lookup_in_all_replicas_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + + if (Z_TYPE_P(specs) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "specs must be an array" }; + } + couchbase::lookup_in_specs cxx_specs; + + const zval* item = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(specs), item) + { + auto [operation, e] = decode_lookup_subdoc_opcode(item); + if (e.ec) { + return e; + } + bool xattr = false; + if (e = cb_assign_boolean(xattr, item, "isXattr"); e.ec) { + return e; + } + std::string path; + if (e = cb_assign_string(path, item, "path"); e.ec) { + return e; + } + switch (operation) { + case core::protocol::subdoc_opcode::get_doc: + case core::protocol::subdoc_opcode::get: + cxx_specs.push_back(lookup_in_specs::get(path).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::exists: + cxx_specs.push_back(lookup_in_specs::exists(path).xattr(xattr)); + break; + case core::protocol::subdoc_opcode::get_count: + cxx_specs.push_back(lookup_in_specs::count(path).xattr(xattr)); + break; + default: + break; + } + } + ZEND_HASH_FOREACH_END(); + + auto [ctx, responses] = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)) + .lookup_in_all_replicas(cb_string_new(id), cxx_specs, opts) + .get(); + if (ctx.ec()) { + return { + ctx.ec(), ERROR_LOCATION, "unable to execute lookup_in_all_replicas", build_error_context(ctx) + }; + } + + array_init_size(return_value, responses.size()); + for (const auto& resp : responses) { + zval lookup_in_entry; + array_init(&lookup_in_entry); + add_assoc_stringl(&lookup_in_entry, "id", ctx.id().data(), ctx.id().size()); + add_assoc_bool(&lookup_in_entry, "deleted", resp.is_deleted()); + add_assoc_bool(&lookup_in_entry, "isReplica", resp.is_replica()); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(&lookup_in_entry, "cas", cas.data(), cas.size()); + zval fields; + array_init_size(&fields, cxx_specs.specs().size()); + for (std::size_t idx = 0; idx < cxx_specs.specs().size(); ++idx) { + zval entry; + array_init(&entry); + add_assoc_stringl( + &entry, "path", cxx_specs.specs()[idx].path_.data(), cxx_specs.specs()[idx].path_.size()); + add_assoc_bool(&entry, "exists", resp.exists(idx)); + if (resp.has_value(idx)) { + auto value = resp.content_as(idx); + auto str = core::utils::json::generate(value); + add_assoc_stringl(&entry, "value", str.data(), str.size()); + } + add_next_index_zval(&fields, &entry); + } + add_assoc_zval(&lookup_in_entry, "fields", &fields); + add_next_index_zval(return_value, &lookup_in_entry); + } + return {}; } COUCHBASE_API @@ -1805,53 +1916,60 @@ connection_handle::document_get_multi(zval* return_value, const zval* ids, const zval* options) { - if (Z_TYPE_P(ids) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected ids to be an array" }; - } - couchbase::get_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; + if (Z_TYPE_P(ids) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected ids to be an array" }; + } + couchbase::get_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + + std::vector requests{}; + requests.reserve(zend_array_count(Z_ARRVAL_P(ids))); + + const zval* id = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(ids), id) + { + requests.emplace_back(cb_string_new(id)); + } + ZEND_HASH_FOREACH_END(); + + std::vector>> + futures; + futures.reserve(requests.size()); + + auto c = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); + + for (auto&& request : requests) { + futures.emplace_back(c.get(std::move(request), opts)); + } + + array_init(return_value); + for (auto& f : futures) { + auto [ctx, resp] = f.get(); + + zval entry; + array_init(&entry); + add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); + if (ctx.ec()) { + zval ex; + create_exception(&ex, + { ctx.ec(), + ERROR_LOCATION, + "unable to execute KV operation getMulti", + build_error_context(ctx) }); + add_assoc_zval(&entry, "error", &ex); } - - std::vector requests{}; - requests.reserve(zend_array_count(Z_ARRVAL_P(ids))); - - const zval* id = nullptr; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(ids), id) - { - requests.emplace_back(cb_string_new(id)); - } - ZEND_HASH_FOREACH_END(); - - std::vector>> futures; - futures.reserve(requests.size()); - - auto c = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); - - for (auto&& request : requests) { - futures.emplace_back(c.get(std::move(request), opts)); - } - - array_init(return_value); - for (auto& f : futures) { - auto [ctx, resp] = f.get(); - - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); - if (ctx.ec()) { - zval ex; - create_exception(&ex, { ctx.ec(), ERROR_LOCATION, "unable to execute KV operation getMulti", build_error_context(ctx) }); - add_assoc_zval(&entry, "error", &ex); - } - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); - auto encoded = resp.content_as(); - add_assoc_long(&entry, "flags", encoded.flags); - add_assoc_stringl(&entry, "value", reinterpret_cast(encoded.data.data()), encoded.data.size()); - add_next_index_zval(return_value, &entry); - } - return {}; + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); + auto encoded = resp.content_as(); + add_assoc_long(&entry, "flags", encoded.flags); + add_assoc_stringl( + &entry, "value", reinterpret_cast(encoded.data.data()), encoded.data.size()); + add_next_index_zval(return_value, &entry); + } + return {}; } COUCHBASE_API @@ -1863,91 +1981,102 @@ connection_handle::document_remove_multi(zval* return_value, const zval* entries, const zval* options) { - if (Z_TYPE_P(entries) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected entries to be an array" }; - } - couchbase::remove_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - - std::vector> requests{}; - requests.reserve(zend_array_count(Z_ARRVAL_P(entries))); - - const zval* tuple = nullptr; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(entries), tuple) - { - switch (Z_TYPE_P(tuple)) { - case IS_STRING: { - requests.emplace_back(cb_string_new(tuple), couchbase::cas{}); - } break; - case IS_ARRAY: { - if (zend_array_count(Z_ARRVAL_P(tuple)) != 2) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that removeMulti ID-CAS tuples be represented by arrays with exactly two entries" }; - } - const zval* id = zend_hash_index_find(Z_ARRVAL_P(tuple), 0); - if (id == nullptr || Z_TYPE_P(id) != IS_STRING) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that removeMulti first member (ID) of ID-CAS tuple be a string" }; - } - const zval* cas = zend_hash_index_find(Z_ARRVAL_P(tuple), 1); - if (cas == nullptr || Z_TYPE_P(cas) != IS_STRING) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that removeMulti second member (CAS) of ID-CAS tuple be a string" }; - } - couchbase::cas cas_value{}; - if (auto e = cb_string_to_cas(std::string(Z_STRVAL_P(cas), Z_STRLEN_P(cas)), cas_value); e.ec) { - return e; - } - requests.emplace_back(cb_string_new(tuple), cas_value); - } break; - default: - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that removeMulti entries will be either ID strings or pairs of ID with CAS" }; - break; + if (Z_TYPE_P(entries) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected entries to be an array" }; + } + couchbase::remove_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + + std::vector> requests{}; + requests.reserve(zend_array_count(Z_ARRVAL_P(entries))); + + const zval* tuple = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(entries), tuple) + { + switch (Z_TYPE_P(tuple)) { + case IS_STRING: { + requests.emplace_back(cb_string_new(tuple), couchbase::cas{}); + } break; + case IS_ARRAY: { + if (zend_array_count(Z_ARRVAL_P(tuple)) != 2) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected that removeMulti ID-CAS tuples be represented by arrays with exactly " + "two entries" }; } - } - ZEND_HASH_FOREACH_END(); - - std::vector>> futures; - futures.reserve(requests.size()); - - auto c = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); - - for (auto& [id, content] : requests) { - futures.emplace_back(c.remove(std::move(id), opts)); - } - - array_init(return_value); - for (auto& f : futures) { - auto [ctx, resp] = f.get(); - - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); - if (ctx.ec()) { - zval ex; - create_exception(&ex, { ctx.ec(), ERROR_LOCATION, "unable to execute KV operation removeMulti", build_error_context(ctx) }); - add_assoc_zval(&entry, "error", &ex); + const zval* id = zend_hash_index_find(Z_ARRVAL_P(tuple), 0); + if (id == nullptr || Z_TYPE_P(id) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected that removeMulti first member (ID) of ID-CAS tuple be a string" }; } - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(&entry, "mutationToken", &token_val); + const zval* cas = zend_hash_index_find(Z_ARRVAL_P(tuple), 1); + if (cas == nullptr || Z_TYPE_P(cas) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected that removeMulti second member (CAS) of ID-CAS tuple be a string" }; } - add_next_index_zval(return_value, &entry); + couchbase::cas cas_value{}; + if (auto e = cb_string_to_cas(std::string(Z_STRVAL_P(cas), Z_STRLEN_P(cas)), cas_value); + e.ec) { + return e; + } + requests.emplace_back(cb_string_new(tuple), cas_value); + } break; + default: + return { + errc::common::invalid_argument, + ERROR_LOCATION, + "expected that removeMulti entries will be either ID strings or pairs of ID with CAS" + }; + break; + } + } + ZEND_HASH_FOREACH_END(); + + std::vector< + std::future>> + futures; + futures.reserve(requests.size()); + + auto c = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); + + for (auto& [id, content] : requests) { + futures.emplace_back(c.remove(std::move(id), opts)); + } + + array_init(return_value); + for (auto& f : futures) { + auto [ctx, resp] = f.get(); + + zval entry; + array_init(&entry); + add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); + if (ctx.ec()) { + zval ex; + create_exception(&ex, + { ctx.ec(), + ERROR_LOCATION, + "unable to execute KV operation removeMulti", + build_error_context(ctx) }); + add_assoc_zval(&entry, "error", &ex); } - return {}; + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(&entry, "mutationToken", &token_val); + } + add_next_index_zval(return_value, &entry); + } + return {}; } COUCHBASE_API @@ -1959,271 +2088,295 @@ connection_handle::document_upsert_multi(zval* return_value, const zval* entries, const zval* options) { - if (Z_TYPE_P(entries) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected entries to be an array" }; - } - couchbase::upsert_options opts; - if (auto e = cb_set_timeout(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_durability(opts, options); e.ec) { - return e; - } - if (auto e = cb_set_preserve_expiry(opts, options); e.ec) { - return e; - } - - std::vector> requests{}; - requests.reserve(zend_array_count(Z_ARRVAL_P(entries))); - - const zval* tuple = nullptr; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(entries), tuple) - { - if (Z_TYPE_P(tuple) != IS_ARRAY || zend_array_count(Z_ARRVAL_P(tuple)) != 3) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that core upsertMulti entries will be ID-VALUE-FLAGS tuples" }; - } - const zval* id = zend_hash_index_find(Z_ARRVAL_P(tuple), 0); - if (id == nullptr || Z_TYPE_P(id) != IS_STRING) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that core upsertMulti first member (ID) of ID-VALUE-FLAGS tuple be a string" }; - } - const zval* value = zend_hash_index_find(Z_ARRVAL_P(tuple), 1); - if (value == nullptr || Z_TYPE_P(value) != IS_STRING) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that core upsertMulti second member (CAS) of ID-VALUE-FLAGS tuple be a string" }; - } - const zval* flags = zend_hash_index_find(Z_ARRVAL_P(tuple), 2); - if (flags == nullptr || Z_TYPE_P(flags) != IS_LONG) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected that core upsertMulti third member (FLAGS) of ID-VALUE-FLAGS tuple be an integer" }; - } - requests.emplace_back(cb_string_new(id), codec::encoded_value{ cb_binary_new(value), static_cast(Z_LVAL_P(flags)) }); - } - ZEND_HASH_FOREACH_END(); - - std::vector>> futures; - futures.reserve(requests.size()); - - auto c = impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); - - for (auto& [id, content] : requests) { - futures.emplace_back(c.upsert(std::move(id), content, opts)); + if (Z_TYPE_P(entries) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected entries to be an array" }; + } + couchbase::upsert_options opts; + if (auto e = cb_set_timeout(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_durability(opts, options); e.ec) { + return e; + } + if (auto e = cb_set_preserve_expiry(opts, options); e.ec) { + return e; + } + + std::vector> requests{}; + requests.reserve(zend_array_count(Z_ARRVAL_P(entries))); + + const zval* tuple = nullptr; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(entries), tuple) + { + if (Z_TYPE_P(tuple) != IS_ARRAY || zend_array_count(Z_ARRVAL_P(tuple)) != 3) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected that core upsertMulti entries will be ID-VALUE-FLAGS tuples" }; + } + const zval* id = zend_hash_index_find(Z_ARRVAL_P(tuple), 0); + if (id == nullptr || Z_TYPE_P(id) != IS_STRING) { + return { + errc::common::invalid_argument, + ERROR_LOCATION, + "expected that core upsertMulti first member (ID) of ID-VALUE-FLAGS tuple be a string" + }; + } + const zval* value = zend_hash_index_find(Z_ARRVAL_P(tuple), 1); + if (value == nullptr || Z_TYPE_P(value) != IS_STRING) { + return { + errc::common::invalid_argument, + ERROR_LOCATION, + "expected that core upsertMulti second member (CAS) of ID-VALUE-FLAGS tuple be a string" + }; + } + const zval* flags = zend_hash_index_find(Z_ARRVAL_P(tuple), 2); + if (flags == nullptr || Z_TYPE_P(flags) != IS_LONG) { + return { + errc::common::invalid_argument, + ERROR_LOCATION, + "expected that core upsertMulti third member (FLAGS) of ID-VALUE-FLAGS tuple be an integer" + }; + } + requests.emplace_back( + cb_string_new(id), + codec::encoded_value{ cb_binary_new(value), static_cast(Z_LVAL_P(flags)) }); + } + ZEND_HASH_FOREACH_END(); + + std::vector< + std::future>> + futures; + futures.reserve(requests.size()); + + auto c = + impl_->collection(cb_string_new(bucket), cb_string_new(scope), cb_string_new(collection)); + + for (auto& [id, content] : requests) { + futures.emplace_back(c.upsert(std::move(id), content, opts)); + } + + array_init(return_value); + for (auto& f : futures) { + auto [ctx, resp] = f.get(); + + zval entry; + array_init(&entry); + add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); + if (ctx.ec()) { + zval ex; + create_exception(&ex, + { ctx.ec(), + ERROR_LOCATION, + "unable to execute KV operation upsertMulti", + build_error_context(ctx) }); + add_assoc_zval(&entry, "error", &ex); } - - array_init(return_value); - for (auto& f : futures) { - auto [ctx, resp] = f.get(); - - zval entry; - array_init(&entry); - add_assoc_stringl(&entry, "id", ctx.id().data(), ctx.id().size()); - if (ctx.ec()) { - zval ex; - create_exception(&ex, { ctx.ec(), ERROR_LOCATION, "unable to execute KV operation upsertMulti", build_error_context(ctx) }); - add_assoc_zval(&entry, "error", &ex); - } - auto cas = fmt::format("{:x}", resp.cas().value()); - add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); - if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { - zval token_val; - mutation_token_to_zval(resp.mutation_token().value(), &token_val); - add_assoc_zval(&entry, "mutationToken", &token_val); - } - add_next_index_zval(return_value, &entry); + auto cas = fmt::format("{:x}", resp.cas().value()); + add_assoc_stringl(&entry, "cas", cas.data(), cas.size()); + if (resp.mutation_token() && is_mutation_token_valid(resp.mutation_token().value())) { + zval token_val; + mutation_token_to_zval(resp.mutation_token().value(), &token_val); + add_assoc_zval(&entry, "mutationToken", &token_val); } - return {}; + add_next_index_zval(return_value, &entry); + } + return {}; } COUCHBASE_API core_error_info connection_handle::query(zval* return_value, const zend_string* statement, const zval* options) { - auto [request, e] = zval_to_query_request(statement, options); - if (e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - query_response_to_zval(return_value, resp); - return {}; + auto [request, e] = zval_to_query_request(statement, options); + if (e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + query_response_to_zval(return_value, resp); + return {}; } static const char* cb_analytics_status_str(core::operations::analytics_response::analytics_status status) { - switch (status) { - case couchbase::core::operations::analytics_response::running: - return "running"; - case couchbase::core::operations::analytics_response::success: - return "success"; - case couchbase::core::operations::analytics_response::errors: - return "errors"; - case couchbase::core::operations::analytics_response::completed: - return "completed"; - case couchbase::core::operations::analytics_response::stopped: - return "stopped"; - case couchbase::core::operations::analytics_response::timedout: - return "timedout"; - case couchbase::core::operations::analytics_response::closed: - return "closed"; - case couchbase::core::operations::analytics_response::fatal: - return "fatal"; - case couchbase::core::operations::analytics_response::aborted: - return "aborted"; - case couchbase::core::operations::analytics_response::unknown: - return "unknown"; - default: - break; - } - return "unknown"; + switch (status) { + case couchbase::core::operations::analytics_response::running: + return "running"; + case couchbase::core::operations::analytics_response::success: + return "success"; + case couchbase::core::operations::analytics_response::errors: + return "errors"; + case couchbase::core::operations::analytics_response::completed: + return "completed"; + case couchbase::core::operations::analytics_response::stopped: + return "stopped"; + case couchbase::core::operations::analytics_response::timedout: + return "timedout"; + case couchbase::core::operations::analytics_response::closed: + return "closed"; + case couchbase::core::operations::analytics_response::fatal: + return "fatal"; + case couchbase::core::operations::analytics_response::aborted: + return "aborted"; + case couchbase::core::operations::analytics_response::unknown: + return "unknown"; + default: + break; + } + return "unknown"; } COUCHBASE_API core_error_info -connection_handle::analytics_query(zval* return_value, const zend_string* statement, const zval* options) +connection_handle::analytics_query(zval* return_value, + const zend_string* statement, + const zval* options) { - couchbase::core::operations::analytics_request request{ cb_string_new(statement) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + couchbase::core::operations::analytics_request request{ cb_string_new(statement) }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + + if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { + if (scan_consistency == "notBounded") { + request.scan_consistency = core::analytics_scan_consistency::not_bounded; + } else if (scan_consistency == "requestPlus") { + request.scan_consistency = core::analytics_scan_consistency::request_plus; + } else if (scan_consistency) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for scan consistency: {}", *scan_consistency) }; + } + } else if (e.ec) { + return e; + } + + if (auto e = cb_assign_boolean(request.readonly, options, "readonly"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.priority, options, "priority"); e.ec) { + return e; + } + if (const zval* value = + zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("positionalParameters")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector params{}; + const zval* item = nullptr; - if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { - if (scan_consistency == "notBounded") { - request.scan_consistency = core::analytics_scan_consistency::not_bounded; - } else if (scan_consistency == "requestPlus") { - request.scan_consistency = core::analytics_scan_consistency::request_plus; - } else if (scan_consistency) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for scan consistency: {}", *scan_consistency) }; - } - } else if (e.ec) { - return e; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + params.emplace_back(std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) })); } + ZEND_HASH_FOREACH_END(); - if (auto e = cb_assign_boolean(request.readonly, options, "readonly"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.priority, options, "priority"); e.ec) { - return e; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("positionalParameters")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector params{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - params.emplace_back(std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) })); - } - ZEND_HASH_FOREACH_END(); + request.positional_parameters = params; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("namedParameters")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map params{}; + const zend_string* key = nullptr; + const zval* item = nullptr; - request.positional_parameters = params; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("namedParameters")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map params{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - } - ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_END(); - request.named_parameters = params; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map params{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - } - ZEND_HASH_FOREACH_END(); + request.named_parameters = params; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map params{}; + const zend_string* key = nullptr; + const zval* item = nullptr; - request.raw = params; - } - if (auto e = cb_assign_string(request.client_context_id, options, "clientContextId"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.bucket_name, options, "bucketName"); e.ec) { - return e; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); } + ZEND_HASH_FOREACH_END(); - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; + request.raw = params; + } + if (auto e = cb_assign_string(request.client_context_id, options, "clientContextId"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.bucket_name, options, "bucketName"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + + zval rows; + array_init(&rows); + for (const auto& row : resp.rows) { + add_next_index_stringl(&rows, row.data(), row.size()); + } + add_assoc_zval(return_value, "rows", &rows); + { + zval meta; + array_init(&meta); + add_assoc_string(&meta, "clientContextId", resp.meta.client_context_id.c_str()); + add_assoc_string(&meta, "requestId", resp.meta.request_id.c_str()); + add_assoc_string(&meta, "status", cb_analytics_status_str(resp.meta.status)); + if (resp.meta.signature.has_value()) { + add_assoc_string(&meta, "signature", resp.meta.signature.value().c_str()); } - array_init(return_value); - - zval rows; - array_init(&rows); - for (const auto& row : resp.rows) { - add_next_index_stringl(&rows, row.data(), row.size()); - } - add_assoc_zval(return_value, "rows", &rows); { - zval meta; - array_init(&meta); - add_assoc_string(&meta, "clientContextId", resp.meta.client_context_id.c_str()); - add_assoc_string(&meta, "requestId", resp.meta.request_id.c_str()); - add_assoc_string(&meta, "status", cb_analytics_status_str(resp.meta.status)); - if (resp.meta.signature.has_value()) { - add_assoc_string(&meta, "signature", resp.meta.signature.value().c_str()); - } - - { - zval metrics; - array_init(&metrics); - add_assoc_long(&metrics, "errorCount", resp.meta.metrics.error_count); - add_assoc_long(&metrics, "processedObjects", resp.meta.metrics.processed_objects); - add_assoc_long(&metrics, "resultCount", resp.meta.metrics.result_count); - add_assoc_long(&metrics, "resultSize", resp.meta.metrics.result_size); - add_assoc_long(&metrics, "warningCount", resp.meta.metrics.warning_count); - add_assoc_long( - &metrics, "elapsedTime", std::chrono::duration_cast(resp.meta.metrics.elapsed_time).count()); - add_assoc_long( - &metrics, "executionTime", std::chrono::duration_cast(resp.meta.metrics.execution_time).count()); - - add_assoc_zval(&meta, "metrics", &metrics); - } - - { - zval warnings; - array_init(&warnings); - for (const auto& w : resp.meta.warnings) { - zval warning; - array_init(&warning); + zval metrics; + array_init(&metrics); + add_assoc_long(&metrics, "errorCount", resp.meta.metrics.error_count); + add_assoc_long(&metrics, "processedObjects", resp.meta.metrics.processed_objects); + add_assoc_long(&metrics, "resultCount", resp.meta.metrics.result_count); + add_assoc_long(&metrics, "resultSize", resp.meta.metrics.result_size); + add_assoc_long(&metrics, "warningCount", resp.meta.metrics.warning_count); + add_assoc_long( + &metrics, + "elapsedTime", + std::chrono::duration_cast(resp.meta.metrics.elapsed_time) + .count()); + add_assoc_long( + &metrics, + "executionTime", + std::chrono::duration_cast(resp.meta.metrics.execution_time) + .count()); + + add_assoc_zval(&meta, "metrics", &metrics); + } - add_assoc_long(&warning, "code", w.code); - add_assoc_string(&warning, "code", w.message.c_str()); + { + zval warnings; + array_init(&warnings); + for (const auto& w : resp.meta.warnings) { + zval warning; + array_init(&warning); - add_next_index_zval(&warnings, &warning); - } - add_assoc_zval(return_value, "warnings", &warnings); - } + add_assoc_long(&warning, "code", w.code); + add_assoc_string(&warning, "code", w.message.c_str()); - add_assoc_zval(return_value, "meta", &meta); + add_next_index_zval(&warnings, &warning); + } + add_assoc_zval(return_value, "warnings", &warnings); } - return {}; + add_assoc_zval(return_value, "meta", &meta); + } + + return {}; } COUCHBASE_API @@ -2235,49 +2388,54 @@ connection_handle::search(zval* return_value, const zend_string* vector_search, const zval* vector_options) { - auto [request, e] = zval_to_common_search_request(index_name, query, options); - if (e.ec) { - return e; - } - - request.show_request = false; - request.vector_search = cb_string_new(vector_search); - - if (auto [e, vector_query_combination] = cb_get_string(vector_options, "vectorQueryCombination"); vector_query_combination) { - if (vector_query_combination == "or") { - request.vector_query_combination = core::vector_query_combination::combination_or; - } else if (vector_query_combination == "and") { - request.vector_query_combination = core::vector_query_combination::combination_and; - } else if (vector_query_combination) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for vector_query_combination: {}", *vector_query_combination) }; - } - } else if (e.ec) { - return e; + auto [request, e] = zval_to_common_search_request(index_name, query, options); + if (e.ec) { + return e; + } + + request.show_request = false; + request.vector_search = cb_string_new(vector_search); + + if (auto [e, vector_query_combination] = cb_get_string(vector_options, "vectorQueryCombination"); + vector_query_combination) { + if (vector_query_combination == "or") { + request.vector_query_combination = core::vector_query_combination::combination_or; + } else if (vector_query_combination == "and") { + request.vector_query_combination = core::vector_query_combination::combination_and; + } else if (vector_query_combination) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for vector_query_combination: {}", + *vector_query_combination) }; } + } else if (e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - search_query_response_to_zval(return_value, resp); - return {}; + search_query_response_to_zval(return_value, resp); + return {}; } COUCHBASE_API core_error_info -connection_handle::search_query(zval* return_value, const zend_string* index_name, const zend_string* query, const zval* options) +connection_handle::search_query(zval* return_value, + const zend_string* index_name, + const zend_string* query, + const zval* options) { - auto [request, e] = zval_to_common_search_request(index_name, query, options); - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - search_query_response_to_zval(return_value, resp); - return {}; + auto [request, e] = zval_to_common_search_request(index_name, query, options); + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + search_query_response_to_zval(return_value, resp); + return {}; } COUCHBASE_API @@ -2289,594 +2447,621 @@ connection_handle::view_query(zval* return_value, const zend_long name_space, const zval* options) { - core::design_document_namespace cxx_name_space; - switch (auto name_space_val = static_cast(name_space); name_space_val) { - case 1: - cxx_name_space = core::design_document_namespace::development; - break; - - case 2: - cxx_name_space = core::design_document_namespace::production; - break; - - default: - return { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("invalid value used for namespace: {}", name_space_val) }; + core::design_document_namespace cxx_name_space; + switch (auto name_space_val = static_cast(name_space); name_space_val) { + case 1: + cxx_name_space = core::design_document_namespace::development; + break; + + case 2: + cxx_name_space = core::design_document_namespace::production; + break; + + default: + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for namespace: {}", name_space_val) }; + } + + couchbase::core::operations::document_view_request request{ + cb_string_new(bucket_name), + cb_string_new(design_document_name), + cb_string_new(view_name), + cxx_name_space, + }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { + if (scan_consistency == "notBounded") { + request.consistency = core::view_scan_consistency::not_bounded; + } else if (scan_consistency == "requestPlus") { + request.consistency = core::view_scan_consistency::request_plus; + } else if (scan_consistency == "updateAfter") { + request.consistency = core::view_scan_consistency::update_after; + } else if (scan_consistency) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for scan consistency: {}", *scan_consistency) }; } + } else if (e.ec) { + return e; + } - couchbase::core::operations::document_view_request request{ - cb_string_new(bucket_name), - cb_string_new(design_document_name), - cb_string_new(view_name), - cxx_name_space, - }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { - if (scan_consistency == "notBounded") { - request.consistency = core::view_scan_consistency::not_bounded; - } else if (scan_consistency == "requestPlus") { - request.consistency = core::view_scan_consistency::request_plus; - } else if (scan_consistency == "updateAfter") { - request.consistency = core::view_scan_consistency::update_after; - } else if (scan_consistency) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for scan consistency: {}", *scan_consistency) }; - } - } else if (e.ec) { - return e; + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("keys")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector keys{}; + const zval* item = nullptr; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + keys.emplace_back(Z_STRVAL_P(item), Z_STRLEN_P(item)); } + ZEND_HASH_FOREACH_END(); - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("keys")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector keys{}; - const zval* item = nullptr; + request.keys = keys; + } + if (auto [e, order] = cb_get_string(options, "order"); order) { + if (order == "ascending") { + request.order = core::view_sort_order::ascending; + } else if (order == "descending") { + request.order = core::view_sort_order::descending; + } else if (order) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for order: {}", *order) }; + } + } else if (e.ec) { + return e; + } + // { + // const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); + // if (value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + // std::map values{}; + // const zend_string* key = nullptr; + // const zval *item = nullptr; + // + // ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + // { + // auto str = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); + // auto k = std::string({ ZSTR_VAL(key), ZSTR_LEN(key) }); + // values.emplace(k, std::move(str)); + // } + // ZEND_HASH_FOREACH_END(); + // + // request.raw = values; + // } + // } + if (auto e = cb_assign_boolean(request.reduce, options, "reduce"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.group, options, "group"); e.ec) { + return e; + } + if (auto e = cb_assign_integer(request.group_level, options, "groupLevel"); e.ec) { + return e; + } + if (auto e = cb_assign_integer(request.limit, options, "limit"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.skip, options, "skip"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.key, options, "key"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.start_key, options, "startKey"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.end_key, options, "endKey"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.start_key_doc_id, options, "startKeyDocId"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.end_key_doc_id, options, "endKeyDocId"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.inclusive_end, options, "inclusiveEnd"); e.ec) { + return e; + } + // if (auto e = cb_assign_integer(request.on_error, options, "onError"); e.ec) { + // return { nullptr, e }; + // } + if (auto e = cb_assign_boolean(request.debug, options, "debug"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + + zval rows; + array_init(&rows); + for (auto& row : resp.rows) { + zval zrow; + array_init(&zrow); + if (row.id.has_value()) { + add_assoc_string(&zrow, "id", row.id.value().c_str()); + } + add_assoc_string(&zrow, "value", row.value.c_str()); + add_assoc_string(&zrow, "key", row.key.c_str()); + + add_next_index_zval(&rows, &zrow); + } + add_assoc_zval(return_value, "rows", &rows); + + { + zval meta; + array_init(&meta); + if (resp.meta.debug_info.has_value()) { + add_assoc_string(&meta, "debugInfo", resp.meta.debug_info.value().c_str()); + } + if (resp.meta.total_rows.has_value()) { + add_assoc_long(&meta, "totalRows", resp.meta.total_rows.value()); + } + + add_assoc_zval(return_value, "meta", &meta); + } + + return {}; +} - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - keys.emplace_back(Z_STRVAL_P(item), Z_STRLEN_P(item)); - } - ZEND_HASH_FOREACH_END(); +COUCHBASE_API +core_error_info +connection_handle::ping(zval* return_value, const zval* options) +{ + std::optional report_id; + if (auto e = cb_assign_string(report_id, options, "reportId"); e.ec) { + return e; + } + std::optional bucket_name; + if (auto e = cb_assign_string(bucket_name, options, "bucketName"); e.ec) { + return e; + } + std::vector service_types; + if (auto e = cb_assign_vector_of_strings(service_types, options, "serviceTypes"); e.ec) { + return e; + } + std::set cb_services{}; + if (!service_types.empty()) { + for (const auto& service_type : service_types) { + if (service_type == "kv") { + cb_services.emplace(core::service_type::key_value); + } else if (service_type == "query") { + cb_services.emplace(core::service_type::query); + } else if (service_type == "analytics") { + cb_services.emplace(core::service_type::analytics); + } else if (service_type == "search") { + cb_services.emplace(core::service_type::search); + } else if (service_type == "views") { + cb_services.emplace(core::service_type::view); + } else if (service_type == "mgmt") { + cb_services.emplace(core::service_type::management); + } else if (service_type == "eventing") { + cb_services.emplace(core::service_type::eventing); + } else { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for service type: {}", service_type) }; + } + } + } + + auto [err, resp] = + impl_->ping(std::move(report_id), std::move(bucket_name), std::move(cb_services)); + if (err.ec) { + return { err }; + } + + array_init(return_value); + add_assoc_string(return_value, "id", resp.id.c_str()); + add_assoc_string(return_value, "sdk", resp.sdk.c_str()); + add_assoc_long(return_value, "version", resp.version); + + zval services; + array_init(&services); + for (const auto& [service_type, service_infos] : resp.services) { + std::string type_str; + switch (service_type) { + case core::service_type::key_value: + type_str = "kv"; + break; + case core::service_type::query: + type_str = "query"; + break; + case core::service_type::analytics: + type_str = "analytics"; + break; + case core::service_type::search: + type_str = "search"; + break; + case core::service_type::view: + type_str = "views"; + break; + case core::service_type::management: + type_str = "mgmt"; + break; + case core::service_type::eventing: + type_str = "eventing"; + break; + } + + zval endpoints; + array_init(&endpoints); + for (const auto& svc : service_infos) { + zval endpoint; + array_init(&endpoint); + add_assoc_string(&endpoint, "id", svc.id.c_str()); + add_assoc_string(&endpoint, "remote", svc.remote.c_str()); + add_assoc_string(&endpoint, "local", svc.local.c_str()); + add_assoc_long(&endpoint, "latencyUs", svc.latency.count()); + std::string state; + switch (svc.state) { + case core::diag::ping_state::ok: + state = "ok"; + break; + case core::diag::ping_state::timeout: + state = "timeout"; + break; + case core::diag::ping_state::error: + state = "error"; + break; + } + add_assoc_string(&endpoint, "state", state.c_str()); + if (svc.bucket) { + add_assoc_string(&endpoint, "bucket", svc.bucket->c_str()); + } + if (svc.error) { + add_assoc_string(&endpoint, "error", svc.error->c_str()); + } + add_next_index_zval(&endpoints, &endpoint); + } + add_assoc_zval(&services, type_str.c_str(), &endpoints); + } + add_assoc_zval(return_value, "services", &services); + + return {}; +} - request.keys = keys; - } - if (auto [e, order] = cb_get_string(options, "order"); order) { - if (order == "ascending") { - request.order = core::view_sort_order::ascending; - } else if (order == "descending") { - request.order = core::view_sort_order::descending; - } else if (order) { - return { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("invalid value used for order: {}", *order) }; - } - } else if (e.ec) { - return e; - } - // { - // const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); - // if (value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - // std::map values{}; - // const zend_string* key = nullptr; - // const zval *item = nullptr; - // - // ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - // { - // auto str = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - // auto k = std::string({ ZSTR_VAL(key), ZSTR_LEN(key) }); - // values.emplace(k, std::move(str)); - // } - // ZEND_HASH_FOREACH_END(); - // - // request.raw = values; - // } - // } - if (auto e = cb_assign_boolean(request.reduce, options, "reduce"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.group, options, "group"); e.ec) { - return e; - } - if (auto e = cb_assign_integer(request.group_level, options, "groupLevel"); e.ec) { - return e; - } - if (auto e = cb_assign_integer(request.limit, options, "limit"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.skip, options, "skip"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.key, options, "key"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.start_key, options, "startKey"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.end_key, options, "endKey"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.start_key_doc_id, options, "startKeyDocId"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.end_key_doc_id, options, "endKeyDocId"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.inclusive_end, options, "inclusiveEnd"); e.ec) { - return e; - } - // if (auto e = cb_assign_integer(request.on_error, options, "onError"); e.ec) { - // return { nullptr, e }; - // } - if (auto e = cb_assign_boolean(request.debug, options, "debug"); e.ec) { - return e; - } +COUCHBASE_API +core_error_info +connection_handle::diagnostics(zval* return_value, + const zend_string* report_id, + const zval* /* options */) +{ + auto [err, resp] = impl_->diagnostics(cb_string_new(report_id)); + if (err.ec) { + return { err }; + } + + array_init(return_value); + add_assoc_string(return_value, "id", resp.id.c_str()); + add_assoc_string(return_value, "sdk", resp.sdk.c_str()); + add_assoc_long(return_value, "version", resp.version); + + zval services; + array_init(&services); + for (const auto& [service_type, service_infos] : resp.services) { + std::string type_str; + switch (service_type) { + case core::service_type::key_value: + type_str = "kv"; + break; + case core::service_type::query: + type_str = "query"; + break; + case core::service_type::analytics: + type_str = "analytics"; + break; + case core::service_type::search: + type_str = "search"; + break; + case core::service_type::view: + type_str = "views"; + break; + case core::service_type::management: + type_str = "mgmt"; + break; + case core::service_type::eventing: + type_str = "eventing"; + break; + } + + zval endpoints; + array_init(&endpoints); + for (const auto& svc : service_infos) { + zval endpoint; + array_init(&endpoint); + if (svc.last_activity) { + add_assoc_long(&endpoint, "lastActivityUs", svc.last_activity->count()); + } + add_assoc_string(&endpoint, "id", svc.id.c_str()); + add_assoc_string(&endpoint, "remote", svc.remote.c_str()); + add_assoc_string(&endpoint, "local", svc.local.c_str()); + std::string state; + switch (svc.state) { + case core::diag::endpoint_state::disconnected: + state = "disconnected"; + break; + case core::diag::endpoint_state::connecting: + state = "connecting"; + break; + case core::diag::endpoint_state::connected: + state = "connected"; + break; + case core::diag::endpoint_state::disconnecting: + state = "disconnecting"; + break; + } + add_assoc_string(&endpoint, "state", state.c_str()); + if (svc.details) { + add_assoc_string(&endpoint, "details", svc.details->c_str()); + } + add_next_index_zval(&endpoints, &endpoint); + } + add_assoc_zval(&services, type_str.c_str(), &endpoints); + } + add_assoc_zval(return_value, "services", &services); + + return {}; +} - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } +COUCHBASE_API +core_error_info +cb_search_index_to_zval(zval* return_value, const couchbase::core::management::search::index& index) +{ + array_init(return_value); + + add_assoc_string(return_value, "uuid", index.uuid.c_str()); + add_assoc_string(return_value, "name", index.name.c_str()); + add_assoc_string(return_value, "type", index.type.c_str()); + add_assoc_string(return_value, "params_json", index.params_json.c_str()); + add_assoc_string(return_value, "source_uuid", index.source_uuid.c_str()); + add_assoc_string(return_value, "source_name", index.source_name.c_str()); + add_assoc_string(return_value, "source_type", index.source_type.c_str()); + add_assoc_string(return_value, "source_params_json", index.source_params_json.c_str()); + add_assoc_string(return_value, "plan_params_json", index.plan_params_json.c_str()); + + return {}; +} - array_init(return_value); +COUCHBASE_API +core_error_info +zval_to_search_index(couchbase::core::operations::management::search_index_upsert_request& request, + const zval* index) +{ + couchbase::core::management::search::index idx{}; + if (auto e = cb_assign_string(idx.name, index, "name"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.type, index, "type"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.uuid, index, "uuid"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.params_json, index, "params"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.source_uuid, index, "sourceUuid"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.source_name, index, "sourceName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.source_type, index, "sourceType"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.source_params_json, index, "sourceParams"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.plan_params_json, index, "planParams"); e.ec) { + return e; + } + request.index = idx; + + return {}; +} - zval rows; - array_init(&rows); - for (auto& row : resp.rows) { - zval zrow; - array_init(&zrow); - if (row.id.has_value()) { - add_assoc_string(&zrow, "id", row.id.value().c_str()); - } - add_assoc_string(&zrow, "value", row.value.c_str()); - add_assoc_string(&zrow, "key", row.key.c_str()); +COUCHBASE_API +core_error_info +connection_handle::search_index_get(zval* return_value, + const zend_string* index_name, + const zval* options) +{ + couchbase::core::operations::management::search_index_get_request request{ cb_string_new( + index_name) }; - add_next_index_zval(&rows, &zrow); - } - add_assoc_zval(return_value, "rows", &rows); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - { - zval meta; - array_init(&meta); - if (resp.meta.debug_info.has_value()) { - add_assoc_string(&meta, "debugInfo", resp.meta.debug_info.value().c_str()); - } - if (resp.meta.total_rows.has_value()) { - add_assoc_long(&meta, "totalRows", resp.meta.total_rows.value()); - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - add_assoc_zval(return_value, "meta", &meta); - } + if (auto e = cb_search_index_to_zval(return_value, resp.index); e.ec) { + return e; + } - return {}; + return {}; } COUCHBASE_API core_error_info -connection_handle::ping(zval* return_value, const zval* options) +connection_handle::search_index_get_all(zval* return_value, const zval* options) { - std::optional report_id; - if (auto e = cb_assign_string(report_id, options, "reportId"); e.ec) { - return e; - } - std::optional bucket_name; - if (auto e = cb_assign_string(bucket_name, options, "bucketName"); e.ec) { - return e; - } - std::vector service_types; - if (auto e = cb_assign_vector_of_strings(service_types, options, "serviceTypes"); e.ec) { - return e; - } - std::set cb_services{}; - if (!service_types.empty()) { - for (const auto& service_type : service_types) { - if (service_type == "kv") { - cb_services.emplace(core::service_type::key_value); - } else if (service_type == "query") { - cb_services.emplace(core::service_type::query); - } else if (service_type == "analytics") { - cb_services.emplace(core::service_type::analytics); - } else if (service_type == "search") { - cb_services.emplace(core::service_type::search); - } else if (service_type == "views") { - cb_services.emplace(core::service_type::view); - } else if (service_type == "mgmt") { - cb_services.emplace(core::service_type::management); - } else if (service_type == "eventing") { - cb_services.emplace(core::service_type::eventing); - } else { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for service type: {}", service_type) }; - } - } - } + couchbase::core::operations::management::search_index_get_all_request request{}; - auto [err, resp] = impl_->ping(std::move(report_id), std::move(bucket_name), std::move(cb_services)); - if (err.ec) { - return { err }; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - array_init(return_value); - add_assoc_string(return_value, "id", resp.id.c_str()); - add_assoc_string(return_value, "sdk", resp.sdk.c_str()); - add_assoc_long(return_value, "version", resp.version); - - zval services; - array_init(&services); - for (const auto& [service_type, service_infos] : resp.services) { - std::string type_str; - switch (service_type) { - case core::service_type::key_value: - type_str = "kv"; - break; - case core::service_type::query: - type_str = "query"; - break; - case core::service_type::analytics: - type_str = "analytics"; - break; - case core::service_type::search: - type_str = "search"; - break; - case core::service_type::view: - type_str = "views"; - break; - case core::service_type::management: - type_str = "mgmt"; - break; - case core::service_type::eventing: - type_str = "eventing"; - break; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - zval endpoints; - array_init(&endpoints); - for (const auto& svc : service_infos) { - zval endpoint; - array_init(&endpoint); - add_assoc_string(&endpoint, "id", svc.id.c_str()); - add_assoc_string(&endpoint, "remote", svc.remote.c_str()); - add_assoc_string(&endpoint, "local", svc.local.c_str()); - add_assoc_long(&endpoint, "latencyUs", svc.latency.count()); - std::string state; - switch (svc.state) { - case core::diag::ping_state::ok: - state = "ok"; - break; - case core::diag::ping_state::timeout: - state = "timeout"; - break; - case core::diag::ping_state::error: - state = "error"; - break; - } - add_assoc_string(&endpoint, "state", state.c_str()); - if (svc.bucket) { - add_assoc_string(&endpoint, "bucket", svc.bucket->c_str()); - } - if (svc.error) { - add_assoc_string(&endpoint, "error", svc.error->c_str()); - } - add_next_index_zval(&endpoints, &endpoint); - } - add_assoc_zval(&services, type_str.c_str(), &endpoints); + array_init(return_value); + for (const auto& search_index : resp.indexes) { + zval this_index; + if (auto e = cb_search_index_to_zval(&this_index, search_index); e.ec) { + return e; } - add_assoc_zval(return_value, "services", &services); + add_next_index_zval(return_value, &this_index); + } - return {}; + return {}; } COUCHBASE_API core_error_info -connection_handle::diagnostics(zval* return_value, const zend_string* report_id, const zval* /* options */) +connection_handle::search_index_upsert(zval* return_value, const zval* index, const zval* options) { - auto [err, resp] = impl_->diagnostics(cb_string_new(report_id)); - if (err.ec) { - return { err }; - } + couchbase::core::operations::management::search_index_upsert_request request{}; - array_init(return_value); - add_assoc_string(return_value, "id", resp.id.c_str()); - add_assoc_string(return_value, "sdk", resp.sdk.c_str()); - add_assoc_long(return_value, "version", resp.version); - - zval services; - array_init(&services); - for (const auto& [service_type, service_infos] : resp.services) { - std::string type_str; - switch (service_type) { - case core::service_type::key_value: - type_str = "kv"; - break; - case core::service_type::query: - type_str = "query"; - break; - case core::service_type::analytics: - type_str = "analytics"; - break; - case core::service_type::search: - type_str = "search"; - break; - case core::service_type::view: - type_str = "views"; - break; - case core::service_type::management: - type_str = "mgmt"; - break; - case core::service_type::eventing: - type_str = "eventing"; - break; - } + if (auto e = zval_to_search_index(request, index); e.ec) { + return e; + } - zval endpoints; - array_init(&endpoints); - for (const auto& svc : service_infos) { - zval endpoint; - array_init(&endpoint); - if (svc.last_activity) { - add_assoc_long(&endpoint, "lastActivityUs", svc.last_activity->count()); - } - add_assoc_string(&endpoint, "id", svc.id.c_str()); - add_assoc_string(&endpoint, "remote", svc.remote.c_str()); - add_assoc_string(&endpoint, "local", svc.local.c_str()); - std::string state; - switch (svc.state) { - case core::diag::endpoint_state::disconnected: - state = "disconnected"; - break; - case core::diag::endpoint_state::connecting: - state = "connecting"; - break; - case core::diag::endpoint_state::connected: - state = "connected"; - break; - case core::diag::endpoint_state::disconnecting: - state = "disconnecting"; - break; - } - add_assoc_string(&endpoint, "state", state.c_str()); - if (svc.details) { - add_assoc_string(&endpoint, "details", svc.details->c_str()); - } - add_next_index_zval(&endpoints, &endpoint); - } - add_assoc_zval(&services, type_str.c_str(), &endpoints); - } - add_assoc_zval(return_value, "services", &services); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - return {}; + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + add_assoc_string(return_value, "status", resp.status.c_str()); + add_assoc_string(return_value, "error", resp.error.c_str()); + + return {}; } COUCHBASE_API core_error_info -cb_search_index_to_zval(zval* return_value, const couchbase::core::management::search::index& index) +connection_handle::search_index_drop(zval* return_value, + const zend_string* index_name, + const zval* options) { - array_init(return_value); + couchbase::core::operations::management::search_index_drop_request request{ cb_string_new( + index_name) }; - add_assoc_string(return_value, "uuid", index.uuid.c_str()); - add_assoc_string(return_value, "name", index.name.c_str()); - add_assoc_string(return_value, "type", index.type.c_str()); - add_assoc_string(return_value, "params_json", index.params_json.c_str()); - add_assoc_string(return_value, "source_uuid", index.source_uuid.c_str()); - add_assoc_string(return_value, "source_name", index.source_name.c_str()); - add_assoc_string(return_value, "source_type", index.source_type.c_str()); - add_assoc_string(return_value, "source_params_json", index.source_params_json.c_str()); - add_assoc_string(return_value, "plan_params_json", index.plan_params_json.c_str()); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - return {}; + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -zval_to_search_index(couchbase::core::operations::management::search_index_upsert_request& request, const zval* index) +connection_handle::search_index_get_documents_count(zval* return_value, + const zend_string* index_name, + const zval* options) { - couchbase::core::management::search::index idx{}; - if (auto e = cb_assign_string(idx.name, index, "name"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.type, index, "type"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.uuid, index, "uuid"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.params_json, index, "params"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.source_uuid, index, "sourceUuid"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.source_name, index, "sourceName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.source_type, index, "sourceType"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.source_params_json, index, "sourceParams"); e.ec) { - return e; - } - if (auto e = cb_assign_string(idx.plan_params_json, index, "planParams"); e.ec) { - return e; - } - request.index = idx; - - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::search_index_get(zval* return_value, const zend_string* index_name, const zval* options) -{ - couchbase::core::operations::management::search_index_get_request request{ cb_string_new(index_name) }; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - if (auto e = cb_search_index_to_zval(return_value, resp.index); e.ec) { - return e; - } - - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::search_index_get_all(zval* return_value, const zval* options) -{ - couchbase::core::operations::management::search_index_get_all_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - for (const auto& search_index : resp.indexes) { - zval this_index; - if (auto e = cb_search_index_to_zval(&this_index, search_index); e.ec) { - return e; - } - add_next_index_zval(return_value, &this_index); - } - - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::search_index_upsert(zval* return_value, const zval* index, const zval* options) -{ - couchbase::core::operations::management::search_index_upsert_request request{}; - - if (auto e = zval_to_search_index(request, index); e.ec) { - return e; - } - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - add_assoc_string(return_value, "status", resp.status.c_str()); - add_assoc_string(return_value, "error", resp.error.c_str()); - - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::search_index_drop(zval* return_value, const zend_string* index_name, const zval* options) -{ - couchbase::core::operations::management::search_index_drop_request request{ cb_string_new(index_name) }; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::search_index_get_documents_count(zval* return_value, const zend_string* index_name, const zval* options) -{ - couchbase::core::operations::management::search_index_get_documents_count_request request{ cb_string_new(index_name) }; + couchbase::core::operations::management::search_index_get_documents_count_request request{ + cb_string_new(index_name) + }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - add_assoc_long(return_value, "count", resp.count); + array_init(return_value); + add_assoc_long(return_value, "count", resp.count); - return {}; + return {}; } COUCHBASE_API core_error_info -connection_handle::search_index_control_ingest(zval* return_value, const zend_string* index_name, bool pause, const zval* options) +connection_handle::search_index_control_ingest(zval* return_value, + const zend_string* index_name, + bool pause, + const zval* options) { - couchbase::core::operations::management::search_index_control_ingest_request request{}; - request.index_name = cb_string_new(index_name); - request.pause = pause; + couchbase::core::operations::management::search_index_control_ingest_request request{}; + request.index_name = cb_string_new(index_name); + request.pause = pause; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::search_index_control_query(zval* return_value, const zend_string* index_name, bool allow, const zval* options) +connection_handle::search_index_control_query(zval* return_value, + const zend_string* index_name, + bool allow, + const zval* options) { - couchbase::core::operations::management::search_index_control_query_request request{}; - request.index_name = cb_string_new(index_name); - request.allow = allow; + couchbase::core::operations::management::search_index_control_query_request request{}; + request.index_name = cb_string_new(index_name); + request.allow = allow; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::search_index_control_plan_freeze(zval* return_value, const zend_string* index_name, bool freeze, const zval* options) +connection_handle::search_index_control_plan_freeze(zval* return_value, + const zend_string* index_name, + bool freeze, + const zval* options) { - couchbase::core::operations::management::search_index_control_plan_freeze_request request{}; - request.index_name = cb_string_new(index_name); - request.freeze = freeze; + couchbase::core::operations::management::search_index_control_plan_freeze_request request{}; + request.index_name = cb_string_new(index_name); + request.freeze = freeze; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -2886,23 +3071,23 @@ connection_handle::search_index_analyze_document(zval* return_value, const zend_string* document, const zval* options) { - couchbase::core::operations::management::search_index_analyze_document_request request{}; - request.index_name = cb_string_new(index_name); - request.encoded_document = cb_string_new(document); + couchbase::core::operations::management::search_index_analyze_document_request request{}; + request.index_name = cb_string_new(index_name); + request.encoded_document = cb_string_new(document); - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - add_assoc_string(return_value, "analysis", resp.analysis.c_str()); + array_init(return_value); + add_assoc_string(return_value, "analysis", resp.analysis.c_str()); - return {}; + return {}; } COUCHBASE_API @@ -2913,25 +3098,26 @@ connection_handle::scope_search_index_get(zval* return_value, const zend_string* index_name, const zval* options) { - couchbase::core::operations::management::search_index_get_request request{ cb_string_new(index_name) }; + couchbase::core::operations::management::search_index_get_request request{ cb_string_new( + index_name) }; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - if (auto e = cb_search_index_to_zval(return_value, resp.index); e.ec) { - return e; - } + if (auto e = cb_search_index_to_zval(return_value, resp.index); e.ec) { + return e; + } - return {}; + return {}; } COUCHBASE_API @@ -2941,30 +3127,30 @@ connection_handle::scope_search_index_get_all(zval* return_value, const zend_string* scope_name, const zval* options) { - couchbase::core::operations::management::search_index_get_all_request request{}; + couchbase::core::operations::management::search_index_get_all_request request{}; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - for (const auto& search_index : resp.indexes) { - zval this_index; - if (auto e = cb_search_index_to_zval(&this_index, search_index); e.ec) { - return e; - } - add_next_index_zval(return_value, &this_index); + array_init(return_value); + for (const auto& search_index : resp.indexes) { + zval this_index; + if (auto e = cb_search_index_to_zval(&this_index, search_index); e.ec) { + return e; } + add_next_index_zval(return_value, &this_index); + } - return {}; + return {}; } COUCHBASE_API @@ -2975,29 +3161,29 @@ connection_handle::scope_search_index_upsert(zval* return_value, const zval* index, const zval* options) { - couchbase::core::operations::management::search_index_upsert_request request{}; + couchbase::core::operations::management::search_index_upsert_request request{}; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - if (auto e = zval_to_search_index(request, index); e.ec) { - return e; - } + if (auto e = zval_to_search_index(request, index); e.ec) { + return e; + } - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - add_assoc_string(return_value, "status", resp.status.c_str()); - add_assoc_string(return_value, "error", resp.error.c_str()); + array_init(return_value); + add_assoc_string(return_value, "status", resp.status.c_str()); + add_assoc_string(return_value, "error", resp.error.c_str()); - return {}; + return {}; } COUCHBASE_API @@ -3008,22 +3194,23 @@ connection_handle::scope_search_index_drop(zval* return_value, const zend_string* index_name, const zval* options) { - couchbase::core::operations::management::search_index_drop_request request{ cb_string_new(index_name) }; + couchbase::core::operations::management::search_index_drop_request request{ cb_string_new( + index_name) }; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -3034,24 +3221,26 @@ connection_handle::scope_search_index_get_documents_count(zval* return_value, const zend_string* index_name, const zval* options) { - couchbase::core::operations::management::search_index_get_documents_count_request request{ cb_string_new(index_name) }; + couchbase::core::operations::management::search_index_get_documents_count_request request{ + cb_string_new(index_name) + }; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - add_assoc_long(return_value, "count", resp.count); + array_init(return_value); + add_assoc_long(return_value, "count", resp.count); - return {}; + return {}; } COUCHBASE_API @@ -3063,25 +3252,25 @@ connection_handle::scope_search_index_control_ingest(zval* return_value, bool pause, const zval* options) { - couchbase::core::operations::management::search_index_control_ingest_request request{}; + couchbase::core::operations::management::search_index_control_ingest_request request{}; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - request.index_name = cb_string_new(index_name); - request.pause = pause; + request.index_name = cb_string_new(index_name); + request.pause = pause; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -3093,25 +3282,25 @@ connection_handle::scope_search_index_control_query(zval* return_value, bool allow, const zval* options) { - couchbase::core::operations::management::search_index_control_query_request request{}; + couchbase::core::operations::management::search_index_control_query_request request{}; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - request.index_name = cb_string_new(index_name); - request.allow = allow; + request.index_name = cb_string_new(index_name); + request.allow = allow; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -3123,25 +3312,25 @@ connection_handle::scope_search_index_control_plan_freeze(zval* return_value, bool freeze, const zval* options) { - couchbase::core::operations::management::search_index_control_plan_freeze_request request{}; + couchbase::core::operations::management::search_index_control_plan_freeze_request request{}; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - request.index_name = cb_string_new(index_name); - request.freeze = freeze; + request.index_name = cb_string_new(index_name); + request.freeze = freeze; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -3153,27 +3342,27 @@ connection_handle::scope_search_index_analyze_document(zval* return_value, const zend_string* document, const zval* options) { - couchbase::core::operations::management::search_index_analyze_document_request request{}; + couchbase::core::operations::management::search_index_analyze_document_request request{}; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - request.index_name = cb_string_new(index_name); - request.encoded_document = cb_string_new(document); + request.index_name = cb_string_new(index_name); + request.encoded_document = cb_string_new(document); - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - add_assoc_string(return_value, "analysis", resp.analysis.c_str()); + array_init(return_value); + add_assoc_string(return_value, "analysis", resp.analysis.c_str()); - return {}; + return {}; } COUCHBASE_API @@ -3184,553 +3373,595 @@ connection_handle::view_index_upsert(zval* return_value, zend_long name_space, const zval* options) { - couchbase::core::management::views::design_document idx{}; - if (auto e = cb_assign_string(idx.name, design_document, "name"); e.ec) { + couchbase::core::management::views::design_document idx{}; + if (auto e = cb_assign_string(idx.name, design_document, "name"); e.ec) { + return e; + } + if (auto e = cb_assign_string(idx.rev, design_document, "rev"); e.ec) { + return e; + } + switch (name_space) { + case 1: + idx.ns = core::design_document_namespace::development; + break; + + case 2: + idx.ns = core::design_document_namespace::production; + break; + + default: + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for namespace: {}", name_space) }; + } + + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(design_document), ZEND_STRL("views")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map views{}; + const zend_string* key = nullptr; + const zval* item = nullptr; + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + couchbase::core::management::views::design_document::view view{}; + if (auto e = cb_assign_string(view.name, item, "name"); e.ec) { return e; - } - if (auto e = cb_assign_string(idx.rev, design_document, "rev"); e.ec) { + } + if (auto e = cb_assign_string(view.map, item, "map"); e.ec) { return e; - } - switch (name_space) { - case 1: - idx.ns = core::design_document_namespace::development; - break; - - case 2: - idx.ns = core::design_document_namespace::production; - break; + } + if (auto e = cb_assign_string(view.reduce, item, "reduce"); e.ec) { + return e; + } - default: - return { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("invalid value used for namespace: {}", name_space) }; + views[cb_string_new(key)] = view; } + ZEND_HASH_FOREACH_END(); - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(design_document), ZEND_STRL("views")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map views{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - couchbase::core::management::views::design_document::view view{}; - if (auto e = cb_assign_string(view.name, item, "name"); e.ec) { - return e; - } - if (auto e = cb_assign_string(view.map, item, "map"); e.ec) { - return e; - } - if (auto e = cb_assign_string(view.reduce, item, "reduce"); e.ec) { - return e; - } - - views[cb_string_new(key)] = view; - } - ZEND_HASH_FOREACH_END(); - - idx.views = views; - } + idx.views = views; + } - couchbase::core::operations::management::view_index_upsert_request request{ cb_string_new(bucket_name), idx }; + couchbase::core::operations::management::view_index_upsert_request request{ + cb_string_new(bucket_name), idx + }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); + array_init(return_value); - return {}; + return {}; } static std::pair zval_to_bucket_settings(const zval* bucket_settings) { - couchbase::core::management::cluster::bucket_settings bucket{}; - if (auto e = cb_assign_string(bucket.name, bucket_settings, "name"); e.ec) { - return { e, {} }; - } - if (auto [e, bucket_type] = cb_get_string(bucket_settings, "bucketType"); bucket_type) { - if (bucket_type == "couchbase") { - bucket.bucket_type = couchbase::core::management::cluster::bucket_type::couchbase; - } else if (bucket_type == "ephemeral") { - bucket.bucket_type = couchbase::core::management::cluster::bucket_type::ephemeral; - } else if (bucket_type == "memcached") { - bucket.bucket_type = couchbase::core::management::cluster::bucket_type::memcached; - } else if (bucket_type) { - return { - { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("invalid value used for bucket type: {}", *bucket_type) }, {} - }; - } - } else if (e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_integer(bucket.ram_quota_mb, bucket_settings, "ramQuotaMB"); e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_integer(bucket.max_expiry, bucket_settings, "maxExpiry"); e.ec) { - return { e, {} }; - } - if (auto [e, compression_mode] = cb_get_string(bucket_settings, "compressionMode"); compression_mode) { - if (compression_mode == "off") { - bucket.compression_mode = couchbase::core::management::cluster::bucket_compression::off; - } else if (compression_mode == "active") { - bucket.compression_mode = couchbase::core::management::cluster::bucket_compression::active; - } else if (compression_mode == "passive") { - bucket.compression_mode = couchbase::core::management::cluster::bucket_compression::passive; - } else if (compression_mode) { - return { { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for compression mode: {}", *compression_mode) }, - {} }; - } - } else if (e.ec) { - return { e, {} }; - } - if (auto [e, durability_level] = cb_get_string(bucket_settings, "minimumDurabilityLevel"); durability_level) { - if (durability_level == "none") { - bucket.minimum_durability_level = durability_level::none; - } else if (durability_level == "majority") { - bucket.minimum_durability_level = durability_level::majority; - } else if (durability_level == "majorityAndPersistToActive") { - bucket.minimum_durability_level = durability_level::majority_and_persist_to_active; - } else if (durability_level == "persistToMajority") { - bucket.minimum_durability_level = durability_level::persist_to_majority; - } else if (durability_level) { - return { { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for durability level: {}", *durability_level) }, - {} }; - } - } else if (e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_integer(bucket.num_replicas, bucket_settings, "numReplicas"); e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_boolean(bucket.replica_indexes, bucket_settings, "replicaIndexes"); e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_boolean(bucket.flush_enabled, bucket_settings, "flushEnabled"); e.ec) { - return { e, {} }; - } - if (auto [e, eviction_policy] = cb_get_string(bucket_settings, "evictionPolicy"); eviction_policy) { - if (eviction_policy == "noEviction") { - bucket.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::no_eviction; - } else if (eviction_policy == "fullEviction") { - bucket.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::full; - } else if (eviction_policy == "valueOnly") { - bucket.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::value_only; - } else if (eviction_policy == "nruEviction") { - bucket.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used; - } else if (eviction_policy) { - return { { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for eviction policy: {}", *eviction_policy) }, - {} }; - } - } else if (e.ec) { - return { e, {} }; - } - if (auto [e, resolution_type] = cb_get_string(bucket_settings, "conflictResolutionType"); resolution_type) { - if (resolution_type == "sequenceNumber") { - bucket.conflict_resolution_type = couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number; - } else if (resolution_type == "timestamp") { - bucket.conflict_resolution_type = couchbase::core::management::cluster::bucket_conflict_resolution::timestamp; - } else if (resolution_type == "custom") { - bucket.conflict_resolution_type = couchbase::core::management::cluster::bucket_conflict_resolution::custom; - } else if (resolution_type) { - return { { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for custom resolution type: {}", *resolution_type) }, - {} }; - } - } else if (e.ec) { - return { e, {} }; - } - if (auto [e, storage_backend] = cb_get_string(bucket_settings, "storageBackend"); storage_backend) { - if (storage_backend == "couchstore") { - bucket.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::couchstore; - } else if (storage_backend == "magma") { - bucket.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::magma; - } else if (storage_backend) { - return { { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for storage backend: {}", *storage_backend) }, - {} }; - } - } else if (e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_boolean(bucket.history_retention_collection_default, bucket_settings, "historyRetentionCollectionDefault"); - e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_integer(bucket.history_retention_bytes, bucket_settings, "historyRetentionBytes"); e.ec) { - return { e, {} }; - } - if (auto e = cb_assign_integer(bucket.history_retention_duration, bucket_settings, "historyRetentionDuration"); e.ec) { - return { e, {} }; - } - - return { {}, bucket }; + couchbase::core::management::cluster::bucket_settings bucket{}; + if (auto e = cb_assign_string(bucket.name, bucket_settings, "name"); e.ec) { + return { e, {} }; + } + if (auto [e, bucket_type] = cb_get_string(bucket_settings, "bucketType"); bucket_type) { + if (bucket_type == "couchbase") { + bucket.bucket_type = couchbase::core::management::cluster::bucket_type::couchbase; + } else if (bucket_type == "ephemeral") { + bucket.bucket_type = couchbase::core::management::cluster::bucket_type::ephemeral; + } else if (bucket_type == "memcached") { + bucket.bucket_type = couchbase::core::management::cluster::bucket_type::memcached; + } else if (bucket_type) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for bucket type: {}", *bucket_type) }, + {} }; + } + } else if (e.ec) { + return { e, {} }; + } + if (auto e = cb_assign_integer(bucket.ram_quota_mb, bucket_settings, "ramQuotaMB"); e.ec) { + return { e, {} }; + } + if (auto e = cb_assign_integer(bucket.max_expiry, bucket_settings, "maxExpiry"); e.ec) { + return { e, {} }; + } + if (auto [e, compression_mode] = cb_get_string(bucket_settings, "compressionMode"); + compression_mode) { + if (compression_mode == "off") { + bucket.compression_mode = couchbase::core::management::cluster::bucket_compression::off; + } else if (compression_mode == "active") { + bucket.compression_mode = couchbase::core::management::cluster::bucket_compression::active; + } else if (compression_mode == "passive") { + bucket.compression_mode = couchbase::core::management::cluster::bucket_compression::passive; + } else if (compression_mode) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for compression mode: {}", *compression_mode) }, + {} }; + } + } else if (e.ec) { + return { e, {} }; + } + if (auto [e, durability_level] = cb_get_string(bucket_settings, "minimumDurabilityLevel"); + durability_level) { + if (durability_level == "none") { + bucket.minimum_durability_level = durability_level::none; + } else if (durability_level == "majority") { + bucket.minimum_durability_level = durability_level::majority; + } else if (durability_level == "majorityAndPersistToActive") { + bucket.minimum_durability_level = durability_level::majority_and_persist_to_active; + } else if (durability_level == "persistToMajority") { + bucket.minimum_durability_level = durability_level::persist_to_majority; + } else if (durability_level) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for durability level: {}", *durability_level) }, + {} }; + } + } else if (e.ec) { + return { e, {} }; + } + if (auto e = cb_assign_integer(bucket.num_replicas, bucket_settings, "numReplicas"); e.ec) { + return { e, {} }; + } + if (auto e = cb_assign_boolean(bucket.replica_indexes, bucket_settings, "replicaIndexes"); e.ec) { + return { e, {} }; + } + if (auto e = cb_assign_boolean(bucket.flush_enabled, bucket_settings, "flushEnabled"); e.ec) { + return { e, {} }; + } + if (auto [e, eviction_policy] = cb_get_string(bucket_settings, "evictionPolicy"); + eviction_policy) { + if (eviction_policy == "noEviction") { + bucket.eviction_policy = + couchbase::core::management::cluster::bucket_eviction_policy::no_eviction; + } else if (eviction_policy == "fullEviction") { + bucket.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::full; + } else if (eviction_policy == "valueOnly") { + bucket.eviction_policy = + couchbase::core::management::cluster::bucket_eviction_policy::value_only; + } else if (eviction_policy == "nruEviction") { + bucket.eviction_policy = + couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used; + } else if (eviction_policy) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for eviction policy: {}", *eviction_policy) }, + {} }; + } + } else if (e.ec) { + return { e, {} }; + } + if (auto [e, resolution_type] = cb_get_string(bucket_settings, "conflictResolutionType"); + resolution_type) { + if (resolution_type == "sequenceNumber") { + bucket.conflict_resolution_type = + couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number; + } else if (resolution_type == "timestamp") { + bucket.conflict_resolution_type = + couchbase::core::management::cluster::bucket_conflict_resolution::timestamp; + } else if (resolution_type == "custom") { + bucket.conflict_resolution_type = + couchbase::core::management::cluster::bucket_conflict_resolution::custom; + } else if (resolution_type) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for custom resolution type: {}", + *resolution_type) }, + {} }; + } + } else if (e.ec) { + return { e, {} }; + } + if (auto [e, storage_backend] = cb_get_string(bucket_settings, "storageBackend"); + storage_backend) { + if (storage_backend == "couchstore") { + bucket.storage_backend = + couchbase::core::management::cluster::bucket_storage_backend::couchstore; + } else if (storage_backend == "magma") { + bucket.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::magma; + } else if (storage_backend) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for storage backend: {}", *storage_backend) }, + {} }; + } + } else if (e.ec) { + return { e, {} }; + } + if (auto e = cb_assign_boolean(bucket.history_retention_collection_default, + bucket_settings, + "historyRetentionCollectionDefault"); + e.ec) { + return { e, {} }; + } + if (auto e = + cb_assign_integer(bucket.history_retention_bytes, bucket_settings, "historyRetentionBytes"); + e.ec) { + return { e, {} }; + } + if (auto e = cb_assign_integer( + bucket.history_retention_duration, bucket_settings, "historyRetentionDuration"); + e.ec) { + return { e, {} }; + } + + return { {}, bucket }; } COUCHBASE_API core_error_info -connection_handle::bucket_create(zval* return_value, const zval* bucket_settings, const zval* options) +connection_handle::bucket_create(zval* return_value, + const zval* bucket_settings, + const zval* options) { - auto [e, bucket] = zval_to_bucket_settings(bucket_settings); - if (e.ec) { - return e; - } + auto [e, bucket] = zval_to_bucket_settings(bucket_settings); + if (e.ec) { + return e; + } - couchbase::core::operations::management::bucket_create_request request{ bucket }; + couchbase::core::operations::management::bucket_create_request request{ bucket }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::bucket_update(zval* return_value, const zval* bucket_settings, const zval* options) +connection_handle::bucket_update(zval* return_value, + const zval* bucket_settings, + const zval* options) { - auto [e, bucket] = zval_to_bucket_settings(bucket_settings); - if (e.ec) { - return e; - } + auto [e, bucket] = zval_to_bucket_settings(bucket_settings); + if (e.ec) { + return e; + } - couchbase::core::operations::management::bucket_update_request request{ bucket }; + couchbase::core::operations::management::bucket_update_request request{ bucket }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -cb_bucket_settings_to_zval(zval* return_value, const couchbase::core::management::cluster::bucket_settings& bucket_settings) +cb_bucket_settings_to_zval( + zval* return_value, + const couchbase::core::management::cluster::bucket_settings& bucket_settings) { - array_init(return_value); - - add_assoc_string(return_value, "name", bucket_settings.name.c_str()); - add_assoc_string(return_value, "uuid", bucket_settings.uuid.c_str()); - std::string bucket_type; - switch (bucket_settings.bucket_type) { - case couchbase::core::management::cluster::bucket_type::couchbase: - bucket_type = "couchbase"; - break; - case couchbase::core::management::cluster::bucket_type::ephemeral: - bucket_type = "ephemeral"; - break; - case couchbase::core::management::cluster::bucket_type::memcached: - bucket_type = "memcached"; - break; - default: - bucket_type = "unknown"; - break; - } - add_assoc_string(return_value, "bucketType", bucket_type.c_str()); - add_assoc_long(return_value, "ramQuotaMB", bucket_settings.ram_quota_mb); - if (bucket_settings.max_expiry.has_value()) { - add_assoc_long(return_value, "maxExpiry", bucket_settings.max_expiry.value()); - } - std::string compression_mode; - switch (bucket_settings.compression_mode) { - case couchbase::core::management::cluster::bucket_compression::off: - compression_mode = "off"; - break; - case couchbase::core::management::cluster::bucket_compression::active: - compression_mode = "active"; - break; - case couchbase::core::management::cluster::bucket_compression::passive: - compression_mode = "passive"; - break; - default: - compression_mode = "unknown"; - break; - } - add_assoc_string(return_value, "compressionMode", compression_mode.c_str()); - if (bucket_settings.minimum_durability_level) { - std::string durability_level; - switch (*bucket_settings.minimum_durability_level) { - case durability_level::none: - durability_level = "none"; - break; - case durability_level::majority: - durability_level = "majority"; - break; - case durability_level::majority_and_persist_to_active: - durability_level = "majorityAndPersistToActive"; - break; - case durability_level::persist_to_majority: - durability_level = "persistToMajority"; - break; - } - add_assoc_string(return_value, "minimumDurabilityLevel", durability_level.c_str()); - } - if (bucket_settings.num_replicas.has_value()) { - add_assoc_long(return_value, "numReplicas", bucket_settings.num_replicas.value()); - } - if (bucket_settings.replica_indexes.has_value()) { - add_assoc_bool(return_value, "replicaIndexes", bucket_settings.replica_indexes.value()); - } - if (bucket_settings.flush_enabled.has_value()) { - add_assoc_bool(return_value, "flushEnabled", bucket_settings.flush_enabled.value()); - } - std::string eviction_policy; - switch (bucket_settings.eviction_policy) { - case couchbase::core::management::cluster::bucket_eviction_policy::no_eviction: - eviction_policy = "noEviction"; - break; - case couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used: - eviction_policy = "nruEviction"; - break; - case couchbase::core::management::cluster::bucket_eviction_policy::value_only: - eviction_policy = "valueOnly"; - break; - case couchbase::core::management::cluster::bucket_eviction_policy::full: - eviction_policy = "fullEviction"; - break; - default: - eviction_policy = "unknown"; - break; - } - add_assoc_string(return_value, "evictionPolicy", eviction_policy.c_str()); - std::string conflict_resolution_type; - switch (bucket_settings.conflict_resolution_type) { - case couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number: - conflict_resolution_type = "sequenceNumber"; - break; - case couchbase::core::management::cluster::bucket_conflict_resolution::timestamp: - conflict_resolution_type = "timestamp"; - break; - case couchbase::core::management::cluster::bucket_conflict_resolution::custom: - conflict_resolution_type = "custom"; - break; - default: - conflict_resolution_type = "unknown"; - break; - } - add_assoc_string(return_value, "conflictResolutionType", conflict_resolution_type.c_str()); - std::string storage_backend; - switch (bucket_settings.storage_backend) { - case couchbase::core::management::cluster::bucket_storage_backend::couchstore: - storage_backend = "couchstore"; - break; - case couchbase::core::management::cluster::bucket_storage_backend::magma: - storage_backend = "magma"; - break; - default: - storage_backend = "unknown"; - break; - } - add_assoc_string(return_value, "storageBackend", storage_backend.c_str()); - if (bucket_settings.history_retention_collection_default.has_value()) { - add_assoc_bool(return_value, "historyRetentionCollectionDefault", bucket_settings.history_retention_collection_default.value()); - } - if (bucket_settings.history_retention_bytes.has_value()) { - add_assoc_long(return_value, "historyRetentionBytes", bucket_settings.history_retention_bytes.value()); - } - if (bucket_settings.history_retention_duration.has_value()) { - add_assoc_long(return_value, "historyRetentionDuration", bucket_settings.history_retention_duration.value()); - } - - return {}; + array_init(return_value); + + add_assoc_string(return_value, "name", bucket_settings.name.c_str()); + add_assoc_string(return_value, "uuid", bucket_settings.uuid.c_str()); + std::string bucket_type; + switch (bucket_settings.bucket_type) { + case couchbase::core::management::cluster::bucket_type::couchbase: + bucket_type = "couchbase"; + break; + case couchbase::core::management::cluster::bucket_type::ephemeral: + bucket_type = "ephemeral"; + break; + case couchbase::core::management::cluster::bucket_type::memcached: + bucket_type = "memcached"; + break; + default: + bucket_type = "unknown"; + break; + } + add_assoc_string(return_value, "bucketType", bucket_type.c_str()); + add_assoc_long(return_value, "ramQuotaMB", bucket_settings.ram_quota_mb); + if (bucket_settings.max_expiry.has_value()) { + add_assoc_long(return_value, "maxExpiry", bucket_settings.max_expiry.value()); + } + std::string compression_mode; + switch (bucket_settings.compression_mode) { + case couchbase::core::management::cluster::bucket_compression::off: + compression_mode = "off"; + break; + case couchbase::core::management::cluster::bucket_compression::active: + compression_mode = "active"; + break; + case couchbase::core::management::cluster::bucket_compression::passive: + compression_mode = "passive"; + break; + default: + compression_mode = "unknown"; + break; + } + add_assoc_string(return_value, "compressionMode", compression_mode.c_str()); + if (bucket_settings.minimum_durability_level) { + std::string durability_level; + switch (*bucket_settings.minimum_durability_level) { + case durability_level::none: + durability_level = "none"; + break; + case durability_level::majority: + durability_level = "majority"; + break; + case durability_level::majority_and_persist_to_active: + durability_level = "majorityAndPersistToActive"; + break; + case durability_level::persist_to_majority: + durability_level = "persistToMajority"; + break; + } + add_assoc_string(return_value, "minimumDurabilityLevel", durability_level.c_str()); + } + if (bucket_settings.num_replicas.has_value()) { + add_assoc_long(return_value, "numReplicas", bucket_settings.num_replicas.value()); + } + if (bucket_settings.replica_indexes.has_value()) { + add_assoc_bool(return_value, "replicaIndexes", bucket_settings.replica_indexes.value()); + } + if (bucket_settings.flush_enabled.has_value()) { + add_assoc_bool(return_value, "flushEnabled", bucket_settings.flush_enabled.value()); + } + std::string eviction_policy; + switch (bucket_settings.eviction_policy) { + case couchbase::core::management::cluster::bucket_eviction_policy::no_eviction: + eviction_policy = "noEviction"; + break; + case couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used: + eviction_policy = "nruEviction"; + break; + case couchbase::core::management::cluster::bucket_eviction_policy::value_only: + eviction_policy = "valueOnly"; + break; + case couchbase::core::management::cluster::bucket_eviction_policy::full: + eviction_policy = "fullEviction"; + break; + default: + eviction_policy = "unknown"; + break; + } + add_assoc_string(return_value, "evictionPolicy", eviction_policy.c_str()); + std::string conflict_resolution_type; + switch (bucket_settings.conflict_resolution_type) { + case couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number: + conflict_resolution_type = "sequenceNumber"; + break; + case couchbase::core::management::cluster::bucket_conflict_resolution::timestamp: + conflict_resolution_type = "timestamp"; + break; + case couchbase::core::management::cluster::bucket_conflict_resolution::custom: + conflict_resolution_type = "custom"; + break; + default: + conflict_resolution_type = "unknown"; + break; + } + add_assoc_string(return_value, "conflictResolutionType", conflict_resolution_type.c_str()); + std::string storage_backend; + switch (bucket_settings.storage_backend) { + case couchbase::core::management::cluster::bucket_storage_backend::couchstore: + storage_backend = "couchstore"; + break; + case couchbase::core::management::cluster::bucket_storage_backend::magma: + storage_backend = "magma"; + break; + default: + storage_backend = "unknown"; + break; + } + add_assoc_string(return_value, "storageBackend", storage_backend.c_str()); + if (bucket_settings.history_retention_collection_default.has_value()) { + add_assoc_bool(return_value, + "historyRetentionCollectionDefault", + bucket_settings.history_retention_collection_default.value()); + } + if (bucket_settings.history_retention_bytes.has_value()) { + add_assoc_long( + return_value, "historyRetentionBytes", bucket_settings.history_retention_bytes.value()); + } + if (bucket_settings.history_retention_duration.has_value()) { + add_assoc_long( + return_value, "historyRetentionDuration", bucket_settings.history_retention_duration.value()); + } + + return {}; } COUCHBASE_API core_error_info connection_handle::bucket_get(zval* return_value, const zend_string* name, const zval* options) { - couchbase::core::operations::management::bucket_get_request request{ cb_string_new(name) }; + couchbase::core::operations::management::bucket_get_request request{ cb_string_new(name) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - if (auto e = cb_bucket_settings_to_zval(return_value, resp.bucket); e.ec) { - return e; - } + if (auto e = cb_bucket_settings_to_zval(return_value, resp.bucket); e.ec) { + return e; + } - return {}; + return {}; } COUCHBASE_API core_error_info connection_handle::bucket_get_all(zval* return_value, const zval* options) { - couchbase::core::operations::management::bucket_get_all_request request{}; + couchbase::core::operations::management::bucket_get_all_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - array_init(return_value); - for (const auto& bucket_settings : resp.buckets) { - zval this_settings; - if (auto e = cb_bucket_settings_to_zval(&this_settings, bucket_settings); e.ec) { - return e; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - add_next_index_zval(return_value, &this_settings); + array_init(return_value); + for (const auto& bucket_settings : resp.buckets) { + zval this_settings; + if (auto e = cb_bucket_settings_to_zval(&this_settings, bucket_settings); e.ec) { + return e; } - return {}; + add_next_index_zval(return_value, &this_settings); + } + + return {}; } COUCHBASE_API core_error_info connection_handle::bucket_drop(zval* return_value, const zend_string* name, const zval* options) { - couchbase::core::operations::management::bucket_drop_request request{ cb_string_new(name) }; + couchbase::core::operations::management::bucket_drop_request request{ cb_string_new(name) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info connection_handle::bucket_flush(zval* return_value, const zend_string* name, const zval* options) { - couchbase::core::operations::management::bucket_flush_request request{ cb_string_new(name) }; + couchbase::core::operations::management::bucket_flush_request request{ cb_string_new(name) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::scope_get_all(zval* return_value, const zend_string* bucket_name, const zval* options) +connection_handle::scope_get_all(zval* return_value, + const zend_string* bucket_name, + const zval* options) { - couchbase::core::operations::management::scope_get_all_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.bucket_name = cb_string_new(bucket_name); - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - - zval scopes; - array_init(&scopes); - for (const auto& s : resp.manifest.scopes) { - zval scope; - array_init(&scope); - add_assoc_string(&scope, "name", s.name.c_str()); - zval collections; - array_init(&collections); - for (const auto& c : s.collections) { - zval collection; - array_init(&collection); - add_assoc_string(&collection, "name", c.name.c_str()); - add_assoc_long(&collection, "max_expiry", c.max_expiry); - if (c.history.has_value()) { - add_assoc_bool(&collection, "history", c.history.value()); - } - add_next_index_zval(&collections, &collection); - } - add_assoc_zval(&scope, "collections", &collections); - add_next_index_zval(&scopes, &scope); - } - add_assoc_zval(return_value, "scopes", &scopes); - - return {}; + couchbase::core::operations::management::scope_get_all_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.bucket_name = cb_string_new(bucket_name); + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + + zval scopes; + array_init(&scopes); + for (const auto& s : resp.manifest.scopes) { + zval scope; + array_init(&scope); + add_assoc_string(&scope, "name", s.name.c_str()); + zval collections; + array_init(&collections); + for (const auto& c : s.collections) { + zval collection; + array_init(&collection); + add_assoc_string(&collection, "name", c.name.c_str()); + add_assoc_long(&collection, "max_expiry", c.max_expiry); + if (c.history.has_value()) { + add_assoc_bool(&collection, "history", c.history.value()); + } + add_next_index_zval(&collections, &collection); + } + add_assoc_zval(&scope, "collections", &collections); + add_next_index_zval(&scopes, &scope); + } + add_assoc_zval(return_value, "scopes", &scopes); + + return {}; } COUCHBASE_API core_error_info -connection_handle::scope_create(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zval* options) +connection_handle::scope_create(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zval* options) { - couchbase::core::operations::management::scope_create_request request{}; + couchbase::core::operations::management::scope_create_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::scope_drop(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zval* options) +connection_handle::scope_drop(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zval* options) { - couchbase::core::operations::management::scope_drop_request request{}; + couchbase::core::operations::management::scope_drop_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -3742,31 +3973,31 @@ connection_handle::collection_create(zval* return_value, const zval* settings, const zval* options) { - couchbase::core::operations::management::collection_create_request request{}; + couchbase::core::operations::management::collection_create_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); - if (auto e = cb_assign_integer(request.max_expiry, settings, "maxExpiry"); e.ec) { - return e; - } + if (auto e = cb_assign_integer(request.max_expiry, settings, "maxExpiry"); e.ec) { + return e; + } - if (auto e = cb_assign_boolean(request.history, settings, "history"); e.ec) { - return e; - } + if (auto e = cb_assign_boolean(request.history, settings, "history"); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -3777,23 +4008,23 @@ connection_handle::collection_drop(zval* return_value, const zend_string* collection_name, const zval* options) { - couchbase::core::operations::management::collection_drop_request request{}; + couchbase::core::operations::management::collection_drop_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API @@ -3805,718 +4036,734 @@ connection_handle::collection_update(zval* return_value, const zval* settings, const zval* options) { - couchbase::core::operations::management::collection_update_request request{}; + couchbase::core::operations::management::collection_update_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); - if (auto e = cb_assign_integer(request.max_expiry, settings, "maxExpiry"); e.ec) { - return e; - } + if (auto e = cb_assign_integer(request.max_expiry, settings, "maxExpiry"); e.ec) { + return e; + } - if (auto e = cb_assign_boolean(request.history, settings, "history"); e.ec) { - return e; - } + if (auto e = cb_assign_boolean(request.history, settings, "history"); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } void cb_role_to_zval(zval* return_value, const couchbase::core::management::rbac::role& role) { - add_assoc_string(return_value, "name", role.name.c_str()); - if (role.bucket) { - add_assoc_string(return_value, "bucket", role.bucket->c_str()); - } - if (role.scope) { - add_assoc_string(return_value, "scope", role.scope->c_str()); - } - if (role.collection) { - add_assoc_string(return_value, "collection", role.collection->c_str()); - } + add_assoc_string(return_value, "name", role.name.c_str()); + if (role.bucket) { + add_assoc_string(return_value, "bucket", role.bucket->c_str()); + } + if (role.scope) { + add_assoc_string(return_value, "scope", role.scope->c_str()); + } + if (role.collection) { + add_assoc_string(return_value, "collection", role.collection->c_str()); + } } COUCHBASE_API core_error_info -cb_user_and_metadata_to_zval(zval* return_value, const couchbase::core::management::rbac::user_and_metadata& user) +cb_user_and_metadata_to_zval(zval* return_value, + const couchbase::core::management::rbac::user_and_metadata& user) { - array_init(return_value); - - add_assoc_string(return_value, "username", user.username.c_str()); - if (user.display_name) { - add_assoc_string(return_value, "displayName", user.display_name->c_str()); - } - - zval groups; - array_init(&groups); - for (const auto& group : user.groups) { - add_next_index_string(&groups, group.c_str()); - } - add_assoc_zval(return_value, "groups", &groups); - - zval roles; - array_init(&roles); - for (const auto& role : user.roles) { - zval z_role; - array_init(&z_role); - add_assoc_string(&z_role, "name", role.name.c_str()); - if (role.bucket) { - add_assoc_string(&z_role, "bucket", role.bucket->c_str()); - } - if (role.scope) { - add_assoc_string(&z_role, "scope", role.scope->c_str()); - } - if (role.collection) { - add_assoc_string(&z_role, "collection", role.collection->c_str()); - } - add_next_index_zval(&roles, &z_role); - } - add_assoc_zval(return_value, "roles", &roles); - - std::string domain; - switch (user.domain) { - case couchbase::core::management::rbac::auth_domain::local: - domain = "local"; - break; - case couchbase::core::management::rbac::auth_domain::external: - domain = "external"; - break; - default: - domain = "unknown"; - break; - } - add_assoc_string(return_value, "domain", domain.c_str()); - - if (user.password_changed) { - add_assoc_string(return_value, "passwordChanged", user.password_changed->c_str()); - } - - zval external_groups; - array_init(&external_groups); - for (const auto& group : user.external_groups) { - add_next_index_string(&external_groups, group.c_str()); + array_init(return_value); + + add_assoc_string(return_value, "username", user.username.c_str()); + if (user.display_name) { + add_assoc_string(return_value, "displayName", user.display_name->c_str()); + } + + zval groups; + array_init(&groups); + for (const auto& group : user.groups) { + add_next_index_string(&groups, group.c_str()); + } + add_assoc_zval(return_value, "groups", &groups); + + zval roles; + array_init(&roles); + for (const auto& role : user.roles) { + zval z_role; + array_init(&z_role); + add_assoc_string(&z_role, "name", role.name.c_str()); + if (role.bucket) { + add_assoc_string(&z_role, "bucket", role.bucket->c_str()); } - add_assoc_zval(return_value, "externalGroups", &external_groups); - - zval effective_roles; - array_init(&effective_roles); - for (const auto& role : user.effective_roles) { - zval z_role; - array_init(&z_role); - cb_role_to_zval(&z_role, role); - - zval origins; - array_init(&origins); - for (const auto& origin : role.origins) { - zval z_origin; - array_init(&z_origin); - add_assoc_string(&z_origin, "type", origin.type.c_str()); - if (origin.name) { - add_assoc_string(&z_origin, "name", origin.name->c_str()); - } - - add_next_index_zval(&origins, &z_origin); - } - add_assoc_zval(&z_role, "origins", &origins); - - add_next_index_zval(&effective_roles, &z_role); + if (role.scope) { + add_assoc_string(&z_role, "scope", role.scope->c_str()); } - add_assoc_zval(return_value, "effectiveRoles", &effective_roles); - - return {}; + if (role.collection) { + add_assoc_string(&z_role, "collection", role.collection->c_str()); + } + add_next_index_zval(&roles, &z_role); + } + add_assoc_zval(return_value, "roles", &roles); + + std::string domain; + switch (user.domain) { + case couchbase::core::management::rbac::auth_domain::local: + domain = "local"; + break; + case couchbase::core::management::rbac::auth_domain::external: + domain = "external"; + break; + default: + domain = "unknown"; + break; + } + add_assoc_string(return_value, "domain", domain.c_str()); + + if (user.password_changed) { + add_assoc_string(return_value, "passwordChanged", user.password_changed->c_str()); + } + + zval external_groups; + array_init(&external_groups); + for (const auto& group : user.external_groups) { + add_next_index_string(&external_groups, group.c_str()); + } + add_assoc_zval(return_value, "externalGroups", &external_groups); + + zval effective_roles; + array_init(&effective_roles); + for (const auto& role : user.effective_roles) { + zval z_role; + array_init(&z_role); + cb_role_to_zval(&z_role, role); + + zval origins; + array_init(&origins); + for (const auto& origin : role.origins) { + zval z_origin; + array_init(&z_origin); + add_assoc_string(&z_origin, "type", origin.type.c_str()); + if (origin.name) { + add_assoc_string(&z_origin, "name", origin.name->c_str()); + } + + add_next_index_zval(&origins, &z_origin); + } + add_assoc_zval(&z_role, "origins", &origins); + + add_next_index_zval(&effective_roles, &z_role); + } + add_assoc_zval(return_value, "effectiveRoles", &effective_roles); + + return {}; } static void cb_group_to_zval(zval* return_value, const couchbase::core::management::rbac::group& group) { - array_init(return_value); - - add_assoc_string(return_value, "name", group.name.c_str()); - if (group.description) { - add_assoc_string(return_value, "description", group.description->c_str()); - } - if (group.ldap_group_reference) { - add_assoc_string(return_value, "ldapGroupReference", group.ldap_group_reference->c_str()); - } - - zval roles; - array_init(&roles); - for (const auto& role : group.roles) { - zval z_role; - array_init(&z_role); - cb_role_to_zval(&z_role, role); - add_next_index_zval(&roles, &z_role); - } - add_assoc_zval(return_value, "roles", &roles); + array_init(return_value); + + add_assoc_string(return_value, "name", group.name.c_str()); + if (group.description) { + add_assoc_string(return_value, "description", group.description->c_str()); + } + if (group.ldap_group_reference) { + add_assoc_string(return_value, "ldapGroupReference", group.ldap_group_reference->c_str()); + } + + zval roles; + array_init(&roles); + for (const auto& role : group.roles) { + zval z_role; + array_init(&z_role); + cb_role_to_zval(&z_role, role); + add_next_index_zval(&roles, &z_role); + } + add_assoc_zval(return_value, "roles", &roles); } COUCHBASE_API core_error_info connection_handle::user_upsert(zval* return_value, const zval* user, const zval* options) { - couchbase::core::management::rbac::user cuser{}; - if (auto e = cb_assign_string(cuser.username, user, "username"); e.ec) { - return e; - } - if (auto e = cb_assign_string(cuser.display_name, user, "displayName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(cuser.password, user, "password"); e.ec) { - return e; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(user), ZEND_STRL("roles")); value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector roles{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - couchbase::core::management::rbac::role role{}; - if (auto e = cb_assign_string(role.name, item, "name"); e.ec) { - return e; - } - if (auto e = cb_assign_string(role.bucket, item, "bucket"); e.ec) { - return e; - } - if (auto e = cb_assign_string(role.scope, item, "scope"); e.ec) { - return e; - } - if (auto e = cb_assign_string(role.collection, item, "collection"); e.ec) { - return e; - } - roles.emplace_back(role); - } - ZEND_HASH_FOREACH_END(); - - cuser.roles = roles; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(user), ZEND_STRL("groups")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::set groups{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - groups.emplace(std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) })); - } - ZEND_HASH_FOREACH_END(); - - cuser.groups = groups; - } - - couchbase::core::operations::management::user_upsert_request request{}; + couchbase::core::management::rbac::user cuser{}; + if (auto e = cb_assign_string(cuser.username, user, "username"); e.ec) { + return e; + } + if (auto e = cb_assign_string(cuser.display_name, user, "displayName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(cuser.password, user, "password"); e.ec) { + return e; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(user), ZEND_STRL("roles")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector roles{}; + const zval* item = nullptr; - if (auto e = cb_assign_timeout(request, options); e.ec) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + couchbase::core::management::rbac::role role{}; + if (auto e = cb_assign_string(role.name, item, "name"); e.ec) { return e; - } - if (auto e = cb_assign_user_domain(request, options); e.ec) { + } + if (auto e = cb_assign_string(role.bucket, item, "bucket"); e.ec) { return e; - } - request.user = cuser; - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::user_get_all(zval* return_value, const zval* options) -{ - couchbase::core::operations::management::user_get_all_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { + } + if (auto e = cb_assign_string(role.scope, item, "scope"); e.ec) { return e; - } - if (auto e = cb_assign_user_domain(request, options); e.ec) { + } + if (auto e = cb_assign_string(role.collection, item, "collection"); e.ec) { return e; + } + roles.emplace_back(role); } + ZEND_HASH_FOREACH_END(); - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - for (const auto& user : resp.users) { - zval this_user; - if (auto e = cb_user_and_metadata_to_zval(&this_user, user); e.ec) { - return e; - } - - add_next_index_zval(return_value, &this_user); - } - - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::user_get(zval* return_value, const zend_string* name, const zval* options) -{ - couchbase::core::operations::management::user_get_request request{ cb_string_new(name) }; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - if (auto e = cb_assign_user_domain(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - if (auto e = cb_user_and_metadata_to_zval(return_value, resp.user); e.ec) { - return e; - } - - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::user_drop(zval* return_value, const zend_string* name, const zval* options) -{ - couchbase::core::operations::management::user_drop_request request{ cb_string_new(name) }; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - if (auto e = cb_assign_user_domain(request, options); e.ec) { - return e; - } + cuser.roles = roles; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(user), ZEND_STRL("groups")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::set groups{}; + const zval* item = nullptr; - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + groups.emplace(std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) })); } + ZEND_HASH_FOREACH_END(); - array_init(return_value); - return {}; -} + cuser.groups = groups; + } -COUCHBASE_API -core_error_info -connection_handle::change_password(zval* return_value, const zend_string* new_password, const zval* options) -{ - couchbase::core::operations::management::change_password_request request{ cb_string_new(new_password) }; + couchbase::core::operations::management::user_upsert_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + if (auto e = cb_assign_user_domain(request, options); e.ec) { + return e; + } + request.user = cuser; - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - array_init(return_value); - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::group_upsert(zval* return_value, const zval* group, const zval* options) +connection_handle::user_get_all(zval* return_value, const zval* options) { - couchbase::core::management::rbac::group cgroup{}; - if (auto e = cb_assign_string(cgroup.name, group, "name"); e.ec) { - return e; - } - if (auto e = cb_assign_string(cgroup.description, group, "description"); e.ec) { - return e; - } - if (auto e = cb_assign_string(cgroup.ldap_group_reference, group, "ldapGroupReference"); e.ec) { - return e; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(group), ZEND_STRL("roles")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector roles{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - couchbase::core::management::rbac::role role{}; - if (auto e = cb_assign_string(role.name, item, "name"); e.ec) { - return e; - } - if (auto e = cb_assign_string(role.bucket, item, "bucket"); e.ec) { - return e; - } - if (auto e = cb_assign_string(role.scope, item, "scope"); e.ec) { - return e; - } - if (auto e = cb_assign_string(role.collection, item, "collection"); e.ec) { - return e; - } - roles.emplace_back(role); - } - ZEND_HASH_FOREACH_END(); + couchbase::core::operations::management::user_get_all_request request{}; - cgroup.roles = roles; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + if (auto e = cb_assign_user_domain(request, options); e.ec) { + return e; + } - couchbase::core::operations::management::group_upsert_request request{ cgroup }; + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; + array_init(return_value); + for (const auto& user : resp.users) { + zval this_user; + if (auto e = cb_user_and_metadata_to_zval(&this_user, user); e.ec) { + return e; } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + add_next_index_zval(return_value, &this_user); + } - array_init(return_value); - return {}; + return {}; } COUCHBASE_API core_error_info -connection_handle::group_get_all(zval* return_value, const zval* options) -{ - couchbase::core::operations::management::group_get_all_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - for (const auto& group : resp.groups) { - zval this_group; - cb_group_to_zval(&this_group, group); - - add_next_index_zval(return_value, &this_group); - } - - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::group_get(zval* return_value, const zend_string* name, const zval* options) +connection_handle::user_get(zval* return_value, const zend_string* name, const zval* options) { - couchbase::core::operations::management::group_get_request request{ cb_string_new(name) }; + couchbase::core::operations::management::user_get_request request{ cb_string_new(name) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + if (auto e = cb_assign_user_domain(request, options); e.ec) { + return e; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - cb_group_to_zval(return_value, resp.group); + if (auto e = cb_user_and_metadata_to_zval(return_value, resp.user); e.ec) { + return e; + } - return {}; + return {}; } COUCHBASE_API core_error_info -connection_handle::group_drop(zval* return_value, const zend_string* name, const zval* options) +connection_handle::user_drop(zval* return_value, const zend_string* name, const zval* options) { - couchbase::core::operations::management::group_drop_request request{ cb_string_new(name) }; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - return {}; + couchbase::core::operations::management::user_drop_request request{ cb_string_new(name) }; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + if (auto e = cb_assign_user_domain(request, options); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::role_get_all(zval* return_value, const zval* options) +connection_handle::change_password(zval* return_value, + const zend_string* new_password, + const zval* options) { - couchbase::core::operations::management::role_get_all_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } + couchbase::core::operations::management::change_password_request request{ cb_string_new( + new_password) }; - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - array_init(return_value); - for (const auto& role : resp.roles) { - zval this_role; - array_init(&this_role); - cb_role_to_zval(&this_role, role); - add_assoc_string(&this_role, "displayName", role.display_name.c_str()); - add_assoc_string(&this_role, "description", role.description.c_str()); - - add_next_index_zval(return_value, &this_role); - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - return {}; + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::query_index_get_all(zval* return_value, const zend_string* bucket_name, const zval* options) +connection_handle::group_upsert(zval* return_value, const zval* group, const zval* options) { - couchbase::core::operations::management::query_index_get_all_request request{}; + couchbase::core::management::rbac::group cgroup{}; + if (auto e = cb_assign_string(cgroup.name, group, "name"); e.ec) { + return e; + } + if (auto e = cb_assign_string(cgroup.description, group, "description"); e.ec) { + return e; + } + if (auto e = cb_assign_string(cgroup.ldap_group_reference, group, "ldapGroupReference"); e.ec) { + return e; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(group), ZEND_STRL("roles")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector roles{}; + const zval* item = nullptr; - if (auto e = cb_assign_timeout(request, options); e.ec) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + couchbase::core::management::rbac::role role{}; + if (auto e = cb_assign_string(role.name, item, "name"); e.ec) { return e; - } - request.bucket_name = cb_string_new(bucket_name); - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + } + if (auto e = cb_assign_string(role.bucket, item, "bucket"); e.ec) { return e; - } - if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { + } + if (auto e = cb_assign_string(role.scope, item, "scope"); e.ec) { return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - for (const auto& idx : resp.indexes) { - zval index; - array_init(&index); - add_assoc_bool(&index, "isPrimary", idx.is_primary); - add_assoc_stringl(&index, "name", idx.name.data(), idx.name.size()); - add_assoc_stringl(&index, "state", idx.state.data(), idx.state.size()); - add_assoc_stringl(&index, "type", idx.type.data(), idx.type.size()); - add_assoc_stringl(&index, "bucketName", idx.bucket_name.data(), idx.bucket_name.size()); - if (idx.partition) { - add_assoc_stringl(&index, "partition", idx.partition->data(), idx.partition->size()); - } - if (idx.condition) { - add_assoc_stringl(&index, "condition", idx.condition->data(), idx.condition->size()); - } - if (idx.scope_name) { - add_assoc_stringl(&index, "scopeName", idx.scope_name->data(), idx.scope_name->size()); - } - if (idx.collection_name) { - add_assoc_stringl(&index, "collectionName", idx.collection_name->data(), idx.collection_name->size()); - } - zval index_key; - array_init(&index_key); - for (const auto& field : idx.index_key) { - add_next_index_stringl(&index_key, field.data(), field.size()); - } - add_assoc_zval(&index, "indexKey", &index_key); - add_next_index_zval(return_value, &index); - } - return {}; -} - -COUCHBASE_API -core_error_info -connection_handle::query_index_create(const zend_string* bucket_name, - const zend_string* index_name, - const zval* fields, - const zval* options) -{ - if (fields == nullptr || Z_TYPE_P(fields) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for index fields" }; - } - couchbase::core::operations::management::query_index_create_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { + } + if (auto e = cb_assign_string(role.collection, item, "collection"); e.ec) { return e; - } - request.is_primary = false; - request.bucket_name = cb_string_new(bucket_name); - request.index_name = cb_string_new(index_name); - - const zval* value; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), value) - { - if (value == nullptr && Z_TYPE_P(value) == IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected index fields to be array of strings" }; - } - request.keys.emplace_back(cb_string_new(value)); + } + roles.emplace_back(role); } ZEND_HASH_FOREACH_END(); - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.condition, options, "condition"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { - return e; - } - if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { - return e; - } + cgroup.roles = roles; + } + + couchbase::core::operations::management::group_upsert_request request{ cgroup }; - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - return {}; + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + return {}; } COUCHBASE_API core_error_info -connection_handle::query_index_create_primary(const zend_string* bucket_name, const zval* options) +connection_handle::group_get_all(zval* return_value, const zval* options) { - couchbase::core::operations::management::query_index_create_request request{}; + couchbase::core::operations::management::group_get_all_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.is_primary = true; - request.bucket_name = cb_string_new(bucket_name); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { - return e; - } - if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { - return e; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + array_init(return_value); + for (const auto& group : resp.groups) { + zval this_group; + cb_group_to_zval(&this_group, group); - return {}; + add_next_index_zval(return_value, &this_group); + } + + return {}; } COUCHBASE_API core_error_info -connection_handle::query_index_drop(const zend_string* bucket_name, const zend_string* index_name, const zval* options) +connection_handle::group_get(zval* return_value, const zend_string* name, const zval* options) { - couchbase::core::operations::management::query_index_drop_request request{}; + couchbase::core::operations::management::group_get_request request{ cb_string_new(name) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.is_primary = false; - request.bucket_name = cb_string_new(bucket_name); - request.index_name = cb_string_new(index_name); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); e.ec) { - return e; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + cb_group_to_zval(return_value, resp.group); - return {}; + return {}; } COUCHBASE_API core_error_info -connection_handle::query_index_drop_primary(const zend_string* bucket_name, const zval* options) +connection_handle::group_drop(zval* return_value, const zend_string* name, const zval* options) { - couchbase::core::operations::management::query_index_drop_request request{}; + couchbase::core::operations::management::group_drop_request request{ cb_string_new(name) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.is_primary = true; - request.bucket_name = cb_string_new(bucket_name); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } - if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); e.ec) { - return e; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + array_init(return_value); + return {}; +} - return {}; +COUCHBASE_API +core_error_info +connection_handle::role_get_all(zval* return_value, const zval* options) +{ + couchbase::core::operations::management::role_get_all_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + for (const auto& role : resp.roles) { + zval this_role; + array_init(&this_role); + cb_role_to_zval(&this_role, role); + add_assoc_string(&this_role, "displayName", role.display_name.c_str()); + add_assoc_string(&this_role, "description", role.description.c_str()); + + add_next_index_zval(return_value, &this_role); + } + + return {}; } COUCHBASE_API core_error_info -connection_handle::query_index_build_deferred(zval* return_value, const zend_string* bucket_name, const zval* options) +connection_handle::query_index_get_all(zval* return_value, + const zend_string* bucket_name, + const zval* options) { - couchbase::core::operations::management::query_index_build_deferred_request request{}; + couchbase::core::operations::management::query_index_get_all_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.bucket_name = cb_string_new(bucket_name); + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + for (const auto& idx : resp.indexes) { + zval index; + array_init(&index); + add_assoc_bool(&index, "isPrimary", idx.is_primary); + add_assoc_stringl(&index, "name", idx.name.data(), idx.name.size()); + add_assoc_stringl(&index, "state", idx.state.data(), idx.state.size()); + add_assoc_stringl(&index, "type", idx.type.data(), idx.type.size()); + add_assoc_stringl(&index, "bucketName", idx.bucket_name.data(), idx.bucket_name.size()); + if (idx.partition) { + add_assoc_stringl(&index, "partition", idx.partition->data(), idx.partition->size()); + } + if (idx.condition) { + add_assoc_stringl(&index, "condition", idx.condition->data(), idx.condition->size()); + } + if (idx.scope_name) { + add_assoc_stringl(&index, "scopeName", idx.scope_name->data(), idx.scope_name->size()); + } + if (idx.collection_name) { + add_assoc_stringl( + &index, "collectionName", idx.collection_name->data(), idx.collection_name->size()); + } + zval index_key; + array_init(&index_key); + for (const auto& field : idx.index_key) { + add_next_index_stringl(&index_key, field.data(), field.size()); + } + add_assoc_zval(&index, "indexKey", &index_key); + add_next_index_zval(return_value, &index); + } + return {}; +} - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.bucket_name = cb_string_new(bucket_name); +COUCHBASE_API +core_error_info +connection_handle::query_index_create(const zend_string* bucket_name, + const zend_string* index_name, + const zval* fields, + const zval* options) +{ + if (fields == nullptr || Z_TYPE_P(fields) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for index fields" }; + } + couchbase::core::operations::management::query_index_create_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = false; + request.bucket_name = cb_string_new(bucket_name); + request.index_name = cb_string_new(index_name); + + const zval* value; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), value) + { + if (value == nullptr && Z_TYPE_P(value) == IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected index fields to be array of strings" }; + } + request.keys.emplace_back(cb_string_new(value)); + } + ZEND_HASH_FOREACH_END(); + + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.condition, options, "condition"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { + return e; + } + if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; +} - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { - return e; - } - if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { - return e; - } +COUCHBASE_API +core_error_info +connection_handle::query_index_create_primary(const zend_string* bucket_name, const zval* options) +{ + couchbase::core::operations::management::query_index_create_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = true; + request.bucket_name = cb_string_new(bucket_name); + + if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { + return e; + } + if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; +} - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } +COUCHBASE_API +core_error_info +connection_handle::query_index_drop(const zend_string* bucket_name, + const zend_string* index_name, + const zval* options) +{ + couchbase::core::operations::management::query_index_drop_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = false; + request.bucket_name = cb_string_new(bucket_name); + request.index_name = cb_string_new(index_name); + + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); + e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; +} - return {}; +COUCHBASE_API +core_error_info +connection_handle::query_index_drop_primary(const zend_string* bucket_name, const zval* options) +{ + couchbase::core::operations::management::query_index_drop_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = true; + request.bucket_name = cb_string_new(bucket_name); + + if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); + e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; +} + +COUCHBASE_API +core_error_info +connection_handle::query_index_build_deferred(zval* return_value, + const zend_string* bucket_name, + const zval* options) +{ + couchbase::core::operations::management::query_index_build_deferred_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.bucket_name = cb_string_new(bucket_name); + + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return e; + } + if (auto e = cb_assign_string(request.collection_name, options, "collectionName"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; } COUCHBASE_API @@ -4527,50 +4774,51 @@ connection_handle::collection_query_index_get_all(zval* return_value, const zend_string* collection_name, const zval* options) { - couchbase::core::operations::management::query_index_get_all_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - array_init(return_value); - for (const auto& idx : resp.indexes) { - zval index; - array_init(&index); - add_assoc_bool(&index, "isPrimary", idx.is_primary); - add_assoc_stringl(&index, "name", idx.name.data(), idx.name.size()); - add_assoc_stringl(&index, "state", idx.state.data(), idx.state.size()); - add_assoc_stringl(&index, "type", idx.type.data(), idx.type.size()); - add_assoc_stringl(&index, "bucketName", idx.bucket_name.data(), idx.bucket_name.size()); - if (idx.partition) { - add_assoc_stringl(&index, "partition", idx.partition->data(), idx.partition->size()); - } - if (idx.condition) { - add_assoc_stringl(&index, "condition", idx.condition->data(), idx.condition->size()); - } - if (idx.scope_name) { - add_assoc_stringl(&index, "scopeName", idx.scope_name->data(), idx.scope_name->size()); - } - if (idx.collection_name) { - add_assoc_stringl(&index, "collectionName", idx.collection_name->data(), idx.collection_name->size()); - } - zval index_key; - array_init(&index_key); - for (const auto& field : idx.index_key) { - add_next_index_stringl(&index_key, field.data(), field.size()); - } - add_assoc_zval(&index, "indexKey", &index_key); - add_next_index_zval(return_value, &index); - } - return {}; + couchbase::core::operations::management::query_index_get_all_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + array_init(return_value); + for (const auto& idx : resp.indexes) { + zval index; + array_init(&index); + add_assoc_bool(&index, "isPrimary", idx.is_primary); + add_assoc_stringl(&index, "name", idx.name.data(), idx.name.size()); + add_assoc_stringl(&index, "state", idx.state.data(), idx.state.size()); + add_assoc_stringl(&index, "type", idx.type.data(), idx.type.size()); + add_assoc_stringl(&index, "bucketName", idx.bucket_name.data(), idx.bucket_name.size()); + if (idx.partition) { + add_assoc_stringl(&index, "partition", idx.partition->data(), idx.partition->size()); + } + if (idx.condition) { + add_assoc_stringl(&index, "condition", idx.condition->data(), idx.condition->size()); + } + if (idx.scope_name) { + add_assoc_stringl(&index, "scopeName", idx.scope_name->data(), idx.scope_name->size()); + } + if (idx.collection_name) { + add_assoc_stringl( + &index, "collectionName", idx.collection_name->data(), idx.collection_name->size()); + } + zval index_key; + array_init(&index_key); + for (const auto& field : idx.index_key) { + add_next_index_stringl(&index_key, field.data(), field.size()); + } + add_assoc_zval(&index, "indexKey", &index_key); + add_next_index_zval(return_value, &index); + } + return {}; } COUCHBASE_API @@ -4582,49 +4830,51 @@ connection_handle::collection_query_index_create(const zend_string* bucket_name, const zval* fields, const zval* options) { - if (fields == nullptr || Z_TYPE_P(fields) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for index fields" }; - } - couchbase::core::operations::management::query_index_create_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.is_primary = false; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); - request.index_name = cb_string_new(index_name); - - const zval* value; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), value) - { - if (value == nullptr && Z_TYPE_P(value) == IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected index fields to be array of strings" }; - } - request.keys.emplace_back(cb_string_new(value)); - } - ZEND_HASH_FOREACH_END(); - - if (auto e = cb_assign_string(request.condition, options, "condition"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { - return e; - } - if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - return {}; + if (fields == nullptr || Z_TYPE_P(fields) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for index fields" }; + } + couchbase::core::operations::management::query_index_create_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = false; + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); + request.index_name = cb_string_new(index_name); + + const zval* value; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), value) + { + if (value == nullptr && Z_TYPE_P(value) == IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected index fields to be array of strings" }; + } + request.keys.emplace_back(cb_string_new(value)); + } + ZEND_HASH_FOREACH_END(); + + if (auto e = cb_assign_string(request.condition, options, "condition"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { + return e; + } + if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; } COUCHBASE_API @@ -4634,35 +4884,35 @@ connection_handle::collection_query_index_create_primary(const zend_string* buck const zend_string* collection_name, const zval* options) { - couchbase::core::operations::management::query_index_create_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.is_primary = true; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); - - if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { - return e; - } - if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - return {}; + couchbase::core::operations::management::query_index_create_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = true; + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); + + if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.deferred, options, "deferred"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.ignore_if_exists, options, "ignoreIfExists"); e.ec) { + return e; + } + if (auto e = cb_assign_integer(request.num_replicas, options, "numberOfReplicas"); e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; } COUCHBASE_API @@ -4673,27 +4923,28 @@ connection_handle::collection_query_index_drop(const zend_string* bucket_name, const zend_string* index_name, const zval* options) { - couchbase::core::operations::management::query_index_drop_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.is_primary = false; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); - request.index_name = cb_string_new(index_name); - - if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - return {}; + couchbase::core::operations::management::query_index_drop_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = false; + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); + request.index_name = cb_string_new(index_name); + + if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); + e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; } COUCHBASE_API @@ -4703,29 +4954,30 @@ connection_handle::collection_query_index_drop_primary(const zend_string* bucket const zend_string* collection_name, const zval* options) { - couchbase::core::operations::management::query_index_drop_request request{}; - - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.is_primary = true; - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); - - if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { - return e; - } - if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); e.ec) { - return e; - } - - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } - - return {}; + couchbase::core::operations::management::query_index_drop_request request{}; + + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.is_primary = true; + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); + + if (auto e = cb_assign_string(request.index_name, options, "indexName"); e.ec) { + return e; + } + if (auto e = cb_assign_boolean(request.ignore_if_does_not_exist, options, "ignoreIfDoesNotExist"); + e.ec) { + return e; + } + + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } + + return {}; } COUCHBASE_API @@ -4736,264 +4988,297 @@ connection_handle::collection_query_index_build_deferred(zval* return_value, const zend_string* collection_name, const zval* options) { - couchbase::core::operations::management::query_index_build_deferred_request request{}; + couchbase::core::operations::management::query_index_build_deferred_request request{}; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return e; - } - request.bucket_name = cb_string_new(bucket_name); - request.scope_name = cb_string_new(scope_name); - request.collection_name = cb_string_new(collection_name); + if (auto e = cb_assign_timeout(request, options); e.ec) { + return e; + } + request.bucket_name = cb_string_new(bucket_name); + request.scope_name = cb_string_new(scope_name); + request.collection_name = cb_string_new(collection_name); - auto [resp, err] = impl_->http_execute(__func__, std::move(request)); - if (err.ec) { - return err; - } + auto [resp, err] = impl_->http_execute(__func__, std::move(request)); + if (err.ec) { + return err; + } - return {}; + return {}; } bool connection_handle::is_expired(std::chrono::system_clock::time_point now) const { - return idle_expiry_ < now; + return idle_expiry_ < now; } std::shared_ptr connection_handle::cluster() const { - return impl_->cluster(); + return impl_->cluster(); } -#define ASSIGN_DURATION_OPTION(name, field, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - if (Z_TYPE_P(value) != IS_LONG) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected duration as a number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - zend_long ms = Z_LVAL_P(value); \ - if (ms < 0) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected duration as a positive number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - (field) = std::chrono::milliseconds(ms); \ - } - -#define ASSIGN_NUMBER_OPTION(name, field, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - if (Z_TYPE_P(value) != IS_LONG) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - (field) = Z_LVAL_P(value); \ - } - -#define ASSIGN_BOOLEAN_OPTION(name, field, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - switch (Z_TYPE_P(value)) { \ - case IS_TRUE: \ - (field) = true; \ - break; \ - case IS_FALSE: \ - (field) = false; \ - break; \ - default: \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected boolean for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - } - -#define ASSIGN_STRING_OPTION(name, field, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - if (Z_TYPE_P(value) != IS_STRING) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - if (Z_STRLEN_P(value) == 0) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected non-empty string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - (field).assign(Z_STRVAL_P(value), Z_STRLEN_P(value)); \ - } +#define ASSIGN_DURATION_OPTION(name, field, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + if (Z_TYPE_P(value) != IS_LONG) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected duration as a number for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + zend_long ms = Z_LVAL_P(value); \ + if (ms < 0) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected duration as a positive number for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + (field) = std::chrono::milliseconds(ms); \ + } + +#define ASSIGN_NUMBER_OPTION(name, field, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + if (Z_TYPE_P(value) != IS_LONG) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + (field) = Z_LVAL_P(value); \ + } + +#define ASSIGN_BOOLEAN_OPTION(name, field, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + switch (Z_TYPE_P(value)) { \ + case IS_TRUE: \ + (field) = true; \ + break; \ + case IS_FALSE: \ + (field) = false; \ + break; \ + default: \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected boolean for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + } + +#define ASSIGN_STRING_OPTION(name, field, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + if (Z_TYPE_P(value) != IS_STRING) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + if (Z_STRLEN_P(value) == 0) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected non-empty string for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + (field).assign(Z_STRVAL_P(value), Z_STRLEN_P(value)); \ + } struct dns_options { - std::chrono::milliseconds timeout; - std::string nameserver; - std::uint16_t port; + std::chrono::milliseconds timeout; + std::string nameserver; + std::uint16_t port; }; static core_error_info apply_options(core::utils::connection_string& connstr, zval* options) { - if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for cluster options" }; - } - - const zend_string* key; - const zval* value; - - auto system_dns = core::io::dns::dns_config::system_config(); - dns_options dns{ system_dns.timeout(), system_dns.nameserver(), system_dns.port() }; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) - { - ASSIGN_DURATION_OPTION("analyticsTimeout", connstr.options.analytics_timeout, key, value); - ASSIGN_DURATION_OPTION("bootstrapTimeout", connstr.options.bootstrap_timeout, key, value); - ASSIGN_DURATION_OPTION("connectTimeout", connstr.options.connect_timeout, key, value); - - ASSIGN_DURATION_OPTION("dnsSrvTimeout", dns.timeout, key, value); - ASSIGN_STRING_OPTION("dnsSrvNameserver", dns.nameserver, key, value); - ASSIGN_NUMBER_OPTION("dnsSrvPort", dns.port, key, value); - - ASSIGN_DURATION_OPTION("keyValueDurableTimeout", connstr.options.key_value_durable_timeout, key, value); - ASSIGN_DURATION_OPTION("keyValueTimeout", connstr.options.key_value_timeout, key, value); - ASSIGN_DURATION_OPTION("managementTimeout", connstr.options.management_timeout, key, value); - ASSIGN_DURATION_OPTION("queryTimeout", connstr.options.query_timeout, key, value); - ASSIGN_DURATION_OPTION("resolveTimeout", connstr.options.resolve_timeout, key, value); - ASSIGN_DURATION_OPTION("searchTimeout", connstr.options.search_timeout, key, value); - ASSIGN_DURATION_OPTION("viewTimeout", connstr.options.view_timeout, key, value); - - ASSIGN_NUMBER_OPTION("maxHttpConnections", connstr.options.max_http_connections, key, value); - - ASSIGN_DURATION_OPTION("configIdleRedialTimeout", connstr.options.config_idle_redial_timeout, key, value); - ASSIGN_DURATION_OPTION("configPollFloor", connstr.options.config_poll_floor, key, value); - ASSIGN_DURATION_OPTION("configPollInterval", connstr.options.config_poll_interval, key, value); - ASSIGN_DURATION_OPTION("idleHttpConnectionTimeout", connstr.options.idle_http_connection_timeout, key, value); - ASSIGN_DURATION_OPTION("tcpKeepAliveInterval", connstr.options.tcp_keep_alive_interval, key, value); - - ASSIGN_BOOLEAN_OPTION("enableClustermapNotification", connstr.options.enable_clustermap_notification, key, value); - ASSIGN_BOOLEAN_OPTION("enableCompression", connstr.options.enable_compression, key, value); - ASSIGN_BOOLEAN_OPTION("enableDnsSrv", connstr.options.enable_dns_srv, key, value); - ASSIGN_BOOLEAN_OPTION("enableMetrics", connstr.options.enable_metrics, key, value); - ASSIGN_BOOLEAN_OPTION("enableMutationTokens", connstr.options.enable_mutation_tokens, key, value); - ASSIGN_BOOLEAN_OPTION("enableTcpKeepAlive", connstr.options.enable_tcp_keep_alive, key, value); - ASSIGN_BOOLEAN_OPTION("enableTls", connstr.options.enable_tls, key, value); - ASSIGN_BOOLEAN_OPTION("enableTracing", connstr.options.enable_tracing, key, value); - ASSIGN_BOOLEAN_OPTION("enableUnorderedExecution", connstr.options.enable_unordered_execution, key, value); - ASSIGN_BOOLEAN_OPTION("showQueries", connstr.options.show_queries, key, value); - - ASSIGN_STRING_OPTION("network", connstr.options.network, key, value); - ASSIGN_STRING_OPTION("trustCertificate", connstr.options.trust_certificate, key, value); - ASSIGN_STRING_OPTION("userAgentExtra", connstr.options.user_agent_extra, key, value); - - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("useIpProtocol")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_STRING) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("any")) == 0) { - connstr.options.use_ip_protocol = core::io::ip_protocol::any; - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("forceIpv4")) == 0) { - connstr.options.use_ip_protocol = core::io::ip_protocol::force_ipv4; - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("forceIpv6")) == 0) { - connstr.options.use_ip_protocol = core::io::ip_protocol::force_ipv6; - } else { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format(R"(expected mode for TLS verification ({}), supported modes are "peer" and "none")", - std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - } - - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("tlsVerify")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_STRING) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("peer")) == 0) { - connstr.options.tls_verify = core::tls_verify_mode::peer; - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { - connstr.options.tls_verify = core::tls_verify_mode::none; - } else { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format(R"(expected mode for TLS verification ({}), supported modes are "peer" and "none")", - std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - } - - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("thresholdLoggingTracerOptions")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_ARRAY) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected array for {} as tracer options", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - - const zend_string* k; - const zval* v; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) - { - ASSIGN_NUMBER_OPTION("orphanedSampleSize", connstr.options.tracing_options.orphaned_sample_size, k, v); - ASSIGN_DURATION_OPTION("orphanedEmitInterval", connstr.options.tracing_options.orphaned_emit_interval, k, v); - - ASSIGN_NUMBER_OPTION("thresholdSampleSize", connstr.options.tracing_options.threshold_sample_size, k, v); - ASSIGN_DURATION_OPTION("thresholdEmitInterval", connstr.options.tracing_options.threshold_emit_interval, k, v); - ASSIGN_DURATION_OPTION("analyticsThreshold", connstr.options.tracing_options.analytics_threshold, k, v); - ASSIGN_DURATION_OPTION("eventingThreshold", connstr.options.tracing_options.eventing_threshold, k, v); - ASSIGN_DURATION_OPTION("keyValueThreshold", connstr.options.tracing_options.key_value_threshold, k, v); - ASSIGN_DURATION_OPTION("managementThreshold", connstr.options.tracing_options.management_threshold, k, v); - ASSIGN_DURATION_OPTION("queryThreshold", connstr.options.tracing_options.query_threshold, k, v); - ASSIGN_DURATION_OPTION("searchThreshold", connstr.options.tracing_options.search_threshold, k, v); - ASSIGN_DURATION_OPTION("viewThreshold", connstr.options.tracing_options.view_threshold, k, v); - } - ZEND_HASH_FOREACH_END(); - } - - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("loggingMeterOptions")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_ARRAY) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected array for {} as meter options", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } + if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for cluster options" }; + } + + const zend_string* key; + const zval* value; + + auto system_dns = core::io::dns::dns_config::system_config(); + dns_options dns{ system_dns.timeout(), system_dns.nameserver(), system_dns.port() }; + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) + { + ASSIGN_DURATION_OPTION("analyticsTimeout", connstr.options.analytics_timeout, key, value); + ASSIGN_DURATION_OPTION("bootstrapTimeout", connstr.options.bootstrap_timeout, key, value); + ASSIGN_DURATION_OPTION("connectTimeout", connstr.options.connect_timeout, key, value); + + ASSIGN_DURATION_OPTION("dnsSrvTimeout", dns.timeout, key, value); + ASSIGN_STRING_OPTION("dnsSrvNameserver", dns.nameserver, key, value); + ASSIGN_NUMBER_OPTION("dnsSrvPort", dns.port, key, value); + + ASSIGN_DURATION_OPTION( + "keyValueDurableTimeout", connstr.options.key_value_durable_timeout, key, value); + ASSIGN_DURATION_OPTION("keyValueTimeout", connstr.options.key_value_timeout, key, value); + ASSIGN_DURATION_OPTION("managementTimeout", connstr.options.management_timeout, key, value); + ASSIGN_DURATION_OPTION("queryTimeout", connstr.options.query_timeout, key, value); + ASSIGN_DURATION_OPTION("resolveTimeout", connstr.options.resolve_timeout, key, value); + ASSIGN_DURATION_OPTION("searchTimeout", connstr.options.search_timeout, key, value); + ASSIGN_DURATION_OPTION("viewTimeout", connstr.options.view_timeout, key, value); + + ASSIGN_NUMBER_OPTION("maxHttpConnections", connstr.options.max_http_connections, key, value); + + ASSIGN_DURATION_OPTION( + "configIdleRedialTimeout", connstr.options.config_idle_redial_timeout, key, value); + ASSIGN_DURATION_OPTION("configPollFloor", connstr.options.config_poll_floor, key, value); + ASSIGN_DURATION_OPTION("configPollInterval", connstr.options.config_poll_interval, key, value); + ASSIGN_DURATION_OPTION( + "idleHttpConnectionTimeout", connstr.options.idle_http_connection_timeout, key, value); + ASSIGN_DURATION_OPTION( + "tcpKeepAliveInterval", connstr.options.tcp_keep_alive_interval, key, value); + + ASSIGN_BOOLEAN_OPTION( + "enableClustermapNotification", connstr.options.enable_clustermap_notification, key, value); + ASSIGN_BOOLEAN_OPTION("enableCompression", connstr.options.enable_compression, key, value); + ASSIGN_BOOLEAN_OPTION("enableDnsSrv", connstr.options.enable_dns_srv, key, value); + ASSIGN_BOOLEAN_OPTION("enableMetrics", connstr.options.enable_metrics, key, value); + ASSIGN_BOOLEAN_OPTION( + "enableMutationTokens", connstr.options.enable_mutation_tokens, key, value); + ASSIGN_BOOLEAN_OPTION("enableTcpKeepAlive", connstr.options.enable_tcp_keep_alive, key, value); + ASSIGN_BOOLEAN_OPTION("enableTls", connstr.options.enable_tls, key, value); + ASSIGN_BOOLEAN_OPTION("enableTracing", connstr.options.enable_tracing, key, value); + ASSIGN_BOOLEAN_OPTION( + "enableUnorderedExecution", connstr.options.enable_unordered_execution, key, value); + ASSIGN_BOOLEAN_OPTION("showQueries", connstr.options.show_queries, key, value); + + ASSIGN_STRING_OPTION("network", connstr.options.network, key, value); + ASSIGN_STRING_OPTION("trustCertificate", connstr.options.trust_certificate, key, value); + ASSIGN_STRING_OPTION("userAgentExtra", connstr.options.user_agent_extra, key, value); + + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("useIpProtocol")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("any")) == 0) { + connstr.options.use_ip_protocol = core::io::ip_protocol::any; + } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("forceIpv4")) == + 0) { + connstr.options.use_ip_protocol = core::io::ip_protocol::force_ipv4; + } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("forceIpv6")) == + 0) { + connstr.options.use_ip_protocol = core::io::ip_protocol::force_ipv6; + } else { + return { + errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format( + R"(expected mode for TLS verification ({}), supported modes are "peer" and "none")", + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) + }; + } + } + + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("tlsVerify")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("peer")) == 0) { + connstr.options.tls_verify = core::tls_verify_mode::peer; + } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { + connstr.options.tls_verify = core::tls_verify_mode::none; + } else { + return { + errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format( + R"(expected mode for TLS verification ({}), supported modes are "peer" and "none")", + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) + }; + } + } + + if (zend_binary_strcmp( + ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("thresholdLoggingTracerOptions")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected array for {} as tracer options", + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; + } + + const zend_string* k; + const zval* v; + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) + { + ASSIGN_NUMBER_OPTION( + "orphanedSampleSize", connstr.options.tracing_options.orphaned_sample_size, k, v); + ASSIGN_DURATION_OPTION( + "orphanedEmitInterval", connstr.options.tracing_options.orphaned_emit_interval, k, v); + + ASSIGN_NUMBER_OPTION( + "thresholdSampleSize", connstr.options.tracing_options.threshold_sample_size, k, v); + ASSIGN_DURATION_OPTION( + "thresholdEmitInterval", connstr.options.tracing_options.threshold_emit_interval, k, v); + ASSIGN_DURATION_OPTION( + "analyticsThreshold", connstr.options.tracing_options.analytics_threshold, k, v); + ASSIGN_DURATION_OPTION( + "eventingThreshold", connstr.options.tracing_options.eventing_threshold, k, v); + ASSIGN_DURATION_OPTION( + "keyValueThreshold", connstr.options.tracing_options.key_value_threshold, k, v); + ASSIGN_DURATION_OPTION( + "managementThreshold", connstr.options.tracing_options.management_threshold, k, v); + ASSIGN_DURATION_OPTION( + "queryThreshold", connstr.options.tracing_options.query_threshold, k, v); + ASSIGN_DURATION_OPTION( + "searchThreshold", connstr.options.tracing_options.search_threshold, k, v); + ASSIGN_DURATION_OPTION( + "viewThreshold", connstr.options.tracing_options.view_threshold, k, v); + } + ZEND_HASH_FOREACH_END(); + } + + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("loggingMeterOptions")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected array for {} as meter options", + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; + } - const zend_string* k; - const zval* v; + const zend_string* k; + const zval* v; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) - { - ASSIGN_DURATION_OPTION("emitInterval", connstr.options.metrics_options.emit_interval, k, v); - } - ZEND_HASH_FOREACH_END(); - } + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) + { + ASSIGN_DURATION_OPTION("emitInterval", connstr.options.metrics_options.emit_interval, k, v); + } + ZEND_HASH_FOREACH_END(); } - ZEND_HASH_FOREACH_END(); + } + ZEND_HASH_FOREACH_END(); - connstr.options.dns_config = core::io::dns::dns_config(dns.nameserver, dns.port, dns.timeout); + connstr.options.dns_config = core::io::dns::dns_config(dns.nameserver, dns.port, dns.timeout); - return {}; + return {}; } #undef ASSIGN_DURATION_OPTION @@ -5004,67 +5289,82 @@ apply_options(core::utils::connection_string& connstr, zval* options) static core_error_info extract_credentials(couchbase::core::cluster_credentials& credentials, zval* options) { - if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for cluster options" }; - } + if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for cluster options" }; + } - const zval* auth = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("authenticator")); - if (auth == nullptr || Z_TYPE_P(auth) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "missing authenticator" }; - } + const zval* auth = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("authenticator")); + if (auth == nullptr || Z_TYPE_P(auth) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "missing authenticator" }; + } - const zval* auth_type = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("type")); - if (auth_type == nullptr || Z_TYPE_P(auth_type) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "unexpected type of the authenticator" }; + const zval* auth_type = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("type")); + if (auth_type == nullptr || Z_TYPE_P(auth_type) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "unexpected type of the authenticator" }; + } + if (zend_binary_strcmp(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type), ZEND_STRL("password")) == + 0) { + const zval* username = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("username")); + if (username == nullptr || Z_TYPE_P(username) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected username to be a string in the authenticator" }; } - if (zend_binary_strcmp(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type), ZEND_STRL("password")) == 0) { - const zval* username = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("username")); - if (username == nullptr || Z_TYPE_P(username) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected username to be a string in the authenticator" }; - } - const zval* password = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("password")); - if (password == nullptr || Z_TYPE_P(password) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected password to be a string in the authenticator" }; - } - credentials.username.assign(Z_STRVAL_P(username)); - credentials.password.assign(Z_STRVAL_P(password)); + const zval* password = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("password")); + if (password == nullptr || Z_TYPE_P(password) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected password to be a string in the authenticator" }; + } + credentials.username.assign(Z_STRVAL_P(username)); + credentials.password.assign(Z_STRVAL_P(password)); - if (const zval* allowed_sasl_mechanisms = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("allowedSaslMechanisms")); - allowed_sasl_mechanisms != nullptr && Z_TYPE_P(allowed_sasl_mechanisms) != IS_NULL) { - if (Z_TYPE_P(allowed_sasl_mechanisms) != IS_ARRAY) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - "expected allowedSaslMechanisms to be an array in the authenticator" }; - } - std::vector mechanisms; - const zval* mech; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(allowed_sasl_mechanisms), mech) - { - if (mech != nullptr && Z_TYPE_P(mech) == IS_STRING) { - mechanisms.emplace_back(Z_STRVAL_P(mech), Z_STRLEN_P(mech)); - } - } - ZEND_HASH_FOREACH_END(); - credentials.allowed_sasl_mechanisms = mechanisms; + if (const zval* allowed_sasl_mechanisms = + zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("allowedSaslMechanisms")); + allowed_sasl_mechanisms != nullptr && Z_TYPE_P(allowed_sasl_mechanisms) != IS_NULL) { + if (Z_TYPE_P(allowed_sasl_mechanisms) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected allowedSaslMechanisms to be an array in the authenticator" }; + } + std::vector mechanisms; + const zval* mech; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(allowed_sasl_mechanisms), mech) + { + if (mech != nullptr && Z_TYPE_P(mech) == IS_STRING) { + mechanisms.emplace_back(Z_STRVAL_P(mech), Z_STRLEN_P(mech)); } - return {}; + } + ZEND_HASH_FOREACH_END(); + credentials.allowed_sasl_mechanisms = mechanisms; } - if (zend_binary_strcmp(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type), ZEND_STRL("certificate")) == 0) { - const zval* certificate_path = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("certificatePath")); - if (certificate_path == nullptr || Z_TYPE_P(certificate_path) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected certificate path to be a string in the authenticator" }; - } - const zval* key_path = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("keyPath")); - if (key_path == nullptr || Z_TYPE_P(key_path) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected key path to be a string in the authenticator" }; - } - credentials.certificate_path.assign(Z_STRVAL_P(certificate_path)); - credentials.key_path.assign(Z_STRVAL_P(key_path)); - return {}; + return {}; + } + if (zend_binary_strcmp(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type), ZEND_STRL("certificate")) == + 0) { + const zval* certificate_path = + zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("certificatePath")); + if (certificate_path == nullptr || Z_TYPE_P(certificate_path) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected certificate path to be a string in the authenticator" }; } - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("unknown type of the authenticator: {}", std::string(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type))) }; + const zval* key_path = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("keyPath")); + if (key_path == nullptr || Z_TYPE_P(key_path) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected key path to be a string in the authenticator" }; + } + credentials.certificate_path.assign(Z_STRVAL_P(certificate_path)); + credentials.key_path.assign(Z_STRVAL_P(key_path)); + return {}; + } + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unknown type of the authenticator: {}", + std::string(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type))) }; } COUCHBASE_API @@ -5074,32 +5374,35 @@ create_connection_handle(const zend_string* connection_string, zval* options, std::chrono::system_clock::time_point idle_expiry) { - std::string connection_str(ZSTR_VAL(connection_string), ZSTR_LEN(connection_string)); - auto connstr = core::utils::parse_connection_string(connection_str); - if (connstr.error) { - return { nullptr, { couchbase::errc::common::parsing_failure, ERROR_LOCATION, connstr.error.value() } }; - } - if (auto e = apply_options(connstr, options); e.ec) { - return { nullptr, e }; - } - couchbase::core::cluster_credentials credentials; - if (auto e = extract_credentials(credentials, options); e.ec) { - return { nullptr, e }; - } - connstr.options.user_agent_extra = fmt::format("php_sdk/{}/{};ssl/{:x};php/{}", - PHP_COUCHBASE_VERSION, - std::string(extension_revision()).substr(0, 8), - OpenSSL_version_num(), - PHP_VERSION + std::string connection_str(ZSTR_VAL(connection_string), ZSTR_LEN(connection_string)); + auto connstr = core::utils::parse_connection_string(connection_str); + if (connstr.error) { + return { nullptr, + { couchbase::errc::common::parsing_failure, ERROR_LOCATION, connstr.error.value() } }; + } + if (auto e = apply_options(connstr, options); e.ec) { + return { nullptr, e }; + } + couchbase::core::cluster_credentials credentials; + if (auto e = extract_credentials(credentials, options); e.ec) { + return { nullptr, e }; + } + connstr.options.user_agent_extra = fmt::format("php_sdk/{}/{};ssl/{:x};php/{}", + PHP_COUCHBASE_VERSION, + std::string(extension_revision()).substr(0, 8), + OpenSSL_version_num(), + PHP_VERSION #if ZTS - "/z" + "/z" #else - "/n" + "/n" #endif - ); - couchbase::core::origin origin{ credentials, connstr }; - return { new connection_handle( - std::move(connection_str), std::string(ZSTR_VAL(connection_hash), ZSTR_LEN(connection_hash)), origin, idle_expiry), - {} }; + ); + couchbase::core::origin origin{ credentials, connstr }; + return { new connection_handle(std::move(connection_str), + std::string(ZSTR_VAL(connection_hash), ZSTR_LEN(connection_hash)), + origin, + idle_expiry), + {} }; } } // namespace couchbase::php diff --git a/src/wrapper/connection_handle.hxx b/src/wrapper/connection_handle.hxx index ef6c0647..66f8d5aa 100644 --- a/src/wrapper/connection_handle.hxx +++ b/src/wrapper/connection_handle.hxx @@ -38,494 +38,591 @@ namespace couchbase::php { class connection_handle { - public: - COUCHBASE_API - connection_handle(std::string connection_string, - std::string connection_hash, - couchbase::core::origin origin, - std::chrono::system_clock::time_point idle_expiry); - - COUCHBASE_API - ~connection_handle(); - - COUCHBASE_API - std::shared_ptr cluster() const; - - COUCHBASE_API - bool is_expired(std::chrono::system_clock::time_point now) const; - - const std::chrono::system_clock::time_point& expires_at() const - { - return idle_expiry_; - } - - void expires_at(const std::chrono::system_clock::time_point& at) - { - idle_expiry_ = at; - } - - COUCHBASE_API - const std::string& connection_string() const - { - return connection_string_; - } - - COUCHBASE_API - const std::string& connection_hash() const - { - return connection_hash_; - } - - COUCHBASE_API - std::string cluster_version(const zend_string* name); - - COUCHBASE_API - bool replicas_configured_for_bucket(const zend_string* bucket_name); - - COUCHBASE_API - void notify_fork(fork_event event) const; - - COUCHBASE_API - core_error_info open(); - - COUCHBASE_API - core_error_info bucket_open(const std::string& name); - - COUCHBASE_API - core_error_info bucket_open(const zend_string* name); - - COUCHBASE_API - core_error_info bucket_close(const zend_string* name); - - COUCHBASE_API - core_error_info document_upsert(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zend_string* value, - zend_long flags, - const zval* options); +public: + COUCHBASE_API + connection_handle(std::string connection_string, + std::string connection_hash, + couchbase::core::origin origin, + std::chrono::system_clock::time_point idle_expiry); + + COUCHBASE_API + ~connection_handle(); + + COUCHBASE_API + std::shared_ptr cluster() const; + + COUCHBASE_API + bool is_expired(std::chrono::system_clock::time_point now) const; + + const std::chrono::system_clock::time_point& expires_at() const + { + return idle_expiry_; + } + + void expires_at(const std::chrono::system_clock::time_point& at) + { + idle_expiry_ = at; + } + + COUCHBASE_API + const std::string& connection_string() const + { + return connection_string_; + } + + COUCHBASE_API + const std::string& connection_hash() const + { + return connection_hash_; + } + + COUCHBASE_API + std::string cluster_version(const zend_string* name); + + COUCHBASE_API + bool replicas_configured_for_bucket(const zend_string* bucket_name); + + COUCHBASE_API + void notify_fork(fork_event event) const; + + COUCHBASE_API + core_error_info open(); + + COUCHBASE_API + core_error_info bucket_open(const std::string& name); + + COUCHBASE_API + core_error_info bucket_open(const zend_string* name); + + COUCHBASE_API + core_error_info bucket_close(const zend_string* name); + + COUCHBASE_API + core_error_info document_upsert(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zend_string* value, + zend_long flags, + const zval* options); + + COUCHBASE_API + core_error_info document_insert(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zend_string* value, + zend_long flags, + const zval* options); + + COUCHBASE_API + core_error_info document_replace(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zend_string* value, + zend_long flags, + const zval* options); - COUCHBASE_API - core_error_info document_insert(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zend_string* value, - zend_long flags, - const zval* options); + COUCHBASE_API + core_error_info document_append(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zend_string* value, + const zval* options); + + COUCHBASE_API + core_error_info document_prepend(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zend_string* value, + const zval* options); - COUCHBASE_API - core_error_info document_replace(zval* return_value, + COUCHBASE_API + core_error_info document_increment(zval* return_value, const zend_string* bucket, const zend_string* scope, const zend_string* collection, const zend_string* id, - const zend_string* value, - zend_long flags, const zval* options); - COUCHBASE_API - core_error_info document_append(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zend_string* value, - const zval* options); - - COUCHBASE_API - core_error_info document_prepend(zval* return_value, + COUCHBASE_API + core_error_info document_decrement(zval* return_value, const zend_string* bucket, const zend_string* scope, const zend_string* collection, const zend_string* id, - const zend_string* value, const zval* options); - COUCHBASE_API - core_error_info document_increment(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* options); - - COUCHBASE_API - core_error_info document_decrement(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* options); - - COUCHBASE_API - core_error_info document_get(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* options); - - COUCHBASE_API - core_error_info document_get_any_replica(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* options); - - COUCHBASE_API - core_error_info document_get_all_replicas(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* options); - - COUCHBASE_API - core_error_info document_get_and_lock(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - zend_long lock_time, - const zval* options); + COUCHBASE_API + core_error_info document_get(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* options); - COUCHBASE_API - core_error_info document_get_and_touch(zval* return_value, + COUCHBASE_API + core_error_info document_get_any_replica(zval* return_value, const zend_string* bucket, const zend_string* scope, const zend_string* collection, const zend_string* id, - zend_long expiry, const zval* options); - COUCHBASE_API - core_error_info document_unlock(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zend_string* cas, - const zval* options); - - COUCHBASE_API - core_error_info document_remove(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* options); - - COUCHBASE_API - core_error_info document_touch(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - zend_long expiry, - const zval* options); - - COUCHBASE_API - core_error_info document_exists(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* options); - - COUCHBASE_API - core_error_info document_mutate_in(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* specs, - const zval* options); - - COUCHBASE_API - core_error_info document_lookup_in(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* specs, - const zval* options); - - COUCHBASE_API - core_error_info document_lookup_in_any_replica(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* specs, - const zval* options); - - COUCHBASE_API - core_error_info document_lookup_in_all_replicas(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zval* specs, - const zval* options); - - COUCHBASE_API - core_error_info document_get_multi(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zval* ids, - const zval* options); - - COUCHBASE_API - core_error_info document_remove_multi(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zval* entries, - const zval* options); + COUCHBASE_API + core_error_info document_get_all_replicas(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* options); + + COUCHBASE_API + core_error_info document_get_and_lock(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + zend_long lock_time, + const zval* options); + + COUCHBASE_API + core_error_info document_get_and_touch(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + zend_long expiry, + const zval* options); + + COUCHBASE_API + core_error_info document_unlock(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zend_string* cas, + const zval* options); + + COUCHBASE_API + core_error_info document_remove(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* options); + + COUCHBASE_API + core_error_info document_touch(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + zend_long expiry, + const zval* options); - COUCHBASE_API - core_error_info document_upsert_multi(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zval* entries, - const zval* options); + COUCHBASE_API + core_error_info document_exists(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* options); - COUCHBASE_API - core_error_info query(zval* return_value, const zend_string* statement, const zval* options); + COUCHBASE_API + core_error_info document_mutate_in(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* specs, + const zval* options); - COUCHBASE_API - core_error_info analytics_query(zval* return_value, const zend_string* statement, const zval* options); + COUCHBASE_API + core_error_info document_lookup_in(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* specs, + const zval* options); - COUCHBASE_API - core_error_info search(zval* return_value, - const zend_string* index_name, - const zend_string* query, - const zval* options, - const zend_string* vector_search, - const zval* vector_options); + COUCHBASE_API + core_error_info document_lookup_in_any_replica(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* specs, + const zval* options); + + COUCHBASE_API + core_error_info document_lookup_in_all_replicas(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zval* specs, + const zval* options); - COUCHBASE_API - core_error_info search_query(zval* return_value, const zend_string* index_name, const zend_string* query, const zval* options); + COUCHBASE_API + core_error_info document_get_multi(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zval* ids, + const zval* options); - COUCHBASE_API - core_error_info view_query(zval* return_value, - const zend_string* bucket_name, - const zend_string* design_document_name, - const zend_string* view_name, - zend_long name_space, + COUCHBASE_API + core_error_info document_remove_multi(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zval* entries, + const zval* options); + + COUCHBASE_API + core_error_info document_upsert_multi(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zval* entries, + const zval* options); + + COUCHBASE_API + core_error_info query(zval* return_value, const zend_string* statement, const zval* options); + + COUCHBASE_API + core_error_info analytics_query(zval* return_value, + const zend_string* statement, + const zval* options); + + COUCHBASE_API + core_error_info search(zval* return_value, + const zend_string* index_name, + const zend_string* query, + const zval* options, + const zend_string* vector_search, + const zval* vector_options); + + COUCHBASE_API + core_error_info search_query(zval* return_value, + const zend_string* index_name, + const zend_string* query, const zval* options); - COUCHBASE_API - core_error_info ping(zval* return_value, const zval* options); - - COUCHBASE_API - core_error_info diagnostics(zval* return_value, const zend_string* report_id, const zval* options); - - COUCHBASE_API - core_error_info search_index_get(zval* return_value, const zend_string* index_name, const zval* options); - - COUCHBASE_API - core_error_info search_index_get_all(zval* return_value, const zval* options); - - COUCHBASE_API - core_error_info search_index_upsert(zval* return_value, const zval* index, const zval* options); - - COUCHBASE_API - core_error_info search_index_drop(zval* return_value, const zend_string* index_name, const zval* options); - - COUCHBASE_API - core_error_info search_index_get_documents_count(zval* return_value, const zend_string* index_name, const zval* options); - - COUCHBASE_API - core_error_info search_index_control_ingest(zval* return_value, const zend_string* index_name, bool pause, const zval* options); - - COUCHBASE_API - core_error_info search_index_control_query(zval* return_value, const zend_string* index_name, bool allow, const zval* options); - - COUCHBASE_API - core_error_info search_index_control_plan_freeze(zval* return_value, const zend_string* index_name, bool freeze, const zval* options); - - COUCHBASE_API - core_error_info search_index_analyze_document(zval* return_value, const zend_string* index_name, const zend_string* document, const zval* options); - - COUCHBASE_API - core_error_info scope_search_index_get(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* index_name, const zval* options); + COUCHBASE_API + core_error_info view_query(zval* return_value, + const zend_string* bucket_name, + const zend_string* design_document_name, + const zend_string* view_name, + zend_long name_space, + const zval* options); + + COUCHBASE_API + core_error_info ping(zval* return_value, const zval* options); + + COUCHBASE_API + core_error_info diagnostics(zval* return_value, + const zend_string* report_id, + const zval* options); + + COUCHBASE_API + core_error_info search_index_get(zval* return_value, + const zend_string* index_name, + const zval* options); - COUCHBASE_API - core_error_info scope_search_index_get_all(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zval* options); + COUCHBASE_API + core_error_info search_index_get_all(zval* return_value, const zval* options); - COUCHBASE_API - core_error_info scope_search_index_upsert(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zval* index, const zval* options); + COUCHBASE_API + core_error_info search_index_upsert(zval* return_value, const zval* index, const zval* options); - COUCHBASE_API - core_error_info scope_search_index_drop(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* index_name, const zval* options); + COUCHBASE_API + core_error_info search_index_drop(zval* return_value, + const zend_string* index_name, + const zval* options); - COUCHBASE_API - core_error_info scope_search_index_get_documents_count(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* index_name, const zval* options); + COUCHBASE_API + core_error_info search_index_get_documents_count(zval* return_value, + const zend_string* index_name, + const zval* options); - COUCHBASE_API - core_error_info scope_search_index_control_ingest(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* index_name, bool pause, const zval* options); + COUCHBASE_API + core_error_info search_index_control_ingest(zval* return_value, + const zend_string* index_name, + bool pause, + const zval* options); - COUCHBASE_API - core_error_info scope_search_index_control_query(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* index_name, bool allow, const zval* options); + COUCHBASE_API + core_error_info search_index_control_query(zval* return_value, + const zend_string* index_name, + bool allow, + const zval* options); - COUCHBASE_API - core_error_info scope_search_index_control_plan_freeze(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* index_name, bool freeze, const zval* options); + COUCHBASE_API + core_error_info search_index_control_plan_freeze(zval* return_value, + const zend_string* index_name, + bool freeze, + const zval* options); - COUCHBASE_API - core_error_info scope_search_index_analyze_document(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* index_name, const zend_string* document, const zval* options); + COUCHBASE_API + core_error_info search_index_analyze_document(zval* return_value, + const zend_string* index_name, + const zend_string* document, + const zval* options); - COUCHBASE_API - core_error_info view_index_upsert(zval* return_value, - const zend_string* bucket_name, - const zval* design_document, - zend_long name_space, - const zval* options); + COUCHBASE_API + core_error_info scope_search_index_get(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* index_name, + const zval* options); + + COUCHBASE_API + core_error_info scope_search_index_get_all(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zval* options); - COUCHBASE_API - core_error_info bucket_create(zval* return_value, const zval* bucket_settings, const zval* options); + COUCHBASE_API + core_error_info scope_search_index_upsert(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zval* index, + const zval* options); + + COUCHBASE_API + core_error_info scope_search_index_drop(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* index_name, + const zval* options); - COUCHBASE_API - core_error_info bucket_update(zval* return_value, const zval* bucket_settings, const zval* options); + COUCHBASE_API + core_error_info scope_search_index_get_documents_count(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* index_name, + const zval* options); + + COUCHBASE_API + core_error_info scope_search_index_control_ingest(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* index_name, + bool pause, + const zval* options); - COUCHBASE_API - core_error_info bucket_get(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info scope_search_index_control_query(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* index_name, + bool allow, + const zval* options); - COUCHBASE_API - core_error_info bucket_get_all(zval* return_value, const zval* options); + COUCHBASE_API + core_error_info scope_search_index_control_plan_freeze(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* index_name, + bool freeze, + const zval* options); + + COUCHBASE_API + core_error_info scope_search_index_analyze_document(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* index_name, + const zend_string* document, + const zval* options); + + COUCHBASE_API + core_error_info view_index_upsert(zval* return_value, + const zend_string* bucket_name, + const zval* design_document, + zend_long name_space, + const zval* options); - COUCHBASE_API - core_error_info bucket_drop(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info bucket_create(zval* return_value, + const zval* bucket_settings, + const zval* options); - COUCHBASE_API - core_error_info bucket_flush(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info bucket_update(zval* return_value, + const zval* bucket_settings, + const zval* options); - COUCHBASE_API - core_error_info scope_get_all(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info bucket_get(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info scope_create(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zval* options); + COUCHBASE_API + core_error_info bucket_get_all(zval* return_value, const zval* options); - COUCHBASE_API - core_error_info scope_drop(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zval* options); + COUCHBASE_API + core_error_info bucket_drop(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info collection_create(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* collection_name, const zval* settings, const zval* options); + COUCHBASE_API + core_error_info bucket_flush(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info collection_drop(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* collection_name, const zval* options); + COUCHBASE_API + core_error_info scope_get_all(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info collection_update(zval* return_value, const zend_string* bucket_name, const zend_string* scope_name, const zend_string* collection_name, const zval* settings, const zval* options); + COUCHBASE_API + core_error_info scope_create(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zval* options); - COUCHBASE_API - core_error_info user_upsert(zval* return_value, const zval* user, const zval* options); + COUCHBASE_API + core_error_info scope_drop(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zval* options); + + COUCHBASE_API + core_error_info collection_create(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* collection_name, + const zval* settings, + const zval* options); - COUCHBASE_API - core_error_info user_get(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info collection_drop(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* collection_name, + const zval* options); + + COUCHBASE_API + core_error_info collection_update(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* collection_name, + const zval* settings, + const zval* options); - COUCHBASE_API - core_error_info user_get_all(zval* return_value, const zval* options); + COUCHBASE_API + core_error_info user_upsert(zval* return_value, const zval* user, const zval* options); - COUCHBASE_API - core_error_info user_drop(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info user_get(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info change_password(zval* return_value, const zend_string* new_password, const zval* options); + COUCHBASE_API + core_error_info user_get_all(zval* return_value, const zval* options); - COUCHBASE_API - core_error_info group_upsert(zval* return_value, const zval* group, const zval* options); + COUCHBASE_API + core_error_info user_drop(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info group_get(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info change_password(zval* return_value, + const zend_string* new_password, + const zval* options); - COUCHBASE_API - core_error_info group_get_all(zval* return_value, const zval* options); + COUCHBASE_API + core_error_info group_upsert(zval* return_value, const zval* group, const zval* options); - COUCHBASE_API - core_error_info group_drop(zval* return_value, const zend_string* name, const zval* options); + COUCHBASE_API + core_error_info group_get(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info role_get_all(zval* return_value, const zval* options); + COUCHBASE_API + core_error_info group_get_all(zval* return_value, const zval* options); - COUCHBASE_API - core_error_info query_index_get_all(zval* return_value, const zend_string* bucket_name, const zval* options); + COUCHBASE_API + core_error_info group_drop(zval* return_value, const zend_string* name, const zval* options); - COUCHBASE_API - core_error_info query_index_create(const zend_string* bucket_name, - const zend_string* index_name, - const zval* keys, - const zval* options); + COUCHBASE_API + core_error_info role_get_all(zval* return_value, const zval* options); - COUCHBASE_API - core_error_info query_index_create_primary(const zend_string* bucket_name, const zval* options); + COUCHBASE_API + core_error_info query_index_get_all(zval* return_value, + const zend_string* bucket_name, + const zval* options); - COUCHBASE_API - core_error_info query_index_drop(const zend_string* bucket_name, const zend_string* index_name, const zval* options); + COUCHBASE_API + core_error_info query_index_create(const zend_string* bucket_name, + const zend_string* index_name, + const zval* keys, + const zval* options); - COUCHBASE_API - core_error_info query_index_drop_primary(const zend_string* bucket_name, const zval* options); + COUCHBASE_API + core_error_info query_index_create_primary(const zend_string* bucket_name, const zval* options); - COUCHBASE_API - core_error_info query_index_build_deferred(zval* return_value, const zend_string* bucket_name, const zval* options); + COUCHBASE_API + core_error_info query_index_drop(const zend_string* bucket_name, + const zend_string* index_name, + const zval* options); - COUCHBASE_API - core_error_info collection_query_index_get_all(zval* return_value, - const zend_string* bucket_name, - const zend_string* scope_name, - const zend_string* collection_name, - const zval* options); + COUCHBASE_API + core_error_info query_index_drop_primary(const zend_string* bucket_name, const zval* options); - COUCHBASE_API - core_error_info collection_query_index_create(const zend_string* bucket_name, - const zend_string* scope_name, - const zend_string* collection_name, - const zend_string* index_name, - const zval* keys, - const zval* options); + COUCHBASE_API + core_error_info query_index_build_deferred(zval* return_value, + const zend_string* bucket_name, + const zval* options); - COUCHBASE_API - core_error_info collection_query_index_create_primary(const zend_string* bucket_name, - const zend_string* scope_name, - const zend_string* collection_name, - const zval* options); + COUCHBASE_API + core_error_info collection_query_index_get_all(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* collection_name, + const zval* options); - COUCHBASE_API - core_error_info collection_query_index_drop(const zend_string* bucket_name, + COUCHBASE_API + core_error_info collection_query_index_create(const zend_string* bucket_name, const zend_string* scope_name, const zend_string* collection_name, const zend_string* index_name, + const zval* keys, const zval* options); - COUCHBASE_API - core_error_info collection_query_index_drop_primary(const zend_string* bucket_name, + COUCHBASE_API + core_error_info collection_query_index_create_primary(const zend_string* bucket_name, const zend_string* scope_name, const zend_string* collection_name, const zval* options); - COUCHBASE_API - core_error_info collection_query_index_build_deferred(zval* return_value, - const zend_string* bucket_name, - const zend_string* scope_name, - const zend_string* collection_name, - const zval* options); + COUCHBASE_API + core_error_info collection_query_index_drop(const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* collection_name, + const zend_string* index_name, + const zval* options); + + COUCHBASE_API + core_error_info collection_query_index_drop_primary(const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* collection_name, + const zval* options); + + COUCHBASE_API + core_error_info collection_query_index_build_deferred(zval* return_value, + const zend_string* bucket_name, + const zend_string* scope_name, + const zend_string* collection_name, + const zval* options); - private: - class impl; +private: + class impl; - std::chrono::system_clock::time_point idle_expiry_; /* time when the connection will be considered as expired */ + std::chrono::system_clock::time_point + idle_expiry_; /* time when the connection will be considered as expired */ - std::shared_ptr impl_; + std::shared_ptr impl_; - std::string connection_string_; - std::string connection_hash_; + std::string connection_string_; + std::string connection_hash_; }; COUCHBASE_API diff --git a/src/wrapper/conversion_utilities.cxx b/src/wrapper/conversion_utilities.cxx index 1379d2b0..919b736a 100644 --- a/src/wrapper/conversion_utilities.cxx +++ b/src/wrapper/conversion_utilities.cxx @@ -31,1013 +31,1081 @@ namespace couchbase::php std::vector cb_binary_new(const zend_string* value) { - if (value == nullptr) { - return {}; - } - return core::utils::to_binary(ZSTR_VAL(value), ZSTR_LEN(value)); + if (value == nullptr) { + return {}; + } + return core::utils::to_binary(ZSTR_VAL(value), ZSTR_LEN(value)); } std::vector cb_binary_new(const zval* value) { - if (value == nullptr || Z_TYPE_P(value) != IS_STRING) { - return {}; - } - return cb_binary_new(Z_STR_P(value)); + if (value == nullptr || Z_TYPE_P(value) != IS_STRING) { + return {}; + } + return cb_binary_new(Z_STR_P(value)); } std::string cb_string_new(const zend_string* value) { - if (value == nullptr) { - return {}; - } - return { ZSTR_VAL(value), ZSTR_LEN(value) }; + if (value == nullptr) { + return {}; + } + return { ZSTR_VAL(value), ZSTR_LEN(value) }; } std::string cb_string_new(const zval* value) { - if (value == nullptr || Z_TYPE_P(value) != IS_STRING) { - return {}; - } - return cb_string_new(Z_STR_P(value)); + if (value == nullptr || Z_TYPE_P(value) != IS_STRING) { + return {}; + } + return cb_string_new(Z_STR_P(value)); } std::pair> cb_get_string(const zval* options, std::string_view name) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_STRING: - break; - default: - return { - { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("expected {} to be a string value in the options", name) }, {} - }; - } + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} + }; + } + + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); + if (value == nullptr) { + return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_STRING: + break; + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected {} to be a string value in the options", name) }, + {} }; + } - return { {}, cb_string_new(value) }; + return { {}, cb_string_new(value) }; } std::pair> cb_get_boolean(const zval* options, std::string_view name) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_TRUE: - return { {}, true }; - case IS_FALSE: - return { {}, false }; - default: - return { - { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("expected {} to be a boolean value in the options", name) }, - {} - }; - } - + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} + }; + } + + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); + if (value == nullptr) { return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_TRUE: + return { {}, true }; + case IS_FALSE: + return { {}, false }; + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected {} to be a boolean value in the options", name) }, + {} }; + } + + return {}; } std::pair>> cb_get_binary(const zval* options, std::string_view name) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_STRING: - break; - default: - return { - { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("expected {} to be a string value in the options", name) }, {} - }; - } + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} + }; + } + + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); + if (value == nullptr) { + return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_STRING: + break; + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected {} to be a string value in the options", name) }, + {} }; + } - return { {}, cb_binary_new(value) }; + return { {}, cb_binary_new(value) }; } std::pair zval_to_transactions_query_options(const zval* options) { - transactions::transaction_query_options query_options{}; - if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { - if (scan_consistency == "notBounded") { - query_options.scan_consistency(query_scan_consistency::not_bounded); - } else if (scan_consistency == "requestPlus") { - query_options.scan_consistency(query_scan_consistency::request_plus); - } else if (scan_consistency) { - return { {}, - { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for scan consistency: {}", *scan_consistency) } }; - } - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, val] = cb_get_integer(options, "scanCap"); val) { - query_options.scan_cap(val.value()); - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, val] = cb_get_integer(options, "pipelineCap"); val) { - query_options.pipeline_cap(val.value()); - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, val] = cb_get_integer(options, "pipelineBatch"); val) { - query_options.pipeline_batch(val.value()); - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, val] = cb_get_integer(options, "maxParallelism"); val) { - query_options.max_parallelism(val.value()); - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, profile] = cb_get_string(options, "profile"); profile) { - if (profile == "off") { - query_options.profile(query_profile::off); - } else if (profile == "phases") { - query_options.profile(query_profile::phases); - } else if (profile == "timings") { - query_options.profile(query_profile::timings); - } else if (profile) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("invalid value used for profile: {}", *profile) } }; - } - } else if (e.ec) { - return { {}, e }; - } + transactions::transaction_query_options query_options{}; + if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { + if (scan_consistency == "notBounded") { + query_options.scan_consistency(query_scan_consistency::not_bounded); + } else if (scan_consistency == "requestPlus") { + query_options.scan_consistency(query_scan_consistency::request_plus); + } else if (scan_consistency) { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for scan consistency: {}", *scan_consistency) } }; + } + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, val] = cb_get_integer(options, "scanCap"); val) { + query_options.scan_cap(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, val] = cb_get_integer(options, "pipelineCap"); val) { + query_options.pipeline_cap(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, val] = cb_get_integer(options, "pipelineBatch"); val) { + query_options.pipeline_batch(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, val] = cb_get_integer(options, "maxParallelism"); val) { + query_options.max_parallelism(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, profile] = cb_get_string(options, "profile"); profile) { + if (profile == "off") { + query_options.profile(query_profile::off); + } else if (profile == "phases") { + query_options.profile(query_profile::phases); + } else if (profile == "timings") { + query_options.profile(query_profile::timings); + } else if (profile) { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for profile: {}", *profile) } }; + } + } else if (e.ec) { + return { {}, e }; + } + + if (auto [e, val] = cb_get_boolean(options, "readonly"); val) { + query_options.readonly(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, val] = cb_get_boolean(options, "flexIndex"); val) { + query_options.readonly(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, val] = cb_get_boolean(options, "adHoc"); val) { + query_options.readonly(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (auto [e, val] = cb_get_string(options, "clientContextId"); val) { + query_options.client_context_id(val.value()); + } else if (e.ec) { + return { {}, e }; + } + if (const zval* value = + zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("positionalParameters")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector params{}; + const zval* item = nullptr; - if (auto [e, val] = cb_get_boolean(options, "readonly"); val) { - query_options.readonly(val.value()); - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, val] = cb_get_boolean(options, "flexIndex"); val) { - query_options.readonly(val.value()); - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, val] = cb_get_boolean(options, "adHoc"); val) { - query_options.readonly(val.value()); - } else if (e.ec) { - return { {}, e }; - } - if (auto [e, val] = cb_get_string(options, "clientContextId"); val) { - query_options.client_context_id(val.value()); - } else if (e.ec) { - return { {}, e }; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + if (Z_TYPE_P(item) == IS_STRING) { + params.emplace_back(cb_binary_new(item)); + } else { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + "expected encoded positional parameter to be a string" } }; + } } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("positionalParameters")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector params{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - if (Z_TYPE_P(item) == IS_STRING) { - params.emplace_back(cb_binary_new(item)); - } else { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "expected encoded positional parameter to be a string" } }; - } - } - ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_END(); - query_options.encoded_positional_parameters(params); - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("namedParameters")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map> params{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - if (Z_TYPE_P(item) == IS_STRING) { - params[cb_string_new(key)] = cb_binary_new(item); - } else { - return { {}, - { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected encoded named parameter to be a string: {}", cb_string_new(key)) } }; - } - } - ZEND_HASH_FOREACH_END(); + query_options.encoded_positional_parameters(params); + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("namedParameters")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map> params{}; + const zend_string* key = nullptr; + const zval* item = nullptr; - query_options.encoded_named_parameters(std::move(params)); + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + if (Z_TYPE_P(item) == IS_STRING) { + params[cb_string_new(key)] = cb_binary_new(item); + } else { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected encoded named parameter to be a string: {}", + cb_string_new(key)) } }; + } } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map> params{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - if (Z_TYPE_P(item) == IS_STRING) { - params[cb_string_new(key)] = cb_binary_new(item); - } else { - return { {}, - { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected encoded raw parameter to be a string: {}", cb_string_new(key)) } }; - } - } - ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_END(); - query_options.encoded_raw_options(std::move(params)); + query_options.encoded_named_parameters(std::move(params)); + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map> params{}; + const zend_string* key = nullptr; + const zval* item = nullptr; + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + if (Z_TYPE_P(item) == IS_STRING) { + params[cb_string_new(key)] = cb_binary_new(item); + } else { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected encoded raw parameter to be a string: {}", + cb_string_new(key)) } }; + } } - return { query_options, {} }; + ZEND_HASH_FOREACH_END(); + + query_options.encoded_raw_options(std::move(params)); + } + return { query_options, {} }; } std::pair zval_to_query_request(const zend_string* statement, const zval* options) { - core::operations::query_request request{ cb_string_new(statement) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return { {}, e }; - } - if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { - if (scan_consistency == "notBounded") { - request.scan_consistency = query_scan_consistency::not_bounded; - } else if (scan_consistency == "requestPlus") { - request.scan_consistency = query_scan_consistency::request_plus; - } else if (scan_consistency) { - return { {}, - { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for scan consistency: {}", *scan_consistency) } }; - } - } else if (e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(request.scan_cap, options, "scanCap"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(request.pipeline_cap, options, "pipelineCap"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(request.pipeline_batch, options, "pipelineBatch"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(request.max_parallelism, options, "maxParallelism"); e.ec) { - return { {}, e }; - } - if (auto [e, profile] = cb_get_string(options, "profile"); profile) { - if (profile == "off") { - request.profile = query_profile::off; - } else if (profile == "phases") { - request.profile = query_profile::phases; - } else if (profile == "timings") { - request.profile = query_profile::timings; - } else if (profile) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("invalid value used for profile: {}", *profile) } }; - } - } else if (e.ec) { - return { {}, e }; - } + core::operations::query_request request{ cb_string_new(statement) }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return { {}, e }; + } + if (auto [e, scan_consistency] = cb_get_string(options, "scanConsistency"); scan_consistency) { + if (scan_consistency == "notBounded") { + request.scan_consistency = query_scan_consistency::not_bounded; + } else if (scan_consistency == "requestPlus") { + request.scan_consistency = query_scan_consistency::request_plus; + } else if (scan_consistency) { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for scan consistency: {}", *scan_consistency) } }; + } + } else if (e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_integer(request.scan_cap, options, "scanCap"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_integer(request.pipeline_cap, options, "pipelineCap"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_integer(request.pipeline_batch, options, "pipelineBatch"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_integer(request.max_parallelism, options, "maxParallelism"); e.ec) { + return { {}, e }; + } + if (auto [e, profile] = cb_get_string(options, "profile"); profile) { + if (profile == "off") { + request.profile = query_profile::off; + } else if (profile == "phases") { + request.profile = query_profile::phases; + } else if (profile == "timings") { + request.profile = query_profile::timings; + } else if (profile) { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for profile: {}", *profile) } }; + } + } else if (e.ec) { + return { {}, e }; + } + + if (auto e = cb_assign_boolean(request.readonly, options, "readonly"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.flex_index, options, "flexIndex"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.adhoc, options, "adHoc"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.use_replica, options, "useReplica"); e.ec) { + return { {}, e }; + } + if (const zval* value = + zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("positionalParameters")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector params{}; + const zval* item = nullptr; - if (auto e = cb_assign_boolean(request.readonly, options, "readonly"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_boolean(request.flex_index, options, "flexIndex"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_boolean(request.adhoc, options, "adHoc"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_boolean(request.use_replica, options, "useReplica"); e.ec) { - return { {}, e }; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + auto str = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); + params.emplace_back(std::move(str)); } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("positionalParameters")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector params{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - auto str = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - params.emplace_back(std::move(str)); - } - ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_END(); - request.positional_parameters = params; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("namedParameters")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map> params{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - } - ZEND_HASH_FOREACH_END(); + request.positional_parameters = params; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("namedParameters")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map> params{}; + const zend_string* key = nullptr; + const zval* item = nullptr; - request.named_parameters = params; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map> params{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - } - ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_END(); - request.raw = params; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("consistentWith")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector vectors{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - std::uint64_t partition_uuid{ 0 }; - std::uint64_t sequence_number{ 0 }; - std::uint16_t partition_id{ 0 }; - std::string bucket_name{}; - if (auto e = cb_assign_integer(partition_id, item, "partitionId"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(partition_uuid, item, "partitionUuid"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(sequence_number, item, "sequenceNumber"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_string(bucket_name, item, "bucketName"); e.ec) { - return { {}, e }; - } - vectors.emplace_back(partition_uuid, sequence_number, partition_id, bucket_name); - } - ZEND_HASH_FOREACH_END(); + request.named_parameters = params; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map> params{}; + const zend_string* key = nullptr; + const zval* item = nullptr; - request.mutation_state = vectors; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); } - if (auto e = cb_assign_string(request.client_context_id, options, "clientContextId"); e.ec) { + ZEND_HASH_FOREACH_END(); + + request.raw = params; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("consistentWith")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector vectors{}; + const zval* item = nullptr; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + std::uint64_t partition_uuid{ 0 }; + std::uint64_t sequence_number{ 0 }; + std::uint16_t partition_id{ 0 }; + std::string bucket_name{}; + if (auto e = cb_assign_integer(partition_id, item, "partitionId"); e.ec) { return { {}, e }; - } - if (auto e = cb_assign_boolean(request.metrics, options, "metrics"); e.ec) { + } + if (auto e = cb_assign_integer(partition_uuid, item, "partitionUuid"); e.ec) { return { {}, e }; - } - if (auto e = cb_assign_boolean(request.preserve_expiry, options, "preserveExpiry"); e.ec) { + } + if (auto e = cb_assign_integer(sequence_number, item, "sequenceNumber"); e.ec) { return { {}, e }; - } - if (auto e = cb_assign_string(request.query_context, options, "queryContext"); e.ec) { + } + if (auto e = cb_assign_string(bucket_name, item, "bucketName"); e.ec) { return { {}, e }; + } + vectors.emplace_back(partition_uuid, sequence_number, partition_id, bucket_name); } - return { request, {} }; + ZEND_HASH_FOREACH_END(); + + request.mutation_state = vectors; + } + if (auto e = cb_assign_string(request.client_context_id, options, "clientContextId"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.metrics, options, "metrics"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.preserve_expiry, options, "preserveExpiry"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_string(request.query_context, options, "queryContext"); e.ec) { + return { {}, e }; + } + return { request, {} }; } void query_response_to_zval(zval* return_value, const core::operations::query_response& resp) { - array_init(return_value); - add_assoc_string(return_value, "servedByNode", resp.served_by_node.c_str()); - - zval rows; - array_init(&rows); - for (const auto& row : resp.rows) { - add_next_index_string(&rows, row.c_str()); - } - add_assoc_zval(return_value, "rows", &rows); - - zval meta; - array_init(&meta); - add_assoc_string(&meta, "clientContextId", resp.meta.client_context_id.c_str()); - add_assoc_string(&meta, "requestId", resp.meta.request_id.c_str()); - add_assoc_string(&meta, "status", resp.meta.status.c_str()); - if (resp.meta.profile.has_value()) { - add_assoc_string(&meta, "profile", resp.meta.profile.value().c_str()); - } - if (resp.meta.signature.has_value()) { - add_assoc_string(&meta, "signature", resp.meta.signature.value().c_str()); - } - if (resp.meta.metrics.has_value()) { - zval metrics; - array_init(&metrics); - add_assoc_long(&metrics, "errorCount", resp.meta.metrics.value().error_count); - add_assoc_long(&metrics, "mutationCount", resp.meta.metrics.value().mutation_count); - add_assoc_long(&metrics, "resultCount", resp.meta.metrics.value().result_count); - add_assoc_long(&metrics, "resultSize", resp.meta.metrics.value().result_size); - add_assoc_long(&metrics, "sortCount", resp.meta.metrics.value().sort_count); - add_assoc_long(&metrics, "warningCount", resp.meta.metrics.value().warning_count); - add_assoc_long( - &metrics, "elapsedTime", std::chrono::duration_cast(resp.meta.metrics.value().elapsed_time).count()); - add_assoc_long(&metrics, - "executionTime", - std::chrono::duration_cast(resp.meta.metrics.value().execution_time).count()); - - add_assoc_zval(&meta, "metrics", &metrics); - } - if (resp.meta.errors.has_value()) { - zval errors; - array_init(&errors); - for (const auto& e : resp.meta.errors.value()) { - zval error; - array_init(&error); - - add_assoc_long(&error, "code", e.code); - add_assoc_string(&error, "code", e.message.c_str()); - if (e.reason.has_value()) { - add_assoc_long(&error, "reason", e.reason.value()); - } - if (e.retry.has_value()) { - add_assoc_bool(&error, "retry", e.retry.value()); - } - - add_next_index_zval(&errors, &error); - } - add_assoc_zval(return_value, "errors", &errors); - } - if (resp.meta.warnings.has_value()) { - zval warnings; - array_init(&warnings); - for (const auto& w : resp.meta.warnings.value()) { - zval warning; - array_init(&warning); - - add_assoc_long(&warning, "code", w.code); - add_assoc_string(&warning, "code", w.message.c_str()); - if (w.reason.has_value()) { - add_assoc_long(&warning, "reason", w.reason.value()); - } - if (w.retry.has_value()) { - add_assoc_bool(&warning, "retry", w.retry.value()); - } - - add_next_index_zval(&warnings, &warning); - } - add_assoc_zval(return_value, "warnings", &warnings); - } - - add_assoc_zval(return_value, "meta", &meta); + array_init(return_value); + add_assoc_string(return_value, "servedByNode", resp.served_by_node.c_str()); + + zval rows; + array_init(&rows); + for (const auto& row : resp.rows) { + add_next_index_string(&rows, row.c_str()); + } + add_assoc_zval(return_value, "rows", &rows); + + zval meta; + array_init(&meta); + add_assoc_string(&meta, "clientContextId", resp.meta.client_context_id.c_str()); + add_assoc_string(&meta, "requestId", resp.meta.request_id.c_str()); + add_assoc_string(&meta, "status", resp.meta.status.c_str()); + if (resp.meta.profile.has_value()) { + add_assoc_string(&meta, "profile", resp.meta.profile.value().c_str()); + } + if (resp.meta.signature.has_value()) { + add_assoc_string(&meta, "signature", resp.meta.signature.value().c_str()); + } + if (resp.meta.metrics.has_value()) { + zval metrics; + array_init(&metrics); + add_assoc_long(&metrics, "errorCount", resp.meta.metrics.value().error_count); + add_assoc_long(&metrics, "mutationCount", resp.meta.metrics.value().mutation_count); + add_assoc_long(&metrics, "resultCount", resp.meta.metrics.value().result_count); + add_assoc_long(&metrics, "resultSize", resp.meta.metrics.value().result_size); + add_assoc_long(&metrics, "sortCount", resp.meta.metrics.value().sort_count); + add_assoc_long(&metrics, "warningCount", resp.meta.metrics.value().warning_count); + add_assoc_long( + &metrics, + "elapsedTime", + std::chrono::duration_cast(resp.meta.metrics.value().elapsed_time) + .count()); + add_assoc_long(&metrics, + "executionTime", + std::chrono::duration_cast( + resp.meta.metrics.value().execution_time) + .count()); + + add_assoc_zval(&meta, "metrics", &metrics); + } + if (resp.meta.errors.has_value()) { + zval errors; + array_init(&errors); + for (const auto& e : resp.meta.errors.value()) { + zval error; + array_init(&error); + + add_assoc_long(&error, "code", e.code); + add_assoc_string(&error, "code", e.message.c_str()); + if (e.reason.has_value()) { + add_assoc_long(&error, "reason", e.reason.value()); + } + if (e.retry.has_value()) { + add_assoc_bool(&error, "retry", e.retry.value()); + } + + add_next_index_zval(&errors, &error); + } + add_assoc_zval(return_value, "errors", &errors); + } + if (resp.meta.warnings.has_value()) { + zval warnings; + array_init(&warnings); + for (const auto& w : resp.meta.warnings.value()) { + zval warning; + array_init(&warning); + + add_assoc_long(&warning, "code", w.code); + add_assoc_string(&warning, "code", w.message.c_str()); + if (w.reason.has_value()) { + add_assoc_long(&warning, "reason", w.reason.value()); + } + if (w.retry.has_value()) { + add_assoc_bool(&warning, "retry", w.retry.value()); + } + + add_next_index_zval(&warnings, &warning); + } + add_assoc_zval(return_value, "warnings", &warnings); + } + + add_assoc_zval(return_value, "meta", &meta); } void search_query_response_to_zval(zval* return_value, const core::operations::search_response& resp) { - array_init(return_value); - - add_assoc_string(return_value, "status", resp.status.c_str()); - add_assoc_string(return_value, "error", resp.error.c_str()); - - zval rows; - array_init(&rows); - for (const auto& row : resp.rows) { - zval z_row; - array_init(&z_row); - add_assoc_string(&z_row, "index", row.index.c_str()); - add_assoc_string(&z_row, "id", row.id.c_str()); - add_assoc_string(&z_row, "fields", row.fields.c_str()); - add_assoc_string(&z_row, "explanation", row.explanation.c_str()); - add_assoc_double(&z_row, "score", row.score); - - zval z_locations; - array_init(&z_locations); - for (const auto& location : row.locations) { - zval z_location; - array_init(&z_location); - add_assoc_string(&z_location, "field", location.field.c_str()); - add_assoc_string(&z_location, "term", location.term.c_str()); - add_assoc_long(&z_location, "position", location.position); - add_assoc_long(&z_location, "startOffset", location.start_offset); - add_assoc_long(&z_location, "endOffset", location.end_offset); - - if (location.array_positions.has_value()) { - zval z_array_positions; - array_init(&z_array_positions); - for (const auto& position : location.array_positions.value()) { - add_next_index_long(&z_array_positions, static_cast(position)); - } - - add_assoc_zval(&z_location, "arrayPositions", &z_array_positions); - } - add_next_index_zval(&z_locations, &z_location); + array_init(return_value); + + add_assoc_string(return_value, "status", resp.status.c_str()); + add_assoc_string(return_value, "error", resp.error.c_str()); + + zval rows; + array_init(&rows); + for (const auto& row : resp.rows) { + zval z_row; + array_init(&z_row); + add_assoc_string(&z_row, "index", row.index.c_str()); + add_assoc_string(&z_row, "id", row.id.c_str()); + add_assoc_string(&z_row, "fields", row.fields.c_str()); + add_assoc_string(&z_row, "explanation", row.explanation.c_str()); + add_assoc_double(&z_row, "score", row.score); + + zval z_locations; + array_init(&z_locations); + for (const auto& location : row.locations) { + zval z_location; + array_init(&z_location); + add_assoc_string(&z_location, "field", location.field.c_str()); + add_assoc_string(&z_location, "term", location.term.c_str()); + add_assoc_long(&z_location, "position", location.position); + add_assoc_long(&z_location, "startOffset", location.start_offset); + add_assoc_long(&z_location, "endOffset", location.end_offset); + + if (location.array_positions.has_value()) { + zval z_array_positions; + array_init(&z_array_positions); + for (const auto& position : location.array_positions.value()) { + add_next_index_long(&z_array_positions, static_cast(position)); } - add_assoc_zval(&z_row, "locations", &z_locations); - zval fragments; - array_init(&fragments); - for (auto const& [field, fragment] : row.fragments) { - zval z_fragment_values; - array_init(&z_fragment_values); - - for (const auto& fragment_value : fragment) { - add_next_index_string(&z_fragment_values, fragment_value.c_str()); - } - - add_assoc_zval(&fragments, field.c_str(), &z_fragment_values); - } - add_assoc_zval(&z_row, "fragments", &fragments); - - add_next_index_zval(&rows, &z_row); - } - add_assoc_zval(return_value, "rows", &rows); - - zval metadata; - array_init(&metadata); - add_assoc_string(&metadata, "clientContextId", resp.meta.client_context_id.c_str()); - - zval metrics; - array_init(&metrics); - add_assoc_long(&metrics, "tookNanoseconds", resp.meta.metrics.took.count()); - add_assoc_long(&metrics, "totalRows", resp.meta.metrics.total_rows); - add_assoc_double(&metrics, "maxScore", resp.meta.metrics.max_score); - add_assoc_long(&metrics, "successPartitionCount", resp.meta.metrics.success_partition_count); - add_assoc_long(&metrics, "errorPartitionCount", resp.meta.metrics.error_partition_count); - add_assoc_zval(&metadata, "metrics", &metrics); - - zval errors; - array_init(&errors); - for (const auto& [location, message] : resp.meta.errors) { - add_assoc_string(&errors, location.c_str(), message.c_str()); - } - add_assoc_zval(&metadata, "errors", &errors); - - add_assoc_zval(return_value, "meta", &metadata); - - zval facets; - array_init(&facets); - for (const auto& facet : resp.facets) { - zval z_facet; - array_init(&z_facet); - add_assoc_string(&z_facet, "name", facet.name.c_str()); - add_assoc_string(&z_facet, "field", facet.field.c_str()); - add_assoc_long(&z_facet, "total", facet.total); - add_assoc_long(&z_facet, "missing", facet.missing); - add_assoc_long(&z_facet, "other", facet.other); - - zval terms; - array_init(&terms); - for (const auto& term : facet.terms) { - zval z_term; - array_init(&z_term); - add_assoc_string(&z_term, "term", term.term.c_str()); - add_assoc_long(&z_term, "count", term.count); - add_next_index_zval(&terms, &z_term); - } - add_assoc_zval(&z_facet, "terms", &terms); - - zval date_ranges; - array_init(&date_ranges); - for (const auto& range : facet.date_ranges) { - zval z_range; - array_init(&z_range); - add_assoc_string(&z_range, "name", range.name.c_str()); - add_assoc_long(&z_range, "count", range.count); - if (range.start.has_value()) { - add_assoc_string(&z_range, "start", range.start.value().c_str()); - } - if (range.end.has_value()) { - add_assoc_string(&z_range, "end", range.end.value().c_str()); - } - add_next_index_zval(&date_ranges, &z_range); - } - add_assoc_zval(&z_facet, "dateRanges", &date_ranges); - - zval numeric_ranges; - array_init(&numeric_ranges); - for (const auto& range : facet.numeric_ranges) { - zval z_range; - array_init(&z_range); - add_assoc_string(&z_range, "name", range.name.c_str()); - add_assoc_long(&z_range, "count", range.count); - if (std::holds_alternative(range.min)) { - add_assoc_long(&z_range, "min", std::get(range.min)); - } else if (std::holds_alternative(range.min)) { - add_assoc_long(&z_range, "min", std::get(range.min)); - } - if (std::holds_alternative(range.max)) { - add_assoc_long(&z_range, "max", std::get(range.max)); - } else if (std::holds_alternative(range.max)) { - add_assoc_long(&z_range, "max", std::get(range.max)); - } - add_next_index_zval(&numeric_ranges, &z_range); - } - add_assoc_zval(&z_facet, "numericRanges", &numeric_ranges); - - add_next_index_zval(&facets, &z_facet); - } - add_assoc_zval(return_value, "facets", &facets); + add_assoc_zval(&z_location, "arrayPositions", &z_array_positions); + } + add_next_index_zval(&z_locations, &z_location); + } + add_assoc_zval(&z_row, "locations", &z_locations); + + zval fragments; + array_init(&fragments); + for (auto const& [field, fragment] : row.fragments) { + zval z_fragment_values; + array_init(&z_fragment_values); + + for (const auto& fragment_value : fragment) { + add_next_index_string(&z_fragment_values, fragment_value.c_str()); + } + + add_assoc_zval(&fragments, field.c_str(), &z_fragment_values); + } + add_assoc_zval(&z_row, "fragments", &fragments); + + add_next_index_zval(&rows, &z_row); + } + add_assoc_zval(return_value, "rows", &rows); + + zval metadata; + array_init(&metadata); + add_assoc_string(&metadata, "clientContextId", resp.meta.client_context_id.c_str()); + + zval metrics; + array_init(&metrics); + add_assoc_long(&metrics, "tookNanoseconds", resp.meta.metrics.took.count()); + add_assoc_long(&metrics, "totalRows", resp.meta.metrics.total_rows); + add_assoc_double(&metrics, "maxScore", resp.meta.metrics.max_score); + add_assoc_long(&metrics, "successPartitionCount", resp.meta.metrics.success_partition_count); + add_assoc_long(&metrics, "errorPartitionCount", resp.meta.metrics.error_partition_count); + add_assoc_zval(&metadata, "metrics", &metrics); + + zval errors; + array_init(&errors); + for (const auto& [location, message] : resp.meta.errors) { + add_assoc_string(&errors, location.c_str(), message.c_str()); + } + add_assoc_zval(&metadata, "errors", &errors); + + add_assoc_zval(return_value, "meta", &metadata); + + zval facets; + array_init(&facets); + for (const auto& facet : resp.facets) { + zval z_facet; + array_init(&z_facet); + add_assoc_string(&z_facet, "name", facet.name.c_str()); + add_assoc_string(&z_facet, "field", facet.field.c_str()); + add_assoc_long(&z_facet, "total", facet.total); + add_assoc_long(&z_facet, "missing", facet.missing); + add_assoc_long(&z_facet, "other", facet.other); + + zval terms; + array_init(&terms); + for (const auto& term : facet.terms) { + zval z_term; + array_init(&z_term); + add_assoc_string(&z_term, "term", term.term.c_str()); + add_assoc_long(&z_term, "count", term.count); + add_next_index_zval(&terms, &z_term); + } + add_assoc_zval(&z_facet, "terms", &terms); + + zval date_ranges; + array_init(&date_ranges); + for (const auto& range : facet.date_ranges) { + zval z_range; + array_init(&z_range); + add_assoc_string(&z_range, "name", range.name.c_str()); + add_assoc_long(&z_range, "count", range.count); + if (range.start.has_value()) { + add_assoc_string(&z_range, "start", range.start.value().c_str()); + } + if (range.end.has_value()) { + add_assoc_string(&z_range, "end", range.end.value().c_str()); + } + add_next_index_zval(&date_ranges, &z_range); + } + add_assoc_zval(&z_facet, "dateRanges", &date_ranges); + + zval numeric_ranges; + array_init(&numeric_ranges); + for (const auto& range : facet.numeric_ranges) { + zval z_range; + array_init(&z_range); + add_assoc_string(&z_range, "name", range.name.c_str()); + add_assoc_long(&z_range, "count", range.count); + if (std::holds_alternative(range.min)) { + add_assoc_long(&z_range, "min", std::get(range.min)); + } else if (std::holds_alternative(range.min)) { + add_assoc_long(&z_range, "min", std::get(range.min)); + } + if (std::holds_alternative(range.max)) { + add_assoc_long(&z_range, "max", std::get(range.max)); + } else if (std::holds_alternative(range.max)) { + add_assoc_long(&z_range, "max", std::get(range.max)); + } + add_next_index_zval(&numeric_ranges, &z_range); + } + add_assoc_zval(&z_facet, "numericRanges", &numeric_ranges); + + add_next_index_zval(&facets, &z_facet); + } + add_assoc_zval(return_value, "facets", &facets); } std::pair -zval_to_common_search_request(const zend_string* index_name, const zend_string* query, const zval* options) +zval_to_common_search_request(const zend_string* index_name, + const zend_string* query, + const zval* options) { - couchbase::core::operations::search_request request{ cb_string_new(index_name), cb_string_new(query) }; - if (auto e = cb_assign_timeout(request, options); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_string(request.bucket_name, options, "bucketName"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(request.limit, options, "limit"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(request.skip, options, "skip"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_boolean(request.explain, options, "explain"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_boolean(request.disable_scoring, options, "disableScoring"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_boolean(request.include_locations, options, "includeLocations"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_boolean(request.show_request, options, "showRequest"); e.ec) { - return { {}, e }; + couchbase::core::operations::search_request request{ cb_string_new(index_name), + cb_string_new(query) }; + if (auto e = cb_assign_timeout(request, options); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_string(request.bucket_name, options, "bucketName"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_string(request.scope_name, options, "scopeName"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_integer(request.limit, options, "limit"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_integer(request.skip, options, "skip"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.explain, options, "explain"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.disable_scoring, options, "disableScoring"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.include_locations, options, "includeLocations"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_boolean(request.show_request, options, "showRequest"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_vector_of_strings(request.highlight_fields, options, "highlightFields"); + e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_vector_of_strings(request.fields, options, "fields"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_vector_of_strings(request.collections, options, "collections"); e.ec) { + return { {}, e }; + } + if (auto e = cb_assign_vector_of_strings(request.sort_specs, options, "sortSpecs"); e.ec) { + return { {}, e }; + } + + if (auto [e, highlight_style] = cb_get_string(options, "highlightStyle"); highlight_style) { + if (highlight_style == "html" || highlight_style == "simple") { + request.highlight_style = core::search_highlight_style::html; + } else if (highlight_style == "ansi") { + request.highlight_style = core::search_highlight_style::ansi; + } else if (highlight_style) { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid value used for highlight style: {}", *highlight_style) } }; } - if (auto e = cb_assign_vector_of_strings(request.highlight_fields, options, "highlightFields"); e.ec) { + } else if (e.ec) { + return { {}, e }; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("consistentWith")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::vector vectors{}; + const zval* item = nullptr; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + std::uint64_t partition_uuid; + std::uint64_t sequence_number; + std::uint16_t partition_id; + std::string bucket_name; + if (auto e = cb_assign_integer(partition_id, item, "partitionId"); e.ec) { return { {}, e }; - } - if (auto e = cb_assign_vector_of_strings(request.fields, options, "fields"); e.ec) { + } + if (auto e = cb_assign_integer(partition_uuid, item, "partitionUuid"); e.ec) { return { {}, e }; - } - if (auto e = cb_assign_vector_of_strings(request.collections, options, "collections"); e.ec) { + } + if (auto e = cb_assign_integer(sequence_number, item, "sequenceNumber"); e.ec) { return { {}, e }; - } - if (auto e = cb_assign_vector_of_strings(request.sort_specs, options, "sortSpecs"); e.ec) { + } + if (auto e = cb_assign_string(bucket_name, item, "bucketName"); e.ec) { return { {}, e }; + } + vectors.emplace_back( + mutation_token{ partition_uuid, sequence_number, partition_id, bucket_name }); } + ZEND_HASH_FOREACH_END(); - if (auto [e, highlight_style] = cb_get_string(options, "highlightStyle"); highlight_style) { - if (highlight_style == "html" || highlight_style == "simple") { - request.highlight_style = core::search_highlight_style::html; - } else if (highlight_style == "ansi") { - request.highlight_style = core::search_highlight_style::ansi; - } else if (highlight_style) { - return { {}, - { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("invalid value used for highlight style: {}", *highlight_style) } }; - } - } else if (e.ec) { - return { {}, e }; - } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("consistentWith")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::vector vectors{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - std::uint64_t partition_uuid; - std::uint64_t sequence_number; - std::uint16_t partition_id; - std::string bucket_name; - if (auto e = cb_assign_integer(partition_id, item, "partitionId"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(partition_uuid, item, "partitionUuid"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_integer(sequence_number, item, "sequenceNumber"); e.ec) { - return { {}, e }; - } - if (auto e = cb_assign_string(bucket_name, item, "bucketName"); e.ec) { - return { {}, e }; - } - vectors.emplace_back(mutation_token{ partition_uuid, sequence_number, partition_id, bucket_name }); - } - ZEND_HASH_FOREACH_END(); + request.mutation_state = vectors; + } - request.mutation_state = vectors; - } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map params{}; + const zend_string* key = nullptr; + const zval* item = nullptr; - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("raw")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map params{}; - const zend_string* key = nullptr; - const zval* item = nullptr; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); + } + ZEND_HASH_FOREACH_END(); - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - params[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - } - ZEND_HASH_FOREACH_END(); + request.raw = params; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("facets")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + std::map facets{}; + const zend_string* key = nullptr; + const zval* item = nullptr; - request.raw = params; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) + { + facets[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("facets")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - std::map facets{}; - const zend_string* key = nullptr; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), key, item) - { - facets[cb_string_new(key)] = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - } - ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_END(); - request.facets = facets; - } - if (auto e = cb_assign_string(request.client_context_id, options, "clientContextId"); e.ec) { - return { {}, e }; - } - return { request, {} }; + request.facets = facets; + } + if (auto e = cb_assign_string(request.client_context_id, options, "clientContextId"); e.ec) { + return { {}, e }; + } + return { request, {} }; } core_error_info cb_string_to_cas(const std::string& cas_string, couchbase::cas& cas) { - try { - std::size_t end = 0; - const std::uint64_t cas_value = std::stoull(cas_string, &end, 16); - if (end != cas_string.size()) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("trailing characters are not allowed in CAS value: \"{}\"", cas_string) }; - } - cas = couchbase::cas{ cas_value }; - } catch (const std::invalid_argument&) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("no numeric conversion could be performed for encoded CAS value: \"{}\"", cas_string) }; - } catch (const std::out_of_range&) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("the number encoded as CAS is out of the range of representable values by a unsigned long long: \"{}\"", - cas_string) }; - } - return {}; + try { + std::size_t end = 0; + const std::uint64_t cas_value = std::stoull(cas_string, &end, 16); + if (end != cas_string.size()) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("trailing characters are not allowed in CAS value: \"{}\"", + cas_string) }; + } + cas = couchbase::cas{ cas_value }; + } catch (const std::invalid_argument&) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("no numeric conversion could be performed for encoded CAS value: \"{}\"", + cas_string) }; + } catch (const std::out_of_range&) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("the number encoded as CAS is out of the range of representable values by " + "a unsigned long long: \"{}\"", + cas_string) }; + } + return {}; } std::pair> cb_get_cas(const zval* options) { - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("cas")); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_STRING: { - couchbase::cas cas; - if (auto e = cb_string_to_cas(std::string(Z_STRVAL_P(value), Z_STRLEN_P(value)), cas); e.ec) { - return { e, {} }; - } - return { {}, cas }; - } - default: - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected CAS to be a string in the options" }, {} }; - } + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("cas")); + if (value == nullptr) { return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_STRING: { + couchbase::cas cas; + if (auto e = cb_string_to_cas(std::string(Z_STRVAL_P(value), Z_STRLEN_P(value)), cas); e.ec) { + return { e, {} }; + } + return { {}, cas }; + } + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + "expected CAS to be a string in the options" }, + {} }; + } + return {}; } core_error_info cb_assign_cas(couchbase::cas& cas, const zval* document) { - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(document), ZEND_STRL("cas")); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_STRING: - break; - default: - return { errc::common::invalid_argument, ERROR_LOCATION, "expected CAS to be a string in the options" }; - } - cb_string_to_cas(std::string(Z_STRVAL_P(value), Z_STRLEN_P(value)), cas); + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(document), ZEND_STRL("cas")); + if (value == nullptr) { return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_STRING: + break; + default: + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected CAS to be a string in the options" }; + } + cb_string_to_cas(std::string(Z_STRVAL_P(value), Z_STRLEN_P(value)), cas); + return {}; } core_error_info -cb_assign_vector_of_strings(std::vector& field, const zval* options, std::string_view name) +cb_assign_vector_of_strings(std::vector& field, + const zval* options, + std::string_view name) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options" }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(value) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("expected array for options argument \"{}\"", name) }; - } + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options" }; + } - zval* item; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - if (Z_TYPE_P(item) != IS_STRING) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected \"{}\" option to be an array of strings, detected non-string value", name) }; - } - auto str = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); - field.emplace_back(cb_string_new(item)); - } - ZEND_HASH_FOREACH_END(); + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { return {}; + } + if (Z_TYPE_P(value) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected array for options argument \"{}\"", name) }; + } + + zval* item; + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + if (Z_TYPE_P(item) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format( + "expected \"{}\" option to be an array of strings, detected non-string value", + name) }; + } + auto str = std::string({ Z_STRVAL_P(item), Z_STRLEN_P(item) }); + field.emplace_back(cb_string_new(item)); + } + ZEND_HASH_FOREACH_END(); + return {}; } std::pair> cb_get_timeout(const zval* options) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("timeoutMilliseconds")); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_LONG: - break; - default: - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected timeoutMilliseconds to be a number in the options" }, {} }; - } - return { {}, std::chrono::milliseconds(Z_LVAL_P(value)) }; + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} + }; + } + + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("timeoutMilliseconds")); + if (value == nullptr) { + return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_LONG: + break; + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + "expected timeoutMilliseconds to be a number in the options" }, + {} }; + } + return { {}, std::chrono::milliseconds(Z_LVAL_P(value)) }; } std::pair> cb_get_durability_level(const zval* options) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("durabilityLevel")); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_STRING: - break; - default: - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected durabilityLevel to be a string in the options" }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { - return { {}, couchbase::durability_level::none }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majority")) == 0) { - return { {}, couchbase::durability_level::majority }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majorityAndPersistToActive")) == 0) { - return { {}, couchbase::durability_level::majority_and_persist_to_active }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("persistToMajority")) == 0) { - return { {}, couchbase::durability_level::persist_to_majority }; - } - return { { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("unknown durabilityLevel: {}", std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }, - {} }; + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} + }; + } + + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("durabilityLevel")); + if (value == nullptr) { + return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_STRING: + break; + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + "expected durabilityLevel to be a string in the options" }, + {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { + return { {}, couchbase::durability_level::none }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majority")) == 0) { + return { {}, couchbase::durability_level::majority }; + } + if (zend_binary_strcmp( + Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majorityAndPersistToActive")) == 0) { + return { {}, couchbase::durability_level::majority_and_persist_to_active }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("persistToMajority")) == + 0) { + return { {}, couchbase::durability_level::persist_to_majority }; + } + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unknown durabilityLevel: {}", + std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }, + {} }; } std::pair> cb_get_legacy_durability_persist_to(const zval* options) { - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("persistTo")); - if (value == nullptr) { - return { {}, couchbase::persist_to::none }; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return { {}, couchbase::persist_to::none }; - case IS_STRING: - break; - default: - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected persistTo to be a string in the options" }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { - return { {}, couchbase::persist_to::none }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("active")) == 0) { - return { {}, couchbase::persist_to::active }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("one")) == 0) { - return { {}, couchbase::persist_to::one }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("two")) == 0) { - return { {}, couchbase::persist_to::two }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("three")) == 0) { - return { {}, couchbase::persist_to::three }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("four")) == 0) { - return { {}, couchbase::persist_to::four }; - } - return {}; + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("persistTo")); + if (value == nullptr) { + return { {}, couchbase::persist_to::none }; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return { {}, couchbase::persist_to::none }; + case IS_STRING: + break; + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + "expected persistTo to be a string in the options" }, + {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { + return { {}, couchbase::persist_to::none }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("active")) == 0) { + return { {}, couchbase::persist_to::active }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("one")) == 0) { + return { {}, couchbase::persist_to::one }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("two")) == 0) { + return { {}, couchbase::persist_to::two }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("three")) == 0) { + return { {}, couchbase::persist_to::three }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("four")) == 0) { + return { {}, couchbase::persist_to::four }; + } + return {}; } std::pair> cb_get_legacy_durability_replicate_to(const zval* options) { - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("replicateTo")); - if (value == nullptr) { - return { {}, couchbase::replicate_to::none }; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return { {}, couchbase::replicate_to::none }; - case IS_STRING: - break; - default: - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected replicateTo to be a string in the options" }, {} }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { - return { {}, couchbase::replicate_to::none }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("one")) == 0) { - return { {}, couchbase::replicate_to::one }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("two")) == 0) { - return { {}, couchbase::replicate_to::two }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("three")) == 0) { - return { {}, couchbase::replicate_to::three }; - } - return {}; + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("replicateTo")); + if (value == nullptr) { + return { {}, couchbase::replicate_to::none }; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return { {}, couchbase::replicate_to::none }; + case IS_STRING: + break; + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + "expected replicateTo to be a string in the options" }, + {} }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { + return { {}, couchbase::replicate_to::none }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("one")) == 0) { + return { {}, couchbase::replicate_to::one }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("two")) == 0) { + return { {}, couchbase::replicate_to::two }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("three")) == 0) { + return { {}, couchbase::replicate_to::three }; + } + return {}; } std::pair>> cb_get_legacy_durability_constraints(const zval* options) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} }; - } - - auto [e1, persist_to] = cb_get_legacy_durability_persist_to(options); - if (e1.ec) { - return { e1, {} }; - } - auto [e2, replicate_to] = cb_get_legacy_durability_replicate_to(options); - if (e2.ec) { - return { e2, {} }; - } - if (!persist_to && !replicate_to) { - return {}; - } + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} + }; + } + + auto [e1, persist_to] = cb_get_legacy_durability_persist_to(options); + if (e1.ec) { + return { e1, {} }; + } + auto [e2, replicate_to] = cb_get_legacy_durability_replicate_to(options); + if (e2.ec) { + return { e2, {} }; + } + if (!persist_to && !replicate_to) { + return {}; + } - return { {}, std::make_pair(persist_to.value_or(couchbase::persist_to::none), replicate_to.value_or(couchbase::replicate_to::none)) }; + return { {}, + std::make_pair(persist_to.value_or(couchbase::persist_to::none), + replicate_to.value_or(couchbase::replicate_to::none)) }; } } // namespace couchbase::php diff --git a/src/wrapper/conversion_utilities.hxx b/src/wrapper/conversion_utilities.hxx index 0d876700..92796b4e 100644 --- a/src/wrapper/conversion_utilities.hxx +++ b/src/wrapper/conversion_utilities.hxx @@ -60,7 +60,9 @@ std::pair zval_to_transactions_query_options(const zval* options); std::pair -zval_to_common_search_request(const zend_string* index_name, const zend_string* query, const zval* options); +zval_to_common_search_request(const zend_string* index_name, + const zend_string* query, + const zval* options); void query_response_to_zval(zval* return_value, const core::operations::query_response& resp); @@ -68,88 +70,106 @@ query_response_to_zval(zval* return_value, const core::operations::query_respons void search_query_response_to_zval(zval* return_value, const core::operations::search_response& resp); -template +template static Integer parse_integer(const std::string& str, std::size_t* pos = 0, int base = 10) { - if constexpr (std::is_signed_v) { - return std::stoll(str, pos, base); - } else { - return std::stoull(str, pos, base); - } + if constexpr (std::is_signed_v) { + return std::stoll(str, pos, base); + } else { + return std::stoull(str, pos, base); + } } template static std::pair> cb_get_integer_from_hex(const zend_string* value, std::string_view name) { - auto hex_string = cb_string_new(value); - - if(hex_string.empty()) { - return { { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("unexpected empty string for {}", name) }, {} }; - } - - try { - std::size_t pos; - auto result = parse_integer(hex_string, &pos, 16); - if (result < std::numeric_limits::min() || result > std::numeric_limits::max()) { - return { { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("number out of range for {}", name) }, {} }; - } - if (pos != hex_string.length()) { - return { { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("trailing garbage in {}", name) }, {} }; - } - return {{}, result}; - } catch (const std::invalid_argument& e) { - return { { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("invalid hex number for {}", name) }, {} }; - } catch (const std::out_of_range& e) { - return { { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("number out of range for {}", name) }, {} }; - } + auto hex_string = cb_string_new(value); + + if (hex_string.empty()) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unexpected empty string for {}", name) }, + {} }; + } + + try { + std::size_t pos; + auto result = parse_integer(hex_string, &pos, 16); + if (result < std::numeric_limits::min() || + result > std::numeric_limits::max()) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("number out of range for {}", name) }, + {} }; + } + if (pos != hex_string.length()) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("trailing garbage in {}", name) }, + {} }; + } + return { {}, result }; + } catch (const std::invalid_argument& e) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("invalid hex number for {}", name) }, + {} }; + } catch (const std::out_of_range& e) { + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("number out of range for {}", name) }, + {} }; + } } template static std::pair> cb_get_integer(const zval* options, std::string_view name) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_LONG: - break; - case IS_STRING: - return cb_get_integer_from_hex(Z_STR_P(value), name); - default: - return { - { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("expected {} to be a integer value in the options", name) }, - {} - }; - } - - return { {}, Z_LVAL_P(value) }; + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { + return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }, {} + }; + } + + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); + if (value == nullptr) { + return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_LONG: + break; + case IS_STRING: + return cb_get_integer_from_hex(Z_STR_P(value), name); + default: + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected {} to be a integer value in the options", name) }, + {} }; + } + + return { {}, Z_LVAL_P(value) }; } template core_error_info cb_assign_integer(Integer& field, const zval* options, std::string_view name) { - auto [e, value] = cb_get_integer(options, name); - if (e.ec) { - return e; - } - if (value) { - field = *value; - } - return {}; + auto [e, value] = cb_get_integer(options, name); + if (e.ec) { + return e; + } + if (value) { + field = *value; + } + return {}; } std::pair> @@ -159,14 +179,14 @@ template core_error_info cb_assign_string(String& field, const zval* options, std::string_view name) { - auto [e, value] = cb_get_string(options, name); - if (e.ec) { - return e; - } - if (value) { - field = *value; - } - return {}; + auto [e, value] = cb_get_string(options, name); + if (e.ec) { + return e; + } + if (value) { + field = *value; + } + return {}; } std::pair>> @@ -176,14 +196,14 @@ template core_error_info cb_assign_binary(Binary& field, const zval* options, std::string_view name) { - auto [e, value] = cb_get_binary(options, name); - if (e.ec) { - return e; - } - if (value) { - field = *value; - } - return {}; + auto [e, value] = cb_get_binary(options, name); + if (e.ec) { + return e; + } + if (value) { + field = *value; + } + return {}; } std::pair> @@ -193,77 +213,77 @@ template core_error_info cb_assign_timeout(Request& req, const zval* options) { - auto [err, timeout] = cb_get_timeout(options); - if (!err.ec && timeout) { - req.timeout = timeout.value(); - return {}; - } - return err; + auto [err, timeout] = cb_get_timeout(options); + if (!err.ec && timeout) { + req.timeout = timeout.value(); + return {}; + } + return err; } template core_error_info cb_set_expiry(Options& opts, const zval* options) { - if (auto [e, value] = cb_get_integer(options, "expirySeconds"); e.ec) { - return e; - } else if (value) { - try { - opts.expiry(std::chrono::seconds{ value.value() }); - } catch (const std::system_error& ec) { - return { ec.code(), ERROR_LOCATION, ec.what() }; - } - return {}; + if (auto [e, value] = cb_get_integer(options, "expirySeconds"); e.ec) { + return e; + } else if (value) { + try { + opts.expiry(std::chrono::seconds{ value.value() }); + } catch (const std::system_error& ec) { + return { ec.code(), ERROR_LOCATION, ec.what() }; } + return {}; + } - if (auto [e, value] = cb_get_integer(options, "expiryTimestamp"); e.ec) { - return e; - } else if (value) { - try { - opts.expiry(std::chrono::system_clock::time_point{ std::chrono::seconds{ value.value() } }); - } catch (const std::system_error& ec) { - return { ec.code(), ERROR_LOCATION, ec.what() }; - } + if (auto [e, value] = cb_get_integer(options, "expiryTimestamp"); e.ec) { + return e; + } else if (value) { + try { + opts.expiry(std::chrono::system_clock::time_point{ std::chrono::seconds{ value.value() } }); + } catch (const std::system_error& ec) { + return { ec.code(), ERROR_LOCATION, ec.what() }; } - return {}; + } + return {}; } template core_error_info cb_set_initial_value(Options& opts, const zval* options) { - if (auto [e, value] = cb_get_integer(options, "initialValue"); e.ec) { - return e; - } else if (value) { - opts.initial(value.value()); - } - return {}; + if (auto [e, value] = cb_get_integer(options, "initialValue"); e.ec) { + return e; + } else if (value) { + opts.initial(value.value()); + } + return {}; } template core_error_info cb_set_delta(Options& opts, const zval* options) { - if (auto [e, value] = cb_get_integer(options, "delta"); e.ec) { - return e; - } else if (value) { - opts.delta(value.value()); - } - return {}; + if (auto [e, value] = cb_get_integer(options, "delta"); e.ec) { + return e; + } else if (value) { + opts.delta(value.value()); + } + return {}; } template core_error_info cb_set_timeout(Options& opts, const zval* options) { - auto [err, timeout] = cb_get_timeout(options); - if (err.ec) { - return err; - } - if (timeout) { - opts.timeout(timeout.value()); - } - return {}; + auto [err, timeout] = cb_get_timeout(options); + if (err.ec) { + return err; + } + if (timeout) { + opts.timeout(timeout.value()); + } + return {}; } std::pair> @@ -273,42 +293,42 @@ template core_error_info cb_set_access_deleted(Options& opts, const zval* options) { - auto [err, value] = cb_get_boolean(options, "accessDeleted"); - if (err.ec) { - return err; - } - if (value.has_value()) { - opts.access_deleted(value.value()); - } - return {}; + auto [err, value] = cb_get_boolean(options, "accessDeleted"); + if (err.ec) { + return err; + } + if (value.has_value()) { + opts.access_deleted(value.value()); + } + return {}; } template core_error_info cb_set_preserve_expiry(Options& opts, const zval* options) { - auto [err, value] = cb_get_boolean(options, "preserveExpiry"); - if (err.ec) { - return err; - } - if (value.has_value()) { - opts.preserve_expiry(value.value()); - } - return {}; + auto [err, value] = cb_get_boolean(options, "preserveExpiry"); + if (err.ec) { + return err; + } + if (value.has_value()) { + opts.preserve_expiry(value.value()); + } + return {}; } template core_error_info cb_set_create_as_deleted(Options& opts, const zval* options) { - auto [err, value] = cb_get_boolean(options, "createAsDeleted"); - if (err.ec) { - return err; - } - if (value.has_value()) { - opts.create_as_deleted(value.value()); - } - return {}; + auto [err, value] = cb_get_boolean(options, "createAsDeleted"); + if (err.ec) { + return err; + } + if (value.has_value()) { + opts.create_as_deleted(value.value()); + } + return {}; } std::pair> @@ -318,46 +338,48 @@ template core_error_info cb_set_cas(Options& opts, const zval* options) { - auto [err, value] = cb_get_cas(options); - if (err.ec) { - return err; - } - if (value.has_value()) { - opts.cas(value.value()); - } - return {}; + auto [err, value] = cb_get_cas(options); + if (err.ec) { + return err; + } + if (value.has_value()) { + opts.cas(value.value()); + } + return {}; } template core_error_info cb_assign_boolean(Boolean& field, const zval* options, std::string_view name) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }; - } - - const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); - if (value == nullptr) { - return {}; - } - switch (Z_TYPE_P(value)) { - case IS_NULL: - return {}; - case IS_TRUE: - field = true; - break; - case IS_FALSE: - field = false; - break; - default: - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected {} to be a boolean value in the options", name) }; - } + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected array for options argument" }; + } + + const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), name.data(), name.size()); + if (value == nullptr) { + return {}; + } + switch (Z_TYPE_P(value)) { + case IS_NULL: + return {}; + case IS_TRUE: + field = true; + break; + case IS_FALSE: + field = false; + break; + default: + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected {} to be a boolean value in the options", name) }; + } + return {}; } core_error_info @@ -367,7 +389,9 @@ core_error_info cb_assign_cas(couchbase::cas& cas, const zval* document); core_error_info -cb_assign_vector_of_strings(std::vector& field, const zval* options, std::string_view name); +cb_assign_vector_of_strings(std::vector& field, + const zval* options, + std::string_view name); std::pair> cb_get_durability_level(const zval* options); @@ -379,50 +403,52 @@ template core_error_info cb_set_durability(Options& opts, const zval* options) { - if (auto [e, level] = cb_get_durability_level(options); e.ec) { - return e; - } else if (level) { - opts.durability(level.value()); - return {}; - } - - if (auto [e, constraints] = cb_get_legacy_durability_constraints(options); e.ec) { - return e; - } else if (constraints) { - opts.durability(constraints->first, constraints->second); - return {}; - } + if (auto [e, level] = cb_get_durability_level(options); e.ec) { + return e; + } else if (level) { + opts.durability(level.value()); + return {}; + } + if (auto [e, constraints] = cb_get_legacy_durability_constraints(options); e.ec) { + return e; + } else if (constraints) { + opts.durability(constraints->first, constraints->second); return {}; + } + + return {}; } template core_error_info cb_set_store_semantics(Options& opts, const zval* options) { - if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { - return {}; - } - if (Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for options argument" }; - } - - if (auto [e, value] = cb_get_string(options, "storeSemantics"); e.ec) { - return e; - } else if (value) { - if (value.value() == "replace") { - opts.store_semantics(store_semantics::replace); - } else if (value.value() == "insert") { - opts.store_semantics(store_semantics::insert); - } else if (value.value() == "upsert") { - opts.store_semantics(store_semantics::upsert); - } else if (!value.value().empty()) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("unexpected value for storeSemantics option: {}", value.value()) }; - } - } + if (options == nullptr || Z_TYPE_P(options) == IS_NULL) { return {}; + } + if (Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected array for options argument" }; + } + + if (auto [e, value] = cb_get_string(options, "storeSemantics"); e.ec) { + return e; + } else if (value) { + if (value.value() == "replace") { + opts.store_semantics(store_semantics::replace); + } else if (value.value() == "insert") { + opts.store_semantics(store_semantics::insert); + } else if (value.value() == "upsert") { + opts.store_semantics(store_semantics::upsert); + } else if (!value.value().empty()) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unexpected value for storeSemantics option: {}", value.value()) }; + } + } + return {}; } } // namespace couchbase::php diff --git a/src/wrapper/core_error_info.hxx b/src/wrapper/core_error_info.hxx index 6d5f7c5e..fa9fbdfa 100644 --- a/src/wrapper/core_error_info.hxx +++ b/src/wrapper/core_error_info.hxx @@ -18,177 +18,171 @@ #include "api_visibility.hxx" +#include #include #include #include #include #include -#include namespace couchbase::php { // TODO: use std::source_location when C++20 supported struct source_location { - std::uint32_t line{}; - std::string file_name{}; - std::string function_name{}; + std::uint32_t line{}; + std::string file_name{}; + std::string function_name{}; }; struct empty_error_context { }; struct common_error_context { - std::optional last_dispatched_to{}; - std::optional last_dispatched_from{}; - int retry_attempts{ 0 }; - std::set> retry_reasons{}; + std::optional last_dispatched_to{}; + std::optional last_dispatched_from{}; + int retry_attempts{ 0 }; + std::set> retry_reasons{}; }; struct common_http_error_context : public common_error_context { - std::string client_context_id{}; - std::uint32_t http_status{}; - std::string http_body{}; + std::string client_context_id{}; + std::uint32_t http_status{}; + std::string http_body{}; }; struct key_value_error_context : public common_error_context { - std::string bucket; - std::string scope; - std::string collection; - std::string id; - std::uint32_t opaque{}; - std::uint64_t cas{}; - std::optional status_code{}; - std::optional error_map_name{}; - std::optional error_map_description{}; - std::optional enhanced_error_reference{}; - std::optional enhanced_error_context{}; + std::string bucket; + std::string scope; + std::string collection; + std::string id; + std::uint32_t opaque{}; + std::uint64_t cas{}; + std::optional status_code{}; + std::optional error_map_name{}; + std::optional error_map_description{}; + std::optional enhanced_error_reference{}; + std::optional enhanced_error_context{}; }; struct subdocument_error_context : public key_value_error_context { - bool deleted; - std::optional first_error_index{}; - std::optional first_error_path{}; + bool deleted; + std::optional first_error_index{}; + std::optional first_error_path{}; }; struct query_error_context : public common_http_error_context { - std::uint64_t first_error_code{}; - std::string first_error_message{}; - std::string statement{}; - std::optional parameters{}; + std::uint64_t first_error_code{}; + std::string first_error_message{}; + std::string statement{}; + std::optional parameters{}; }; struct analytics_error_context : public common_http_error_context { - std::uint64_t first_error_code{}; - std::string first_error_message{}; - std::string statement{}; - std::optional parameters{}; + std::uint64_t first_error_code{}; + std::string first_error_message{}; + std::string statement{}; + std::optional parameters{}; }; struct view_query_error_context : public common_http_error_context { - std::string design_document_name{}; - std::string view_name{}; - std::vector query_string{}; + std::string design_document_name{}; + std::string view_name{}; + std::vector query_string{}; }; struct search_error_context : public common_http_error_context { - std::string index_name{}; - std::optional query{}; - std::optional parameters{}; + std::string index_name{}; + std::optional query{}; + std::optional parameters{}; }; struct http_error_context : public common_http_error_context { - std::string method{}; - std::string path{}; + std::string method{}; + std::string path{}; }; struct transactions_error_context { - struct transaction_result { - std::string transaction_id; - bool unstaging_complete; - }; - std::optional should_not_retry{}; - std::optional should_not_rollback{}; - std::optional type{}; - std::optional cause{}; - std::optional result{}; + struct transaction_result { + std::string transaction_id; + bool unstaging_complete; + }; + std::optional should_not_retry{}; + std::optional should_not_rollback{}; + std::optional type{}; + std::optional cause{}; + std::optional result{}; }; #if defined(__GNUC__) || defined(__clang__) -#define ERROR_LOCATION \ - { \ - __LINE__, __FILE__, __PRETTY_FUNCTION__ \ - } +#define ERROR_LOCATION { __LINE__, __FILE__, __PRETTY_FUNCTION__ } #else -#define ERROR_LOCATION \ - { \ - __LINE__, __FILE__, __FUNCTION__ \ - } +#define ERROR_LOCATION { __LINE__, __FILE__, __FUNCTION__ } #endif struct core_error_info { - std::error_code ec{}; - source_location location{}; - std::string message{}; - std::variant - error_context{}; + std::error_code ec{}; + source_location location{}; + std::string message{}; + std::variant + error_context{}; }; enum class transactions_errc { - operation_failed = 1101, - std_exception = 1102, - unexpected_exception = 1103, - failed = 1104, - expired = 1105, - commit_ambiguous = 1106, + operation_failed = 1101, + std_exception = 1102, + unexpected_exception = 1103, + failed = 1104, + expired = 1105, + commit_ambiguous = 1106, }; namespace detail { struct transactions_error_category : std::error_category { - [[nodiscard]] const char* name() const noexcept override - { - return "couchbase.transactions"; - } - - [[nodiscard]] std::string message(int ev) const noexcept override - { - switch (static_cast(ev)) { - case transactions_errc::operation_failed: - return "operation_failed"; - case transactions_errc::std_exception: - return "std_exception"; - case transactions_errc::unexpected_exception: - return "unexpected_exception"; - case transactions_errc::failed: - return "failed"; - case transactions_errc::expired: - return "expired"; - case transactions_errc::commit_ambiguous: - return "commit_ambiguous"; - } - return "FIXME: unknown error code in transactions category (recompile with newer library)"; + [[nodiscard]] const char* name() const noexcept override + { + return "couchbase.transactions"; + } + + [[nodiscard]] std::string message(int ev) const noexcept override + { + switch (static_cast(ev)) { + case transactions_errc::operation_failed: + return "operation_failed"; + case transactions_errc::std_exception: + return "std_exception"; + case transactions_errc::unexpected_exception: + return "unexpected_exception"; + case transactions_errc::failed: + return "failed"; + case transactions_errc::expired: + return "expired"; + case transactions_errc::commit_ambiguous: + return "commit_ambiguous"; } + return "FIXME: unknown error code in transactions category (recompile with newer library)"; + } }; inline const std::error_category& get_transactions_category() { - static detail::transactions_error_category instance; - return instance; + static detail::transactions_error_category instance; + return instance; } } // namespace detail inline std::error_code make_error_code(transactions_errc e) { - return { static_cast(e), detail::get_transactions_category() }; + return { static_cast(e), detail::get_transactions_category() }; } } // namespace couchbase::php diff --git a/src/wrapper/logger.cxx b/src/wrapper/logger.cxx index cc237f8a..87ad352b 100644 --- a/src/wrapper/logger.cxx +++ b/src/wrapper/logger.cxx @@ -42,136 +42,142 @@ namespace couchbase::php template class php_log_err_sink : public spdlog::sinks::base_sink { - public: - void flush_deferred_messages() - { - std::lock_guard lock(spdlog::sinks::base_sink::mutex_); - auto messages_ = std::move(deferred_messages_); - while (!messages_.empty()) { - write_message(messages_.front()); - messages_.pop(); - } +public: + void flush_deferred_messages() + { + std::lock_guard lock(spdlog::sinks::base_sink::mutex_); + auto messages_ = std::move(deferred_messages_); + while (!messages_.empty()) { + write_message(messages_.front()); + messages_.pop(); } - - void include_source_info(bool include) - { - include_source_info_ = include; - } - - protected: - struct log_message_for_php { - spdlog::level::level_enum level{}; - spdlog::log_clock::time_point time{}; - size_t thread_id{}; - std::string payload{}; - const char* filename{}; - int line{}; - const char* funcname{}; + } + + void include_source_info(bool include) + { + include_source_info_ = include; + } + +protected: + struct log_message_for_php { + spdlog::level::level_enum level{}; + spdlog::log_clock::time_point time{}; + size_t thread_id{}; + std::string payload{}; + const char* filename{}; + int line{}; + const char* funcname{}; + }; + + void sink_it_(const spdlog::details::log_msg& msg) override + { + tao::json::value data = { + { "level", fmt::format("{}", spdlog::level::to_string_view(msg.level)) }, + { "time", + fmt::format("{:%F %T}.{}", msg.time, msg.time.time_since_epoch().count() % 1'000'000) }, + { "message", std::string(msg.payload.data(), msg.payload.size()) }, + { "thread_id", msg.thread_id }, }; - - void sink_it_(const spdlog::details::log_msg& msg) override - { - tao::json::value data = { - { "level", fmt::format("{}", spdlog::level::to_string_view(msg.level)) }, - { "time", fmt::format("{:%F %T}.{}", msg.time, msg.time.time_since_epoch().count() % 1'000'000) }, - { "message", std::string(msg.payload.data(), msg.payload.size()) }, - { "thread_id", msg.thread_id }, - }; - if (include_source_info_ && !msg.source.empty()) { - data["source"] = { - { "file", msg.source.filename }, - { "line", msg.source.line }, - { "func", msg.source.funcname }, - }; - } - deferred_messages_.emplace(std::move(data)); + if (include_source_info_ && !msg.source.empty()) { + data["source"] = { + { "file", msg.source.filename }, + { "line", msg.source.line }, + { "func", msg.source.funcname }, + }; } + deferred_messages_.emplace(std::move(data)); + } - void flush_() override - { - /* do nothing here, the flush will be initiated by the SDK */ - } + void flush_() override + { + /* do nothing here, the flush will be initiated by the SDK */ + } - private: - void write_message(const tao::json::value& msg) - { +private: + void write_message(const tao::json::value& msg) + { #if PHP_VERSION_ID >= 80000 - php_log_err(core::utils::json::generate(msg).c_str()); + php_log_err(core::utils::json::generate(msg).c_str()); #else - auto data = core::utils::json::generate(msg); - php_log_err(const_cast(data.c_str())); + auto data = core::utils::json::generate(msg); + php_log_err(const_cast(data.c_str())); #endif - } + } - std::queue deferred_messages_{}; - bool include_source_info_{ false }; + std::queue deferred_messages_{}; + bool include_source_info_{ false }; }; -const static std::shared_ptr> global_php_log_err_sink{ std::make_shared>() }; +const static std::shared_ptr> global_php_log_err_sink{ + std::make_shared>() +}; COUCHBASE_API void flush_logger() { - if (global_php_log_err_sink) { - global_php_log_err_sink->flush_deferred_messages(); - } + if (global_php_log_err_sink) { + global_php_log_err_sink->flush_deferred_messages(); + } } COUCHBASE_API void shutdown_logger() { - flush_logger(); - couchbase::core::logger::shutdown(); + flush_logger(); + couchbase::core::logger::shutdown(); } - COUCHBASE_API void initialize_logger() { - auto spd_log_level = spdlog::level::off; - auto cbpp_log_level = couchbase::core::logger::level::off; - if (auto env_val = spdlog::details::os::getenv("COUCHBASE_LOG_LEVEL"); !env_val.empty()) { - cbpp_log_level = couchbase::core::logger::level_from_str(env_val); - spd_log_level = spdlog::level::from_str(env_val); + auto spd_log_level = spdlog::level::off; + auto cbpp_log_level = couchbase::core::logger::level::off; + if (auto env_val = spdlog::details::os::getenv("COUCHBASE_LOG_LEVEL"); !env_val.empty()) { + cbpp_log_level = couchbase::core::logger::level_from_str(env_val); + spd_log_level = spdlog::level::from_str(env_val); + } + if (const char* ini_val = COUCHBASE_G(log_level); ini_val != nullptr) { + std::string log_level(ini_val); + if (!log_level.empty()) { + std::transform(log_level.begin(), log_level.end(), log_level.begin(), [](auto c) { + return std::tolower(c); + }); + if (log_level == "fatal" || log_level == "fatl") { + log_level = "critical"; + } else if (log_level == "trac") { + log_level = "trace"; + } else if (log_level == "debg") { + log_level = "debug"; + } else if (log_level == "eror") { + log_level = "error"; + } + cbpp_log_level = couchbase::core::logger::level_from_str(log_level); + spd_log_level = spdlog::level::from_str(log_level); } - if (const char* ini_val = COUCHBASE_G(log_level); ini_val != nullptr) { - std::string log_level(ini_val); - if (!log_level.empty()) { - std::transform(log_level.begin(), log_level.end(), log_level.begin(), [](auto c) { return std::tolower(c); }); - if (log_level == "fatal" || log_level == "fatl") { - log_level = "critical"; - } else if (log_level == "trac") { - log_level = "trace"; - } else if (log_level == "debg") { - log_level = "debug"; - } else if (log_level == "eror") { - log_level = "error"; - } - cbpp_log_level = couchbase::core::logger::level_from_str(log_level); - spd_log_level = spdlog::level::from_str(log_level); - } + } + + if (cbpp_log_level != couchbase::core::logger::level::off) { + couchbase::core::logger::configuration configuration{}; + if (const char* ini_val = COUCHBASE_G(log_path); + ini_val != nullptr && std::strlen(ini_val) > 0) { + configuration.filename = ini_val; + configuration.filename += fmt::format(".{}", spdlog::details::os::pid()); } - - if (cbpp_log_level != couchbase::core::logger::level::off) { - couchbase::core::logger::configuration configuration{}; - if (const char* ini_val = COUCHBASE_G(log_path); ini_val != nullptr && std::strlen(ini_val) > 0) { - configuration.filename = ini_val; - configuration.filename += fmt::format(".{}", spdlog::details::os::pid()); - } - configuration.unit_test = true; - configuration.console = COUCHBASE_G(log_stderr); - configuration.log_level = cbpp_log_level; - if (COUCHBASE_G(log_php_log_err)) { - configuration.sink = global_php_log_err_sink; - global_php_log_err_sink->include_source_info(cbpp_log_level == couchbase::core::logger::level::trace); - } - couchbase::core::logger::create_file_logger(configuration); + configuration.unit_test = true; + configuration.console = COUCHBASE_G(log_stderr); + configuration.log_level = cbpp_log_level; + if (COUCHBASE_G(log_php_log_err)) { + configuration.sink = global_php_log_err_sink; + global_php_log_err_sink->include_source_info(cbpp_log_level == + couchbase::core::logger::level::trace); } + couchbase::core::logger::create_file_logger(configuration); + } - spdlog::set_level(spd_log_level); - couchbase::core::logger::set_log_levels(cbpp_log_level); + spdlog::set_level(spd_log_level); + couchbase::core::logger::set_log_levels(cbpp_log_level); } } // namespace couchbase::php diff --git a/src/wrapper/passthrough_transcoder.hxx b/src/wrapper/passthrough_transcoder.hxx index c9ae718d..4911631d 100644 --- a/src/wrapper/passthrough_transcoder.hxx +++ b/src/wrapper/passthrough_transcoder.hxx @@ -26,17 +26,17 @@ namespace php { struct passthrough_transcoder { - using document_type = codec::encoded_value; + using document_type = codec::encoded_value; - static auto decode(const codec::encoded_value& data) -> document_type - { - return data; - } + static auto decode(const codec::encoded_value& data) -> document_type + { + return data; + } - static auto encode(codec::encoded_value document) -> codec::encoded_value - { - return document; - } + static auto encode(codec::encoded_value document) -> codec::encoded_value + { + return document; + } }; } // namespace php diff --git a/src/wrapper/persistent_connections_cache.cxx b/src/wrapper/persistent_connections_cache.cxx index dc0a8d81..9630b6fb 100644 --- a/src/wrapper/persistent_connections_cache.cxx +++ b/src/wrapper/persistent_connections_cache.cxx @@ -35,143 +35,157 @@ COUCHBASE_API void set_persistent_connection_destructor_id(int id) { - persistent_connection_destructor_id_ = id; + persistent_connection_destructor_id_ = id; } COUCHBASE_API int get_persistent_connection_destructor_id() { - return persistent_connection_destructor_id_; + return persistent_connection_destructor_id_; } COUCHBASE_API int check_persistent_connection(zval* zv) { - zend_resource* res = Z_RES_P(zv); - auto now = std::chrono::system_clock::now(); + zend_resource* res = Z_RES_P(zv); + auto now = std::chrono::system_clock::now(); - if (res->type == persistent_connection_destructor_id_) { - auto const* connection = static_cast(res->ptr); - if (COUCHBASE_G(persistent_timeout) != -1 && connection->is_expired(now)) { - /* connection has timed out */ - return ZEND_HASH_APPLY_REMOVE; - } + if (res->type == persistent_connection_destructor_id_) { + auto const* connection = static_cast(res->ptr); + if (COUCHBASE_G(persistent_timeout) != -1 && connection->is_expired(now)) { + /* connection has timed out */ + return ZEND_HASH_APPLY_REMOVE; } - return ZEND_HASH_APPLY_KEEP; + } + return ZEND_HASH_APPLY_KEEP; } COUCHBASE_API std::pair -create_persistent_connection(zend_string* connection_hash, zend_string* connection_string, zval* options) +create_persistent_connection(zend_string* connection_hash, + zend_string* connection_string, + zval* options) { - connection_handle* handle = nullptr; - bool found = false; + connection_handle* handle = nullptr; + bool found = false; - if (zval* entry = zend_hash_find(&EG(persistent_list), connection_hash); entry != nullptr) { - zend_resource* res = Z_RES_P(entry); - found = true; - if (res->type == persistent_connection_destructor_id_) { - handle = static_cast(res->ptr); - } - } - auto now = std::chrono::system_clock::now(); - auto expires_at = COUCHBASE_G(persistent_timeout) > 0 ? now + std::chrono::milliseconds(COUCHBASE_G(persistent_timeout)) : now; - if (handle != nullptr) { - handle->expires_at(expires_at); - CB_LOG_DEBUG("persistent connection hit: handle={}, connection_hash={}, connection_string=\"{}\", " - "expires_at=\"{}\" ({}), destructor_id={}", - static_cast(handle), - ZSTR_VAL(connection_hash), - ZSTR_VAL(connection_string), - expires_at, - (expires_at - now), - persistent_connection_destructor_id_); - return { zend_register_resource(handle, persistent_connection_destructor_id_), {} }; - } - if (found) { - /* found something, which is not our resource */ - CB_LOG_DEBUG("persistent connection hit, but handle=nullptr: connection_hash={}, connection_string=\"{}\", destructor_id={}", - ZSTR_VAL(connection_hash), - ZSTR_VAL(connection_string), - persistent_connection_destructor_id_); - zend_hash_del(&EG(persistent_list), connection_hash); + if (zval* entry = zend_hash_find(&EG(persistent_list), connection_hash); entry != nullptr) { + zend_resource* res = Z_RES_P(entry); + found = true; + if (res->type == persistent_connection_destructor_id_) { + handle = static_cast(res->ptr); } + } + auto now = std::chrono::system_clock::now(); + auto expires_at = COUCHBASE_G(persistent_timeout) > 0 + ? now + std::chrono::milliseconds(COUCHBASE_G(persistent_timeout)) + : now; + if (handle != nullptr) { + handle->expires_at(expires_at); + CB_LOG_DEBUG( + "persistent connection hit: handle={}, connection_hash={}, connection_string=\"{}\", " + "expires_at=\"{}\" ({}), destructor_id={}", + static_cast(handle), + ZSTR_VAL(connection_hash), + ZSTR_VAL(connection_string), + expires_at, + (expires_at - now), + persistent_connection_destructor_id_); + return { zend_register_resource(handle, persistent_connection_destructor_id_), {} }; + } + if (found) { + /* found something, which is not our resource */ + CB_LOG_DEBUG("persistent connection hit, but handle=nullptr: connection_hash={}, " + "connection_string=\"{}\", destructor_id={}", + ZSTR_VAL(connection_hash), + ZSTR_VAL(connection_string), + persistent_connection_destructor_id_); + zend_hash_del(&EG(persistent_list), connection_hash); + } - if (COUCHBASE_G(max_persistent) != -1 && COUCHBASE_G(num_persistent) >= COUCHBASE_G(max_persistent)) { - /* try to find an idle connection and kill it */ - CB_LOG_DEBUG("cleanup idle connections. max_persistent({}) != -1, num_persistent({}) >= max_persistent", - COUCHBASE_G(max_persistent), - COUCHBASE_G(num_persistent)); - zend_hash_apply(&EG(persistent_list), check_persistent_connection); - } else { - CB_LOG_DEBUG( - "don't cleanup idle connections. max_persistent={}, num_persistent={}", COUCHBASE_G(max_persistent), COUCHBASE_G(num_persistent)); - } + if (COUCHBASE_G(max_persistent) != -1 && + COUCHBASE_G(num_persistent) >= COUCHBASE_G(max_persistent)) { + /* try to find an idle connection and kill it */ + CB_LOG_DEBUG( + "cleanup idle connections. max_persistent({}) != -1, num_persistent({}) >= max_persistent", + COUCHBASE_G(max_persistent), + COUCHBASE_G(num_persistent)); + zend_hash_apply(&EG(persistent_list), check_persistent_connection); + } else { + CB_LOG_DEBUG("don't cleanup idle connections. max_persistent={}, num_persistent={}", + COUCHBASE_G(max_persistent), + COUCHBASE_G(num_persistent)); + } - core_error_info rc; - std::tie(handle, rc) = create_connection_handle(connection_string, connection_hash, options, expires_at); - if (rc.ec) { - CB_LOG_DEBUG( - "persistent connection miss, failed to create new connection: rc={} ({}), connection_hash={}, connection_string=\"{}\", " - "destructor_id={}", - rc.ec.message(), - rc.message, - ZSTR_VAL(connection_hash), - ZSTR_VAL(connection_string), - persistent_connection_destructor_id_); - return { nullptr, rc }; - } + core_error_info rc; + std::tie(handle, rc) = + create_connection_handle(connection_string, connection_hash, options, expires_at); + if (rc.ec) { + CB_LOG_DEBUG("persistent connection miss, failed to create new connection: rc={} ({}), " + "connection_hash={}, connection_string=\"{}\", " + "destructor_id={}", + rc.ec.message(), + rc.message, + ZSTR_VAL(connection_hash), + ZSTR_VAL(connection_string), + persistent_connection_destructor_id_); + return { nullptr, rc }; + } - if (rc = handle->open(); rc.ec) { - CB_LOG_DEBUG("persistent connection miss, failed to open new connection: rc={} ({}), connection_hash={}, connection_string=\"{}\", " - "destructor_id={}", - rc.ec.message(), - rc.message, - ZSTR_VAL(connection_hash), - ZSTR_VAL(connection_string), - persistent_connection_destructor_id_); - delete handle; - return { nullptr, rc }; - } - zend_register_persistent_resource_ex(zend_string_dup(connection_hash, 1), handle, persistent_connection_destructor_id_); - auto current_persistent = ++COUCHBASE_G(num_persistent); - CB_LOG_DEBUG("persistent connection miss, created new connection: handle={}, connection_hash={}, connection_string=\"{}\", " - "expires_at=\"{}\" ({}), destructor_id={}, num_persistent={}", - static_cast(handle), + if (rc = handle->open(); rc.ec) { + CB_LOG_DEBUG("persistent connection miss, failed to open new connection: rc={} ({}), " + "connection_hash={}, connection_string=\"{}\", " + "destructor_id={}", + rc.ec.message(), + rc.message, ZSTR_VAL(connection_hash), ZSTR_VAL(connection_string), - expires_at, - (expires_at - now), - persistent_connection_destructor_id_, - current_persistent); - return { zend_register_resource(handle, persistent_connection_destructor_id_), {} }; + persistent_connection_destructor_id_); + delete handle; + return { nullptr, rc }; + } + zend_register_persistent_resource_ex( + zend_string_dup(connection_hash, 1), handle, persistent_connection_destructor_id_); + auto current_persistent = ++COUCHBASE_G(num_persistent); + CB_LOG_DEBUG("persistent connection miss, created new connection: handle={}, connection_hash={}, " + "connection_string=\"{}\", " + "expires_at=\"{}\" ({}), destructor_id={}, num_persistent={}", + static_cast(handle), + ZSTR_VAL(connection_hash), + ZSTR_VAL(connection_string), + expires_at, + (expires_at - now), + persistent_connection_destructor_id_, + current_persistent); + return { zend_register_resource(handle, persistent_connection_destructor_id_), {} }; } COUCHBASE_API void destroy_persistent_connection(zend_resource* res) { - if (res->type == persistent_connection_destructor_id_ && res->ptr != nullptr) { - auto* handle = static_cast(res->ptr); - const std::string connection_string = handle->connection_string(); - const std::string connection_hash = handle->connection_hash(); - const auto expires_at = handle->expires_at(); - auto now = std::chrono::system_clock::now(); - delete handle; - res->ptr = nullptr; - auto current_persistent = --COUCHBASE_G(num_persistent); - CB_LOG_DEBUG("persistent connection destroyed: handle={}, connection_hash={}, connection_string=\"{}\", " - "expires_at=\"{}\" ({}), destructor_id={}, num_persistent={}", - static_cast(handle), - connection_hash, - connection_string, - expires_at, - (expires_at - now), - persistent_connection_destructor_id_, - current_persistent); - } + if (res->type == persistent_connection_destructor_id_ && res->ptr != nullptr) { + auto* handle = static_cast(res->ptr); + const std::string connection_string = handle->connection_string(); + const std::string connection_hash = handle->connection_hash(); + const auto expires_at = handle->expires_at(); + auto now = std::chrono::system_clock::now(); + delete handle; + res->ptr = nullptr; + auto current_persistent = --COUCHBASE_G(num_persistent); + CB_LOG_DEBUG( + "persistent connection destroyed: handle={}, connection_hash={}, connection_string=\"{}\", " + "expires_at=\"{}\" ({}), destructor_id={}, num_persistent={}", + static_cast(handle), + connection_hash, + connection_string, + expires_at, + (expires_at - now), + persistent_connection_destructor_id_, + current_persistent); + } } namespace @@ -179,57 +193,65 @@ namespace int notify_transaction(zval* zv, void* event_ptr) { - if (event_ptr == nullptr) { - return ZEND_HASH_APPLY_KEEP; - } + if (event_ptr == nullptr) { + return ZEND_HASH_APPLY_KEEP; + } - zend_resource* res = Z_RES_P(zv); - const fork_event event = *(static_cast(event_ptr)); + zend_resource* res = Z_RES_P(zv); + const fork_event event = *(static_cast(event_ptr)); - if (res->type == get_transactions_destructor_id()) { - auto const* transaction = static_cast(res->ptr); - transaction->notify_fork(event); - } - return ZEND_HASH_APPLY_KEEP; + if (res->type == get_transactions_destructor_id()) { + auto const* transaction = static_cast(res->ptr); + transaction->notify_fork(event); + } + return ZEND_HASH_APPLY_KEEP; } int notify_connection(zval* zv, void* event_ptr) { - if (event_ptr == nullptr) { - return ZEND_HASH_APPLY_KEEP; - } + if (event_ptr == nullptr) { + return ZEND_HASH_APPLY_KEEP; + } - zend_resource* res = Z_RES_P(zv); - const fork_event event = *(static_cast(event_ptr)); + zend_resource* res = Z_RES_P(zv); + const fork_event event = *(static_cast(event_ptr)); - if (res->type == persistent_connection_destructor_id_) { - const auto* connection = static_cast(res->ptr); - connection->notify_fork(event); - } - return ZEND_HASH_APPLY_KEEP; + if (res->type == persistent_connection_destructor_id_) { + const auto* connection = static_cast(res->ptr); + connection->notify_fork(event); + } + return ZEND_HASH_APPLY_KEEP; } std::pair> get_fork_event(const zend_string* fork_event_str) { - if (fork_event_str == nullptr || ZSTR_VAL(fork_event_str) == nullptr || ZSTR_LEN(fork_event_str) == 0) { - return { { errc::common::invalid_argument, ERROR_LOCATION, "expected non-empty string for forkEvent argument" }, {} }; - } - - if (zend_binary_strcmp(ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str), ZEND_STRL("prepare")) == 0) { - return { {}, couchbase::fork_event::prepare }; - } - if (zend_binary_strcmp(ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str), ZEND_STRL("parent")) == 0) { - return { {}, couchbase::fork_event::parent }; - } - if (zend_binary_strcmp(ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str), ZEND_STRL("child")) == 0) { - return { {}, couchbase::fork_event::child }; - } + if (fork_event_str == nullptr || ZSTR_VAL(fork_event_str) == nullptr || + ZSTR_LEN(fork_event_str) == 0) { return { { errc::common::invalid_argument, ERROR_LOCATION, - fmt::format("unknown forkEvent: {}", std::string_view(ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str))) }, + "expected non-empty string for forkEvent argument" }, {} }; + } + + if (zend_binary_strcmp( + ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str), ZEND_STRL("prepare")) == 0) { + return { {}, couchbase::fork_event::prepare }; + } + if (zend_binary_strcmp(ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str), ZEND_STRL("parent")) == + 0) { + return { {}, couchbase::fork_event::parent }; + } + if (zend_binary_strcmp(ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str), ZEND_STRL("child")) == + 0) { + return { {}, couchbase::fork_event::child }; + } + return { { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unknown forkEvent: {}", + std::string_view(ZSTR_VAL(fork_event_str), ZSTR_LEN(fork_event_str))) }, + {} }; } } // namespace @@ -237,24 +259,24 @@ COUCHBASE_API core_error_info notify_fork(const zend_string* fork_event) { - auto [e, event] = get_fork_event(fork_event); - if (e.ec) { - return e; - } + auto [e, event] = get_fork_event(fork_event); + if (e.ec) { + return e; + } - /* transactions must be first to stop */ - if (event == fork_event::prepare) { - zend_hash_apply_with_argument(&EG(persistent_list), notify_transaction, &event); - } + /* transactions must be first to stop */ + if (event == fork_event::prepare) { + zend_hash_apply_with_argument(&EG(persistent_list), notify_transaction, &event); + } - zend_hash_apply_with_argument(&EG(persistent_list), notify_connection, &event); + zend_hash_apply_with_argument(&EG(persistent_list), notify_connection, &event); - /* transactions must be last to start */ - if (event != fork_event::prepare) { - zend_hash_apply_with_argument(&EG(persistent_list), notify_transaction, &event); - } + /* transactions must be last to start */ + if (event != fork_event::prepare) { + zend_hash_apply_with_argument(&EG(persistent_list), notify_transaction, &event); + } - return {}; + return {}; } } // namespace couchbase::php diff --git a/src/wrapper/persistent_connections_cache.hxx b/src/wrapper/persistent_connections_cache.hxx index 09b28568..f8207b56 100644 --- a/src/wrapper/persistent_connections_cache.hxx +++ b/src/wrapper/persistent_connections_cache.hxx @@ -32,7 +32,9 @@ COUCHBASE_API int get_persistent_connection_destructor_id(); COUCHBASE_API std::pair -create_persistent_connection(zend_string* connection_hash, zend_string* connection_string, zval* options); +create_persistent_connection(zend_string* connection_hash, + zend_string* connection_string, + zval* options); COUCHBASE_API void destroy_persistent_connection(zend_resource* res); diff --git a/src/wrapper/php_7_api_layer.hxx b/src/wrapper/php_7_api_layer.hxx index 67d2f309..c7ab57b4 100644 --- a/src/wrapper/php_7_api_layer.hxx +++ b/src/wrapper/php_7_api_layer.hxx @@ -20,31 +20,35 @@ #if PHP_VERSION_ID < 80000 -#define couchbase_update_property_string(scope, object, name, value) \ - zend_update_property_string((scope), (object), ZEND_STRL(name), (value)) -#define couchbase_update_property_long(scope, object, name, value) zend_update_property_long((scope), (object), ZEND_STRL(name), (value)) -#define couchbase_update_property(scope, object, name, value) zend_update_property((scope), (object), ZEND_STRL(name), (value)) - -#define couchbase_read_property(scope, object, name, silent, rv) zend_read_property((scope), (object), ZEND_STRL(name), (silent), (rv)) - -#define RETURN_THROWS() \ - do { \ - ZEND_ASSERT(EG(exception)); \ - (void)return_value; \ - return; \ - } while (0) +#define couchbase_update_property_string(scope, object, name, value) \ + zend_update_property_string((scope), (object), ZEND_STRL(name), (value)) +#define couchbase_update_property_long(scope, object, name, value) \ + zend_update_property_long((scope), (object), ZEND_STRL(name), (value)) +#define couchbase_update_property(scope, object, name, value) \ + zend_update_property((scope), (object), ZEND_STRL(name), (value)) + +#define couchbase_read_property(scope, object, name, silent, rv) \ + zend_read_property((scope), (object), ZEND_STRL(name), (silent), (rv)) + +#define RETURN_THROWS() \ + do { \ + ZEND_ASSERT(EG(exception)); \ + (void)return_value; \ + return; \ + } while (0) #define Z_PARAM_ARRAY_OR_NULL(dest) Z_PARAM_ARRAY_EX(dest, 1, 0) #else // PHP_VERSION_ID >= 80000 -#define couchbase_update_property_string(scope, object, name, value) \ - zend_update_property_string((scope), Z_OBJ_P(object), ZEND_STRL(name), (value)) -#define couchbase_update_property_long(scope, object, name, value) \ - zend_update_property_long((scope), Z_OBJ_P(object), ZEND_STRL(name), (value)) -#define couchbase_update_property(scope, object, name, value) zend_update_property((scope), Z_OBJ_P(object), ZEND_STRL(name), (value)) +#define couchbase_update_property_string(scope, object, name, value) \ + zend_update_property_string((scope), Z_OBJ_P(object), ZEND_STRL(name), (value)) +#define couchbase_update_property_long(scope, object, name, value) \ + zend_update_property_long((scope), Z_OBJ_P(object), ZEND_STRL(name), (value)) +#define couchbase_update_property(scope, object, name, value) \ + zend_update_property((scope), Z_OBJ_P(object), ZEND_STRL(name), (value)) -#define couchbase_read_property(scope, object, name, silent, rv) \ - zend_read_property((scope), Z_OBJ_P(object), ZEND_STRL(name), (silent), (rv)) +#define couchbase_read_property(scope, object, name, silent, rv) \ + zend_read_property((scope), Z_OBJ_P(object), ZEND_STRL(name), (silent), (rv)) #endif // PHP_VERSION_ID \ No newline at end of file diff --git a/src/wrapper/scan_result_resource.cxx b/src/wrapper/scan_result_resource.cxx index a01a90d2..b9db6467 100644 --- a/src/wrapper/scan_result_resource.cxx +++ b/src/wrapper/scan_result_resource.cxx @@ -38,61 +38,66 @@ static int scan_result_destructor_id_{ 0 }; void set_scan_result_destructor_id(int id) { - scan_result_destructor_id_ = id; + scan_result_destructor_id_ = id; } int get_scan_result_destructor_id() { - return scan_result_destructor_id_; + return scan_result_destructor_id_; } class scan_result_resource::impl : public std::enable_shared_from_this { - public: - impl(connection_handle* connection, std::unique_ptr scan_result) - : cluster_{ connection->cluster() } - , scan_result_{ std::move(scan_result) } - { - } +public: + impl(connection_handle* connection, std::unique_ptr scan_result) + : cluster_{ connection->cluster() } + , scan_result_{ std::move(scan_result) } + { + } - impl(impl&& other) = delete; + impl(impl&& other) = delete; - impl(const impl& other) = delete; + impl(const impl& other) = delete; - const impl& operator=(impl&& other) = delete; + const impl& operator=(impl&& other) = delete; - const impl& operator=(const impl& other) = delete; + const impl& operator=(const impl& other) = delete; - [[nodiscard]] std::pair, core_error_info> next_item() - { - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - scan_result_->next([barrier](couchbase::core::range_scan_item item, std::error_code ec) { - if (ec) { - return barrier->set_value(tl::unexpected(ec)); - } else { - return barrier->set_value(item); - } - }); - auto resp = f.get(); - if (!resp.has_value()) { - if (resp.error() != couchbase::errc::key_value::range_scan_completed) { - return { {}, { resp.error(), ERROR_LOCATION, "Unable to fetch scan item" } }; - } - return { {}, {} }; - } - return { resp.value(), {} }; + [[nodiscard]] std::pair, core_error_info> + next_item() + { + auto barrier = std::make_shared< + std::promise>>(); + auto f = barrier->get_future(); + scan_result_->next([barrier](couchbase::core::range_scan_item item, std::error_code ec) { + if (ec) { + return barrier->set_value(tl::unexpected(ec)); + } else { + return barrier->set_value(item); + } + }); + auto resp = f.get(); + if (!resp.has_value()) { + if (resp.error() != couchbase::errc::key_value::range_scan_completed) { + return { {}, { resp.error(), ERROR_LOCATION, "Unable to fetch scan item" } }; + } + return { {}, {} }; } + return { resp.value(), {} }; + } - private: - std::shared_ptr cluster_; - std::unique_ptr scan_result_; +private: + std::shared_ptr cluster_; + std::unique_ptr scan_result_; }; COUCHBASE_API -scan_result_resource::scan_result_resource(connection_handle* connection, const couchbase::core::scan_result& scan_result) - : impl_{ std::make_shared(connection, std::make_unique(scan_result)) } +scan_result_resource::scan_result_resource(connection_handle* connection, + const couchbase::core::scan_result& scan_result) + : impl_{ std::make_shared( + connection, + std::make_unique(scan_result)) } { } @@ -100,26 +105,27 @@ COUCHBASE_API core_error_info scan_result_resource::next_item(zval* return_value) { - auto [resp, err] = impl_->next_item(); - if (err.ec) { - return err; + auto [resp, err] = impl_->next_item(); + if (err.ec) { + return err; + } + if (resp) { + array_init(return_value); + add_assoc_stringl(return_value, "id", resp->key.data(), resp->key.size()); + if (resp->body.has_value()) { + auto body = resp->body.value(); + auto cas = fmt::format("{:x}", body.cas.value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + add_assoc_long(return_value, "flags", body.flags); + add_assoc_stringl( + return_value, "value", reinterpret_cast(body.value.data()), body.value.size()); + add_assoc_long(return_value, "expiry", body.expiry); + add_assoc_bool(return_value, "idsOnly", 0); + } else { + add_assoc_bool(return_value, "idsOnly", 1); } - if (resp) { - array_init(return_value); - add_assoc_stringl(return_value, "id", resp->key.data(), resp->key.size()); - if (resp->body.has_value()) { - auto body = resp->body.value(); - auto cas = fmt::format("{:x}", body.cas.value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - add_assoc_long(return_value, "flags", body.flags); - add_assoc_stringl(return_value, "value", reinterpret_cast(body.value.data()), body.value.size()); - add_assoc_long(return_value, "expiry", body.expiry); - add_assoc_bool(return_value, "idsOnly", 0); - } else { - add_assoc_bool(return_value, "idsOnly", 1); - } - } - return {}; + } + return {}; } COUCHBASE_API @@ -131,161 +137,185 @@ create_scan_result_resource(connection_handle* connection, const zval* scan_type, const zval* options) { - // Get orchestrator options - couchbase::core::range_scan_orchestrator_options opts; - - if (auto e = cb_assign_timeout(opts, options); e.ec) { + // Get orchestrator options + couchbase::core::range_scan_orchestrator_options opts; + + if (auto e = cb_assign_timeout(opts, options); e.ec) { + return { nullptr, e }; + } + if (auto e = cb_assign_boolean(opts.ids_only, options, "idsOnly"); e.ec) { + return { nullptr, e }; + } + if (auto e = cb_assign_integer(opts.concurrency, options, "concurrency"); e.ec) { + return { nullptr, e }; + } + if (auto e = cb_assign_integer(opts.batch_byte_limit, options, "batchByteLimit"); e.ec) { + return { nullptr, e }; + } + if (auto e = cb_assign_integer(opts.batch_item_limit, options, "batchItemLimit"); e.ec) { + return { nullptr, e }; + } + if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("consistentWith")); + value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { + couchbase::core::mutation_state mutation_state{}; + const zval* item = nullptr; + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) + { + std::uint64_t partition_uuid; + std::uint64_t sequence_number; + std::uint16_t partition_id; + std::string bucket_name; + if (auto e = cb_assign_integer(partition_id, options, "partitionId"); e.ec) { return { nullptr, e }; - } - if (auto e = cb_assign_boolean(opts.ids_only, options, "idsOnly"); e.ec) { + } + if (auto e = cb_assign_integer(partition_uuid, options, "partitionUuid"); e.ec) { return { nullptr, e }; - } - if (auto e = cb_assign_integer(opts.concurrency, options, "concurrency"); e.ec) { - return { nullptr, e }; - } - if (auto e = cb_assign_integer(opts.batch_byte_limit, options, "batchByteLimit"); e.ec) { + } + if (auto e = cb_assign_integer(sequence_number, options, "sequenceNumber"); e.ec) { return { nullptr, e }; - } - if (auto e = cb_assign_integer(opts.batch_item_limit, options, "batchItemLimit"); e.ec) { + } + if (auto e = cb_assign_string(bucket_name, options, "bucketName"); e.ec) { return { nullptr, e }; + } + mutation_state.tokens.emplace_back( + mutation_token{ partition_uuid, sequence_number, partition_id, bucket_name }); } - if (const zval* value = zend_symtable_str_find(Z_ARRVAL_P(options), ZEND_STRL("consistentWith")); - value != nullptr && Z_TYPE_P(value) == IS_ARRAY) { - couchbase::core::mutation_state mutation_state{}; - const zval* item = nullptr; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(value), item) - { - std::uint64_t partition_uuid; - std::uint64_t sequence_number; - std::uint16_t partition_id; - std::string bucket_name; - if (auto e = cb_assign_integer(partition_id, options, "partitionId"); e.ec) { - return { nullptr, e }; - } - if (auto e = cb_assign_integer(partition_uuid, options, "partitionUuid"); e.ec) { - return { nullptr, e }; - } - if (auto e = cb_assign_integer(sequence_number, options, "sequenceNumber"); e.ec) { - return { nullptr, e }; - } - if (auto e = cb_assign_string(bucket_name, options, "bucketName"); e.ec) { - return { nullptr, e }; - } - mutation_state.tokens.emplace_back(mutation_token{ partition_uuid, sequence_number, partition_id, bucket_name }); - } - ZEND_HASH_FOREACH_END(); - - opts.consistent_with = mutation_state; - } - - auto bucket_name = cb_string_new(bucket); - auto scope_name = cb_string_new(scope); - auto collection_name = cb_string_new(collection); - - // Get operation agent - auto clust = connection->cluster(); - - auto agent_group = couchbase::core::agent_group(clust->io_context(), couchbase::core::agent_group_config{ { *clust } }); - agent_group.open_bucket(bucket_name); - auto agent = agent_group.get_agent(bucket_name); - if (!agent.has_value()) { - return { nullptr, { agent.error(), ERROR_LOCATION, "Cannot perform scan operation. Unable to get operation agent" } }; - } - - // Get vBucket map - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - clust->with_bucket_configuration(bucket_name, [barrier](std::error_code ec, const core::topology::configuration& config) { - barrier->set_value({ ec, config }); + ZEND_HASH_FOREACH_END(); + + opts.consistent_with = mutation_state; + } + + auto bucket_name = cb_string_new(bucket); + auto scope_name = cb_string_new(scope); + auto collection_name = cb_string_new(collection); + + // Get operation agent + auto clust = connection->cluster(); + + auto agent_group = couchbase::core::agent_group( + clust->io_context(), couchbase::core::agent_group_config{ { *clust } }); + agent_group.open_bucket(bucket_name); + auto agent = agent_group.get_agent(bucket_name); + if (!agent.has_value()) { + return { nullptr, + { agent.error(), + ERROR_LOCATION, + "Cannot perform scan operation. Unable to get operation agent" } }; + } + + // Get vBucket map + auto barrier = + std::make_shared>>(); + auto f = barrier->get_future(); + clust->with_bucket_configuration( + bucket_name, [barrier](std::error_code ec, const core::topology::configuration& config) { + barrier->set_value({ ec, config }); }); - auto [ec, config] = f.get(); - if (ec) { - return { nullptr, { ec, ERROR_LOCATION, "Cannot perform scan operation. Unable to get bucket config" } }; - } - if (!config.capabilities.supports_range_scan()) { - return { nullptr, - { errc::common::feature_not_available, ERROR_LOCATION, "Server version does not support key-value scan operations" } }; - } - auto vbucket_map = config.vbmap; - if (!vbucket_map || vbucket_map->empty()) { - return { nullptr, { std::error_code{}, ERROR_LOCATION, "Cannot perform scan operation. Unable to get vBucket map." } }; - } - - // Create scan type - - std::variant - core_scan_type{}; - - if (auto [e, type] = cb_get_string(scan_type, "type"); type) { - if (type == "range_scan") { - couchbase::core::range_scan range_scan{}; - if (const zval* from = zend_symtable_str_find(Z_ARRVAL_P(scan_type), ZEND_STRL("from")); - from != nullptr && Z_TYPE_P(from) == IS_ARRAY) { - couchbase::core::scan_term from_term{}; - if (auto e = cb_assign_string(from_term.term, from, "term"); e.ec) { - return { nullptr, e }; - } - if (auto e = cb_assign_boolean(from_term.exclusive, from, "exclusive"); e.ec) { - return { nullptr, e }; - } - range_scan.from = from_term; - } - if (const zval* to = zend_symtable_str_find(Z_ARRVAL_P(scan_type), ZEND_STRL("to")); - to != nullptr && Z_TYPE_P(to) == IS_ARRAY) { - couchbase::core::scan_term to_term{}; - if (auto e = cb_assign_string(to_term.term, to, "term"); e.ec) { - return { nullptr, e }; - } - if (auto e = cb_assign_boolean(to_term.exclusive, to, "exclusive"); e.ec) { - return { nullptr, e }; - } - range_scan.to = to_term; - } - core_scan_type = range_scan; - } else if (type == "prefix_scan") { - couchbase::core::prefix_scan prefix_scan{}; - if (auto e = cb_assign_string(prefix_scan.prefix, scan_type, "prefix"); e.ec) { - return { nullptr, e }; - } - core_scan_type = prefix_scan; - } else if (type == "sampling_scan") { - couchbase::core::sampling_scan sampling_scan{}; - if (auto e = cb_assign_integer(sampling_scan.limit, scan_type, "limit"); e.ec) { - return { nullptr, e }; - } - if (auto e = cb_assign_integer(sampling_scan.seed, scan_type, "seed"); e.ec) { - return { nullptr, e }; - } - core_scan_type = sampling_scan; - } else { - return { nullptr, { errc::common::invalid_argument, ERROR_LOCATION, "Invalid scan type provided" } }; + auto [ec, config] = f.get(); + if (ec) { + return { nullptr, + { ec, ERROR_LOCATION, "Cannot perform scan operation. Unable to get bucket config" } }; + } + if (!config.capabilities.supports_range_scan()) { + return { nullptr, + { errc::common::feature_not_available, + ERROR_LOCATION, + "Server version does not support key-value scan operations" } }; + } + auto vbucket_map = config.vbmap; + if (!vbucket_map || vbucket_map->empty()) { + return { nullptr, + { std::error_code{}, + ERROR_LOCATION, + "Cannot perform scan operation. Unable to get vBucket map." } }; + } + + // Create scan type + + std::variant + core_scan_type{}; + + if (auto [e, type] = cb_get_string(scan_type, "type"); type) { + if (type == "range_scan") { + couchbase::core::range_scan range_scan{}; + if (const zval* from = zend_symtable_str_find(Z_ARRVAL_P(scan_type), ZEND_STRL("from")); + from != nullptr && Z_TYPE_P(from) == IS_ARRAY) { + couchbase::core::scan_term from_term{}; + if (auto e = cb_assign_string(from_term.term, from, "term"); e.ec) { + return { nullptr, e }; + } + if (auto e = cb_assign_boolean(from_term.exclusive, from, "exclusive"); e.ec) { + return { nullptr, e }; } - } else if (e.ec) { + range_scan.from = from_term; + } + if (const zval* to = zend_symtable_str_find(Z_ARRVAL_P(scan_type), ZEND_STRL("to")); + to != nullptr && Z_TYPE_P(to) == IS_ARRAY) { + couchbase::core::scan_term to_term{}; + if (auto e = cb_assign_string(to_term.term, to, "term"); e.ec) { + return { nullptr, e }; + } + if (auto e = cb_assign_boolean(to_term.exclusive, to, "exclusive"); e.ec) { + return { nullptr, e }; + } + range_scan.to = to_term; + } + core_scan_type = range_scan; + } else if (type == "prefix_scan") { + couchbase::core::prefix_scan prefix_scan{}; + if (auto e = cb_assign_string(prefix_scan.prefix, scan_type, "prefix"); e.ec) { return { nullptr, e }; + } + core_scan_type = prefix_scan; + } else if (type == "sampling_scan") { + couchbase::core::sampling_scan sampling_scan{}; + if (auto e = cb_assign_integer(sampling_scan.limit, scan_type, "limit"); e.ec) { + return { nullptr, e }; + } + if (auto e = cb_assign_integer(sampling_scan.seed, scan_type, "seed"); e.ec) { + return { nullptr, e }; + } + core_scan_type = sampling_scan; + } else { + return { nullptr, + { errc::common::invalid_argument, ERROR_LOCATION, "Invalid scan type provided" } }; } - auto orchestrator = couchbase::core::range_scan_orchestrator( - clust->io_context(), agent.value(), vbucket_map.value(), scope_name, collection_name, core_scan_type, opts); - - // start scan - auto resp = orchestrator.scan(); - if (!resp.has_value()) { - return { nullptr, { resp.error(), ERROR_LOCATION, "Unable to start the scan" } }; - } - - auto* handle = new scan_result_resource(connection, resp.value()); - - return { zend_register_resource(handle, scan_result_destructor_id_), {} }; + } else if (e.ec) { + return { nullptr, e }; + } + auto orchestrator = couchbase::core::range_scan_orchestrator(clust->io_context(), + agent.value(), + vbucket_map.value(), + scope_name, + collection_name, + core_scan_type, + opts); + + // start scan + auto resp = orchestrator.scan(); + if (!resp.has_value()) { + return { nullptr, { resp.error(), ERROR_LOCATION, "Unable to start the scan" } }; + } + + auto* handle = new scan_result_resource(connection, resp.value()); + + return { zend_register_resource(handle, scan_result_destructor_id_), {} }; } COUCHBASE_API void destroy_scan_result_resource(zend_resource* res) { - if (res->type == scan_result_destructor_id_ && res->ptr != nullptr) { - auto* handle = static_cast(res->ptr); - res->ptr = nullptr; - std::thread([handle]() { delete handle; }).detach(); - } + if (res->type == scan_result_destructor_id_ && res->ptr != nullptr) { + auto* handle = static_cast(res->ptr); + res->ptr = nullptr; + std::thread([handle]() { + delete handle; + }).detach(); + } } } // namespace couchbase::php diff --git a/src/wrapper/scan_result_resource.hxx b/src/wrapper/scan_result_resource.hxx index abcd2e34..b9ef10fb 100644 --- a/src/wrapper/scan_result_resource.hxx +++ b/src/wrapper/scan_result_resource.hxx @@ -39,17 +39,18 @@ namespace couchbase::php { class scan_result_resource { - public: - COUCHBASE_API - scan_result_resource(connection_handle* connection, const couchbase::core::scan_result& scan_result); +public: + COUCHBASE_API + scan_result_resource(connection_handle* connection, + const couchbase::core::scan_result& scan_result); - COUCHBASE_API - core_error_info next_item(zval* return_value); + COUCHBASE_API + core_error_info next_item(zval* return_value); - private: - class impl; +private: + class impl; - std::shared_ptr impl_; + std::shared_ptr impl_; }; COUCHBASE_API std::pair diff --git a/src/wrapper/transaction_context_resource.cxx b/src/wrapper/transaction_context_resource.cxx index 0ab228b8..36b50c92 100644 --- a/src/wrapper/transaction_context_resource.cxx +++ b/src/wrapper/transaction_context_resource.cxx @@ -40,385 +40,440 @@ static int transaction_context_destructor_id_{ 0 }; void set_transaction_context_destructor_id(int id) { - transaction_context_destructor_id_ = id; + transaction_context_destructor_id_ = id; } int get_transaction_context_destructor_id() { - return transaction_context_destructor_id_; + return transaction_context_destructor_id_; } static std::string external_exception_to_string(core::transactions::external_exception cause) { - switch (cause) { - case core::transactions::UNKNOWN: - return "unknown"; - case core::transactions::ACTIVE_TRANSACTION_RECORD_ENTRY_NOT_FOUND: - return "activeTransactionRecordEntryNotFound"; - case core::transactions::ACTIVE_TRANSACTION_RECORD_FULL: - return "activeTransactionRecordFull"; - case core::transactions::ACTIVE_TRANSACTION_RECORD_NOT_FOUND: - return "activeTransactionRecordNotFound"; - case core::transactions::DOCUMENT_ALREADY_IN_TRANSACTION: - return "documentAlreadyInTransaction"; - case core::transactions::DOCUMENT_EXISTS_EXCEPTION: - return "documentExistsException"; - case core::transactions::DOCUMENT_NOT_FOUND_EXCEPTION: - return "documentNotFoundException"; - case core::transactions::NOT_SET: - return "notSet"; - case core::transactions::FEATURE_NOT_AVAILABLE_EXCEPTION: - return "featureNotAvailableException"; - case core::transactions::TRANSACTION_ABORTED_EXTERNALLY: - return "transactionAbortedExternally"; - case core::transactions::PREVIOUS_OPERATION_FAILED: - return "previousOperationFailed"; - case core::transactions::FORWARD_COMPATIBILITY_FAILURE: - return "forwardCompatibilityFailure"; - case core::transactions::PARSING_FAILURE: - return "parsingFailure"; - case core::transactions::ILLEGAL_STATE_EXCEPTION: - return "illegalStateException"; - case core::transactions::COUCHBASE_EXCEPTION: - return "couchbaseException"; - case core::transactions::SERVICE_NOT_AVAILABLE_EXCEPTION: - return "serviceNotAvailableException"; - case core::transactions::REQUEST_CANCELED_EXCEPTION: - return "requestCanceledException"; - case core::transactions::CONCURRENT_OPERATIONS_DETECTED_ON_SAME_DOCUMENT: - return "concurrentOperationsDetectedOnSameDocument"; - case core::transactions::COMMIT_NOT_PERMITTED: - return "commitNotPermitted"; - case core::transactions::ROLLBACK_NOT_PERMITTED: - return "rollbackNotPermitted"; - case core::transactions::TRANSACTION_ALREADY_ABORTED: - return "transactionAlreadyAborted"; - case core::transactions::TRANSACTION_ALREADY_COMMITTED: - return "transactionAlreadyCommitted"; - } - return "unexpectedCause"; + switch (cause) { + case core::transactions::UNKNOWN: + return "unknown"; + case core::transactions::ACTIVE_TRANSACTION_RECORD_ENTRY_NOT_FOUND: + return "activeTransactionRecordEntryNotFound"; + case core::transactions::ACTIVE_TRANSACTION_RECORD_FULL: + return "activeTransactionRecordFull"; + case core::transactions::ACTIVE_TRANSACTION_RECORD_NOT_FOUND: + return "activeTransactionRecordNotFound"; + case core::transactions::DOCUMENT_ALREADY_IN_TRANSACTION: + return "documentAlreadyInTransaction"; + case core::transactions::DOCUMENT_EXISTS_EXCEPTION: + return "documentExistsException"; + case core::transactions::DOCUMENT_NOT_FOUND_EXCEPTION: + return "documentNotFoundException"; + case core::transactions::NOT_SET: + return "notSet"; + case core::transactions::FEATURE_NOT_AVAILABLE_EXCEPTION: + return "featureNotAvailableException"; + case core::transactions::TRANSACTION_ABORTED_EXTERNALLY: + return "transactionAbortedExternally"; + case core::transactions::PREVIOUS_OPERATION_FAILED: + return "previousOperationFailed"; + case core::transactions::FORWARD_COMPATIBILITY_FAILURE: + return "forwardCompatibilityFailure"; + case core::transactions::PARSING_FAILURE: + return "parsingFailure"; + case core::transactions::ILLEGAL_STATE_EXCEPTION: + return "illegalStateException"; + case core::transactions::COUCHBASE_EXCEPTION: + return "couchbaseException"; + case core::transactions::SERVICE_NOT_AVAILABLE_EXCEPTION: + return "serviceNotAvailableException"; + case core::transactions::REQUEST_CANCELED_EXCEPTION: + return "requestCanceledException"; + case core::transactions::CONCURRENT_OPERATIONS_DETECTED_ON_SAME_DOCUMENT: + return "concurrentOperationsDetectedOnSameDocument"; + case core::transactions::COMMIT_NOT_PERMITTED: + return "commitNotPermitted"; + case core::transactions::ROLLBACK_NOT_PERMITTED: + return "rollbackNotPermitted"; + case core::transactions::TRANSACTION_ALREADY_ABORTED: + return "transactionAlreadyAborted"; + case core::transactions::TRANSACTION_ALREADY_COMMITTED: + return "transactionAlreadyCommitted"; + } + return "unexpectedCause"; } static transactions_error_context build_error_context(const core::transactions::transaction_operation_failed& ctx) { - transactions_error_context out; - out.should_not_retry = !ctx.should_retry(); - out.should_not_rollback = !ctx.should_rollback(); - out.cause = external_exception_to_string(ctx.cause()); - return out; + transactions_error_context out; + out.should_not_retry = !ctx.should_retry(); + out.should_not_rollback = !ctx.should_rollback(); + out.cause = external_exception_to_string(ctx.cause()); + return out; } static std::string failure_type_to_string(core::transactions::failure_type failure) { - switch (failure) { - case core::transactions::failure_type::FAIL: - return "fail"; - case core::transactions::failure_type::EXPIRY: - return "expiry"; - case core::transactions::failure_type::COMMIT_AMBIGUOUS: - return "commit_ambiguous"; - } - return "unknown"; + switch (failure) { + case core::transactions::failure_type::FAIL: + return "fail"; + case core::transactions::failure_type::EXPIRY: + return "expiry"; + case core::transactions::failure_type::COMMIT_AMBIGUOUS: + return "commit_ambiguous"; + } + return "unknown"; } static transactions_error_context build_error_context(const core::transactions::transaction_exception& e) { - transactions_error_context out; - out.type = failure_type_to_string(e.type()); - out.cause = external_exception_to_string(e.cause()); - transactions_error_context::transaction_result res; - auto [_, core_res] = e.get_transaction_result(); - res.transaction_id = core_res.transaction_id; - res.unstaging_complete = core_res.unstaging_complete; - out.result = res; - return out; + transactions_error_context out; + out.type = failure_type_to_string(e.type()); + out.cause = external_exception_to_string(e.cause()); + transactions_error_context::transaction_result res; + auto [_, core_res] = e.get_transaction_result(); + res.transaction_id = core_res.transaction_id; + res.unstaging_complete = core_res.unstaging_complete; + out.result = res; + return out; } static std::error_code failure_type_to_error_code(core::transactions::failure_type failure) { - switch (failure) { - case core::transactions::failure_type::FAIL: - return transactions_errc::failed; - case core::transactions::failure_type::EXPIRY: - return transactions_errc::expired; - case core::transactions::failure_type::COMMIT_AMBIGUOUS: - return transactions_errc::commit_ambiguous; - } - return transactions_errc::unexpected_exception; + switch (failure) { + case core::transactions::failure_type::FAIL: + return transactions_errc::failed; + case core::transactions::failure_type::EXPIRY: + return transactions_errc::expired; + case core::transactions::failure_type::COMMIT_AMBIGUOUS: + return transactions_errc::commit_ambiguous; + } + return transactions_errc::unexpected_exception; } -class transaction_context_resource::impl : public std::enable_shared_from_this +class transaction_context_resource::impl + : public std::enable_shared_from_this { - public: - impl(core::transactions::transactions& transactions, const transactions::transaction_options& configuration) - : transaction_context_(transactions, configuration) - { +public: + impl(core::transactions::transactions& transactions, + const transactions::transaction_options& configuration) + : transaction_context_(transactions, configuration) + { + } + + impl(impl&& other) = delete; + + impl(const impl& other) = delete; + + const impl& operator=(impl&& other) = delete; + + const impl& operator=(const impl& other) = delete; + + [[nodiscard]] core_error_info new_attempt() + { + try { + transaction_context_.new_attempt_context(); + } catch (const core::transactions::transaction_operation_failed& e) { + return { transactions_errc::operation_failed, + ERROR_LOCATION, + fmt::format("unable to create new attempt context: {}, cause: {}", + e.what(), + external_exception_to_string(e.cause())), + build_error_context(e) }; + } catch (const std::exception& e) { + return { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format("unable to create new attempt context: {}", e.what()) }; + } catch (...) { + return { transactions_errc::unexpected_exception, + ERROR_LOCATION, + "unable to create new attempt context: unexpected C++ exception" }; } - - impl(impl&& other) = delete; - - impl(const impl& other) = delete; - - const impl& operator=(impl&& other) = delete; - - const impl& operator=(const impl& other) = delete; - - [[nodiscard]] core_error_info new_attempt() - { - try { - transaction_context_.new_attempt_context(); - } catch (const core::transactions::transaction_operation_failed& e) { - return { transactions_errc::operation_failed, - ERROR_LOCATION, - fmt::format("unable to create new attempt context: {}, cause: {}", e.what(), external_exception_to_string(e.cause())), - build_error_context(e) }; - } catch (const std::exception& e) { - return { transactions_errc::std_exception, ERROR_LOCATION, fmt::format("unable to create new attempt context: {}", e.what()) }; - } catch (...) { - return { transactions_errc::unexpected_exception, - ERROR_LOCATION, - "unable to create new attempt context: unexpected C++ exception" }; - } - return {}; - } - - [[nodiscard]] core_error_info rollback() - { - try { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - transaction_context_.rollback([barrier](std::exception_ptr e) { - if (e) { - return barrier->set_exception(std::move(e)); - } - return barrier->set_value(); - }); - f.get(); - } catch (const core::transactions::transaction_operation_failed& e) { - return { transactions_errc::operation_failed, - ERROR_LOCATION, - fmt::format("unable to rollback transaction: {}, cause: {}", e.what(), external_exception_to_string(e.cause())), - build_error_context(e) }; - } catch (const std::exception& e) { - return { transactions_errc::std_exception, ERROR_LOCATION, fmt::format("unable to rollback transaction: {}", e.what()) }; - } catch (...) { - return { transactions_errc::unexpected_exception, ERROR_LOCATION, "unable to rollback transaction: unexpected C++ exception" }; + return {}; + } + + [[nodiscard]] core_error_info rollback() + { + try { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + transaction_context_.rollback([barrier](std::exception_ptr e) { + if (e) { + return barrier->set_exception(std::move(e)); } - return {}; + return barrier->set_value(); + }); + f.get(); + } catch (const core::transactions::transaction_operation_failed& e) { + return { transactions_errc::operation_failed, + ERROR_LOCATION, + fmt::format("unable to rollback transaction: {}, cause: {}", + e.what(), + external_exception_to_string(e.cause())), + build_error_context(e) }; + } catch (const std::exception& e) { + return { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format("unable to rollback transaction: {}", e.what()) }; + } catch (...) { + return { transactions_errc::unexpected_exception, + ERROR_LOCATION, + "unable to rollback transaction: unexpected C++ exception" }; } - - [[nodiscard]] std::pair, core_error_info> commit() - { - try { - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - transaction_context_.finalize( - [barrier](std::optional e, std::optional res) { - if (e) { - return barrier->set_exception(std::make_exception_ptr(e.value())); - } - return barrier->set_value(std::move(res)); - }); - return { f.get(), {} }; - } catch (const core::transactions::transaction_exception& e) { - return { {}, - { failure_type_to_error_code(e.type()), - ERROR_LOCATION, - fmt::format("unable to commit transaction: {}, cause: {}", e.what(), external_exception_to_string(e.cause())), - build_error_context(e) } }; - } catch (const std::exception& e) { - return { {}, { transactions_errc::std_exception, ERROR_LOCATION, fmt::format("unable to commit transaction: {}", e.what()) } }; - } catch (...) { - return { - {}, { transactions_errc::unexpected_exception, ERROR_LOCATION, "unable to commit transaction: unexpected C++ exception" } - }; - } - return {}; + return {}; + } + + [[nodiscard]] std::pair, core_error_info> commit() + { + try { + auto barrier = + std::make_shared>>(); + auto f = barrier->get_future(); + transaction_context_.finalize( + [barrier](std::optional e, + std::optional res) { + if (e) { + return barrier->set_exception(std::make_exception_ptr(e.value())); + } + return barrier->set_value(std::move(res)); + }); + return { f.get(), {} }; + } catch (const core::transactions::transaction_exception& e) { + return { {}, + { failure_type_to_error_code(e.type()), + ERROR_LOCATION, + fmt::format("unable to commit transaction: {}, cause: {}", + e.what(), + external_exception_to_string(e.cause())), + build_error_context(e) } }; + } catch (const std::exception& e) { + return { {}, + { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format("unable to commit transaction: {}", e.what()) } }; + } catch (...) { + return { {}, + { transactions_errc::unexpected_exception, + ERROR_LOCATION, + "unable to commit transaction: unexpected C++ exception" } }; } - - [[nodiscard]] std::pair, core_error_info> get_optional( - const core::document_id& id) - { - try { - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - transaction_context_.get_optional( - id, [barrier](std::exception_ptr e, std::optional res) mutable { - if (e) { - return barrier->set_exception(std::move(e)); - } - return barrier->set_value(std::move(res)); - }); - return { f.get(), {} }; - } catch (const core::transactions::transaction_operation_failed& e) { - return { {}, - { transactions_errc::operation_failed, - ERROR_LOCATION, - fmt::format( - "unable to get document: {}, cause: {}, id=\"{}\"", e.what(), external_exception_to_string(e.cause()), id), - build_error_context(e) } }; - } catch (const std::exception& e) { - return { - {}, { transactions_errc::std_exception, ERROR_LOCATION, fmt::format("unable to get document: {}, id=\"{}\"", e.what(), id) } - }; - } catch (...) { - return { {}, - { transactions_errc::unexpected_exception, - ERROR_LOCATION, - fmt::format("unable to get document: unexpected C++ exception, id=\"{}\"", id) } }; - } - return {}; + return {}; + } + + [[nodiscard]] std::pair, + core_error_info> + get_optional(const core::document_id& id) + { + try { + auto barrier = + std::make_shared>>(); + auto f = barrier->get_future(); + transaction_context_.get_optional( + id, + [barrier](std::exception_ptr e, + std::optional res) mutable { + if (e) { + return barrier->set_exception(std::move(e)); + } + return barrier->set_value(std::move(res)); + }); + return { f.get(), {} }; + } catch (const core::transactions::transaction_operation_failed& e) { + return { {}, + { transactions_errc::operation_failed, + ERROR_LOCATION, + fmt::format("unable to get document: {}, cause: {}, id=\"{}\"", + e.what(), + external_exception_to_string(e.cause()), + id), + build_error_context(e) } }; + } catch (const std::exception& e) { + return { {}, + { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format("unable to get document: {}, id=\"{}\"", e.what(), id) } }; + } catch (...) { + return { {}, + { transactions_errc::unexpected_exception, + ERROR_LOCATION, + fmt::format("unable to get document: unexpected C++ exception, id=\"{}\"", id) } }; } - - [[nodiscard]] std::pair, core_error_info> insert( - const core::document_id& id, - const std::vector& content) - { - try { - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - transaction_context_.insert( - id, content, [barrier](std::exception_ptr e, std::optional res) mutable { - if (e) { - return barrier->set_exception(std::move(e)); - } - return barrier->set_value(std::move(res)); - }); - return { f.get(), {} }; - } catch (const core::transactions::transaction_operation_failed& e) { - return { {}, - { transactions_errc::operation_failed, - ERROR_LOCATION, - fmt::format( - "unable to insert document: {}, cause: {}, id=\"{}\"", e.what(), external_exception_to_string(e.cause()), id), - build_error_context(e) } }; - } catch (const std::exception& e) { - return { - {}, - { transactions_errc::std_exception, ERROR_LOCATION, fmt::format("unable to insert document: {}, id=\"{}\"", e.what(), id) } - }; - } catch (...) { - return { {}, - { transactions_errc::unexpected_exception, - ERROR_LOCATION, - fmt::format("unable to insert document: unexpected C++ exception, id=\"{}\"", id) } }; - } - return {}; + return {}; + } + + [[nodiscard]] std::pair, + core_error_info> + insert(const core::document_id& id, const std::vector& content) + { + try { + auto barrier = + std::make_shared>>(); + auto f = barrier->get_future(); + transaction_context_.insert( + id, + content, + [barrier](std::exception_ptr e, + std::optional res) mutable { + if (e) { + return barrier->set_exception(std::move(e)); + } + return barrier->set_value(std::move(res)); + }); + return { f.get(), {} }; + } catch (const core::transactions::transaction_operation_failed& e) { + return { {}, + { transactions_errc::operation_failed, + ERROR_LOCATION, + fmt::format("unable to insert document: {}, cause: {}, id=\"{}\"", + e.what(), + external_exception_to_string(e.cause()), + id), + build_error_context(e) } }; + } catch (const std::exception& e) { + return { {}, + { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format("unable to insert document: {}, id=\"{}\"", e.what(), id) } }; + } catch (...) { + return { {}, + { transactions_errc::unexpected_exception, + ERROR_LOCATION, + fmt::format("unable to insert document: unexpected C++ exception, id=\"{}\"", + id) } }; } - - [[nodiscard]] std::pair, core_error_info> replace( - const core::transactions::transaction_get_result& document, - const std::vector& content) - { - try { - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - transaction_context_.replace( - document, content, [barrier](std::exception_ptr e, std::optional res) mutable { - if (e) { - return barrier->set_exception(std::move(e)); - } - return barrier->set_value(std::move(res)); - }); - return { f.get(), {} }; - } catch (const core::transactions::transaction_operation_failed& e) { - return { {}, - { transactions_errc::operation_failed, - ERROR_LOCATION, - fmt::format("unable to replace document: {}, cause: {}, id=\"{}\"", - e.what(), - external_exception_to_string(e.cause()), - document.key()), - build_error_context(e) } }; - } catch (const std::exception& e) { - return { {}, - { transactions_errc::std_exception, - ERROR_LOCATION, - fmt::format("unable to replace document: {}, id=\"{}\"", e.what(), document.key()) } }; - } catch (...) { - return { {}, - { transactions_errc::unexpected_exception, - ERROR_LOCATION, - fmt::format("unable to replace document: unexpected C++ exception, id=\"{}\"", document.key()) } }; - } - return {}; + return {}; + } + + [[nodiscard]] std::pair, + core_error_info> + replace(const core::transactions::transaction_get_result& document, + const std::vector& content) + { + try { + auto barrier = + std::make_shared>>(); + auto f = barrier->get_future(); + transaction_context_.replace( + document, + content, + [barrier](std::exception_ptr e, + std::optional res) mutable { + if (e) { + return barrier->set_exception(std::move(e)); + } + return barrier->set_value(std::move(res)); + }); + return { f.get(), {} }; + } catch (const core::transactions::transaction_operation_failed& e) { + return { {}, + { transactions_errc::operation_failed, + ERROR_LOCATION, + fmt::format("unable to replace document: {}, cause: {}, id=\"{}\"", + e.what(), + external_exception_to_string(e.cause()), + document.key()), + build_error_context(e) } }; + } catch (const std::exception& e) { + return { {}, + { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format( + "unable to replace document: {}, id=\"{}\"", e.what(), document.key()) } }; + } catch (...) { + return { {}, + { transactions_errc::unexpected_exception, + ERROR_LOCATION, + fmt::format("unable to replace document: unexpected C++ exception, id=\"{}\"", + document.key()) } }; } - - [[nodiscard]] core_error_info remove(const core::transactions::transaction_get_result& document) - { - try { - auto barrier = std::make_shared>(); - auto f = barrier->get_future(); - transaction_context_.remove(document, [barrier](std::exception_ptr e) { - if (e) { - return barrier->set_exception(std::move(e)); - } - return barrier->set_value(); - }); - f.get(); - } catch (const core::transactions::transaction_operation_failed& e) { - return { transactions_errc::operation_failed, - ERROR_LOCATION, - fmt::format("unable to remove document: {}, cause: {}, id=\"{}\"", - e.what(), - external_exception_to_string(e.cause()), - document.key()), - build_error_context(e) }; - } catch (const std::exception& e) { - return { transactions_errc::std_exception, - ERROR_LOCATION, - fmt::format("unable to remove document: {}, id=\"{}\"", e.what(), document.key()) }; - } catch (...) { - return { transactions_errc::unexpected_exception, - ERROR_LOCATION, - fmt::format("unable to remove document: unexpected C++ exception, id=\"{}\"", document.key()) }; + return {}; + } + + [[nodiscard]] core_error_info remove(const core::transactions::transaction_get_result& document) + { + try { + auto barrier = std::make_shared>(); + auto f = barrier->get_future(); + transaction_context_.remove(document, [barrier](std::exception_ptr e) { + if (e) { + return barrier->set_exception(std::move(e)); } - return {}; + return barrier->set_value(); + }); + f.get(); + } catch (const core::transactions::transaction_operation_failed& e) { + return { transactions_errc::operation_failed, + ERROR_LOCATION, + fmt::format("unable to remove document: {}, cause: {}, id=\"{}\"", + e.what(), + external_exception_to_string(e.cause()), + document.key()), + build_error_context(e) }; + } catch (const std::exception& e) { + return { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format("unable to remove document: {}, id=\"{}\"", e.what(), document.key()) }; + } catch (...) { + return { transactions_errc::unexpected_exception, + ERROR_LOCATION, + fmt::format("unable to remove document: unexpected C++ exception, id=\"{}\"", + document.key()) }; } - - [[nodiscard]] std::pair, core_error_info> query( - const std::string& statement, - const transactions::transaction_query_options& options) - { - try { - auto barrier = std::make_shared>>(); - auto f = barrier->get_future(); - transaction_context_.query( - statement, options, [barrier](std::exception_ptr e, std::optional res) { - if (e) { - return barrier->set_exception(std::move(e)); - } - return barrier->set_value(std::move(res)); - }); - return { f.get(), {} }; - } catch (const core::transactions::transaction_operation_failed& e) { - return { {}, - { transactions_errc::operation_failed, - ERROR_LOCATION, - fmt::format("unable to execute query: {}, cause: {}", e.what(), external_exception_to_string(e.cause())), - build_error_context(e) } }; - } catch (const std::exception& e) { - return { {}, { transactions_errc::std_exception, ERROR_LOCATION, fmt::format("unable to execute query: {}", e.what()) } }; - } catch (...) { - return { {}, { transactions_errc::unexpected_exception, ERROR_LOCATION, "unable to execute query: unexpected C++ exception" } }; - } - return { {}, {} }; + return {}; + } + + [[nodiscard]] std::pair, core_error_info> query( + const std::string& statement, + const transactions::transaction_query_options& options) + { + try { + auto barrier = + std::make_shared>>(); + auto f = barrier->get_future(); + transaction_context_.query( + statement, + options, + [barrier](std::exception_ptr e, std::optional res) { + if (e) { + return barrier->set_exception(std::move(e)); + } + return barrier->set_value(std::move(res)); + }); + return { f.get(), {} }; + } catch (const core::transactions::transaction_operation_failed& e) { + return { {}, + { transactions_errc::operation_failed, + ERROR_LOCATION, + fmt::format("unable to execute query: {}, cause: {}", + e.what(), + external_exception_to_string(e.cause())), + build_error_context(e) } }; + } catch (const std::exception& e) { + return { {}, + { transactions_errc::std_exception, + ERROR_LOCATION, + fmt::format("unable to execute query: {}", e.what()) } }; + } catch (...) { + return { {}, + { transactions_errc::unexpected_exception, + ERROR_LOCATION, + "unable to execute query: unexpected C++ exception" } }; } + return { {}, {} }; + } - private: - core::transactions::transaction_context transaction_context_; +private: + core::transactions::transaction_context transaction_context_; }; COUCHBASE_API -transaction_context_resource::transaction_context_resource(transactions_resource* transactions, - const transactions::transaction_options& configuration) - : impl_{ std::make_shared(transactions->transactions(), configuration) } +transaction_context_resource::transaction_context_resource( + transactions_resource* transactions, + const transactions::transaction_options& configuration) + : impl_{ std::make_shared(transactions->transactions(), + configuration) } { } @@ -426,241 +481,277 @@ COUCHBASE_API core_error_info transaction_context_resource::new_attempt() { - return impl_->new_attempt(); + return impl_->new_attempt(); } COUCHBASE_API core_error_info transaction_context_resource::commit(zval* return_value) { - ZVAL_NULL(return_value); + ZVAL_NULL(return_value); - auto [resp, err] = impl_->commit(); - if (err.ec) { - return err; - } - if (resp) { - array_init(return_value); - add_assoc_stringl(return_value, "transactionId", resp->transaction_id.data(), resp->transaction_id.size()); - add_assoc_bool(return_value, "unstagingComplete", resp->unstaging_complete); - } - return {}; + auto [resp, err] = impl_->commit(); + if (err.ec) { + return err; + } + if (resp) { + array_init(return_value); + add_assoc_stringl( + return_value, "transactionId", resp->transaction_id.data(), resp->transaction_id.size()); + add_assoc_bool(return_value, "unstagingComplete", resp->unstaging_complete); + } + return {}; } COUCHBASE_API core_error_info transaction_context_resource::rollback() { - return impl_->rollback(); + return impl_->rollback(); } static void -transaction_get_result_to_zval(zval* return_value, const core::transactions::transaction_get_result& res) +transaction_get_result_to_zval(zval* return_value, + const core::transactions::transaction_get_result& res) { - array_init(return_value); - add_assoc_stringl(return_value, "id", res.key().data(), res.key().size()); - add_assoc_stringl(return_value, "collectionName", res.collection().data(), res.collection().size()); - add_assoc_stringl(return_value, "scopeName", res.scope().data(), res.scope().size()); - add_assoc_stringl(return_value, "bucketName", res.bucket().data(), res.bucket().size()); - { - auto cas = fmt::format("{:x}", res.cas().value()); - add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); - } - { - const auto& value = res.content(); - add_assoc_stringl(return_value, "value", reinterpret_cast(value.data()), value.size()); - } - if (res.metadata()) { - zval meta; - array_init(&meta); - if (res.metadata()->cas()) { - add_assoc_stringl(&meta, "cas", res.metadata()->cas()->data(), res.metadata()->cas()->size()); - } - if (res.metadata()->crc32()) { - add_assoc_stringl(&meta, "crc32", res.metadata()->crc32()->data(), res.metadata()->crc32()->size()); - } - if (res.metadata()->revid()) { - add_assoc_stringl(&meta, "revid", res.metadata()->revid()->data(), res.metadata()->revid()->size()); - } - if (res.metadata()->exptime()) { - add_assoc_long(&meta, "exptime", res.metadata()->exptime().value()); - } - add_assoc_zval(return_value, "metadata", &meta); - } - { - zval links; - array_init(&links); - if (res.links().atr_id()) { - add_assoc_stringl(&links, "atr_id", res.links().atr_id()->data(), res.links().atr_id()->size()); - } - if (res.links().atr_bucket_name()) { - add_assoc_stringl(&links, "atr_bucket_name", res.links().atr_bucket_name()->data(), res.links().atr_bucket_name()->size()); - } - if (res.links().atr_scope_name()) { - add_assoc_stringl(&links, "atr_scope_name", res.links().atr_scope_name()->data(), res.links().atr_scope_name()->size()); - } - if (res.links().atr_collection_name()) { - add_assoc_stringl( - &links, "atr_collection_name", res.links().atr_collection_name()->data(), res.links().atr_collection_name()->size()); - } - if (res.links().staged_transaction_id()) { - add_assoc_stringl( - &links, "staged_transaction_id", res.links().staged_transaction_id()->data(), res.links().staged_transaction_id()->size()); - } - if (res.links().staged_attempt_id()) { - add_assoc_stringl( - &links, "staged_attempt_id", res.links().staged_attempt_id()->data(), res.links().staged_attempt_id()->size()); - } - add_assoc_stringl(&links, - "staged_content", - reinterpret_cast(res.links().staged_content().data()), - res.links().staged_content().size()); - if (res.links().cas_pre_txn()) { - add_assoc_stringl(&links, "cas_pre_txn", res.links().cas_pre_txn()->data(), res.links().cas_pre_txn()->size()); - } - if (res.links().exptime_pre_txn()) { - add_assoc_long(&links, "exptime_pre_txn", res.links().exptime_pre_txn().value()); - } - if (res.links().crc32_of_staging()) { - add_assoc_stringl(&links, "crc32_of_staging", res.links().crc32_of_staging()->data(), res.links().crc32_of_staging()->size()); - } - if (res.links().op()) { - add_assoc_stringl(&links, "op", res.links().op()->data(), res.links().op()->size()); - } - if (res.links().forward_compat()) { - auto encoded = core::utils::json::generate(res.links().forward_compat().value()); - add_assoc_stringl(&links, "forward_compat", encoded.data(), encoded.size()); - } - add_assoc_bool(&links, "is_deleted", res.links().is_deleted()); - add_assoc_zval(return_value, "links", &links); - } + array_init(return_value); + add_assoc_stringl(return_value, "id", res.key().data(), res.key().size()); + add_assoc_stringl( + return_value, "collectionName", res.collection().data(), res.collection().size()); + add_assoc_stringl(return_value, "scopeName", res.scope().data(), res.scope().size()); + add_assoc_stringl(return_value, "bucketName", res.bucket().data(), res.bucket().size()); + { + auto cas = fmt::format("{:x}", res.cas().value()); + add_assoc_stringl(return_value, "cas", cas.data(), cas.size()); + } + { + const auto& value = res.content(); + add_assoc_stringl( + return_value, "value", reinterpret_cast(value.data()), value.size()); + } + if (res.metadata()) { + zval meta; + array_init(&meta); + if (res.metadata()->cas()) { + add_assoc_stringl(&meta, "cas", res.metadata()->cas()->data(), res.metadata()->cas()->size()); + } + if (res.metadata()->crc32()) { + add_assoc_stringl( + &meta, "crc32", res.metadata()->crc32()->data(), res.metadata()->crc32()->size()); + } + if (res.metadata()->revid()) { + add_assoc_stringl( + &meta, "revid", res.metadata()->revid()->data(), res.metadata()->revid()->size()); + } + if (res.metadata()->exptime()) { + add_assoc_long(&meta, "exptime", res.metadata()->exptime().value()); + } + add_assoc_zval(return_value, "metadata", &meta); + } + { + zval links; + array_init(&links); + if (res.links().atr_id()) { + add_assoc_stringl( + &links, "atr_id", res.links().atr_id()->data(), res.links().atr_id()->size()); + } + if (res.links().atr_bucket_name()) { + add_assoc_stringl(&links, + "atr_bucket_name", + res.links().atr_bucket_name()->data(), + res.links().atr_bucket_name()->size()); + } + if (res.links().atr_scope_name()) { + add_assoc_stringl(&links, + "atr_scope_name", + res.links().atr_scope_name()->data(), + res.links().atr_scope_name()->size()); + } + if (res.links().atr_collection_name()) { + add_assoc_stringl(&links, + "atr_collection_name", + res.links().atr_collection_name()->data(), + res.links().atr_collection_name()->size()); + } + if (res.links().staged_transaction_id()) { + add_assoc_stringl(&links, + "staged_transaction_id", + res.links().staged_transaction_id()->data(), + res.links().staged_transaction_id()->size()); + } + if (res.links().staged_attempt_id()) { + add_assoc_stringl(&links, + "staged_attempt_id", + res.links().staged_attempt_id()->data(), + res.links().staged_attempt_id()->size()); + } + add_assoc_stringl(&links, + "staged_content", + reinterpret_cast(res.links().staged_content().data()), + res.links().staged_content().size()); + if (res.links().cas_pre_txn()) { + add_assoc_stringl(&links, + "cas_pre_txn", + res.links().cas_pre_txn()->data(), + res.links().cas_pre_txn()->size()); + } + if (res.links().exptime_pre_txn()) { + add_assoc_long(&links, "exptime_pre_txn", res.links().exptime_pre_txn().value()); + } + if (res.links().crc32_of_staging()) { + add_assoc_stringl(&links, + "crc32_of_staging", + res.links().crc32_of_staging()->data(), + res.links().crc32_of_staging()->size()); + } + if (res.links().op()) { + add_assoc_stringl(&links, "op", res.links().op()->data(), res.links().op()->size()); + } + if (res.links().forward_compat()) { + auto encoded = core::utils::json::generate(res.links().forward_compat().value()); + add_assoc_stringl(&links, "forward_compat", encoded.data(), encoded.size()); + } + add_assoc_bool(&links, "is_deleted", res.links().is_deleted()); + add_assoc_zval(return_value, "links", &links); + } } static couchbase::core::document_id zval_to_document_id(const zval* document) { - std::string bucket; - std::string scope; - std::string collection; - std::string id; - cb_assign_string(bucket, document, "bucketName"); - cb_assign_string(scope, document, "scopeName"); - cb_assign_string(collection, document, "collectionName"); - cb_assign_string(id, document, "id"); - return { bucket, scope, collection, id }; + std::string bucket; + std::string scope; + std::string collection; + std::string id; + cb_assign_string(bucket, document, "bucketName"); + cb_assign_string(scope, document, "scopeName"); + cb_assign_string(collection, document, "collectionName"); + cb_assign_string(id, document, "id"); + return { bucket, scope, collection, id }; } static std::pair zval_to_links(const zval* document) { - const zval* links = zend_symtable_str_find(Z_ARRVAL_P(document), ZEND_STRL("links")); - if (links == nullptr) { - return { {}, {} }; - } - if (Z_TYPE_P(links) != IS_ARRAY) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "expected links to be an array in the document" } }; - } - std::optional atr_id; - std::optional atr_bucket_name; - std::optional atr_scope_name; - std::optional atr_collection_name; - std::optional staged_transaction_id; - std::optional staged_attempt_id; - std::optional staged_operation_id; - std::optional> staged_content; - std::optional cas_pre_txn; - std::optional revid_pre_txn; - std::optional exptime_pre_txn; - std::optional crc32_of_staging; - std::optional op; - std::optional forward_compat; - bool is_deleted{ false }; - - cb_assign_string(atr_id, links, "atr_id"); - cb_assign_string(atr_bucket_name, links, "atr_bucket_name"); - cb_assign_string(atr_scope_name, links, "atr_scope_name"); - cb_assign_string(atr_collection_name, links, "atr_collection_name"); - cb_assign_string(staged_transaction_id, links, "staged_transaction_id"); - cb_assign_string(staged_attempt_id, links, "staged_attempt_id"); - cb_assign_string(staged_operation_id, links, "staged_operation_id"); - cb_assign_binary(staged_content, links, "staged_content"); - cb_assign_string(cas_pre_txn, links, "cas_pre_txn"); - cb_assign_string(revid_pre_txn, links, "revid_pre_txn"); - cb_assign_string(crc32_of_staging, links, "crc32_of_staging"); - cb_assign_string(op, links, "op"); - cb_assign_integer(exptime_pre_txn, links, "exptime_pre_txn"); - cb_assign_string(forward_compat, links, "forward_compat"); - cb_assign_boolean(is_deleted, links, "is_deleted"); - - std::optional forward_compat_json; - if (forward_compat) { - forward_compat_json = core::utils::json::parse(forward_compat.value()); - } - - return { core::transactions::transaction_links{ atr_id, - atr_bucket_name, - atr_scope_name, - atr_collection_name, - staged_transaction_id, - staged_attempt_id, - staged_operation_id, - staged_content, - cas_pre_txn, - revid_pre_txn, - exptime_pre_txn, - crc32_of_staging, - op, - forward_compat_json, - is_deleted }, - {} }; + const zval* links = zend_symtable_str_find(Z_ARRVAL_P(document), ZEND_STRL("links")); + if (links == nullptr) { + return { {}, {} }; + } + if (Z_TYPE_P(links) != IS_ARRAY) { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + "expected links to be an array in the document" } }; + } + std::optional atr_id; + std::optional atr_bucket_name; + std::optional atr_scope_name; + std::optional atr_collection_name; + std::optional staged_transaction_id; + std::optional staged_attempt_id; + std::optional staged_operation_id; + std::optional> staged_content; + std::optional cas_pre_txn; + std::optional revid_pre_txn; + std::optional exptime_pre_txn; + std::optional crc32_of_staging; + std::optional op; + std::optional forward_compat; + bool is_deleted{ false }; + + cb_assign_string(atr_id, links, "atr_id"); + cb_assign_string(atr_bucket_name, links, "atr_bucket_name"); + cb_assign_string(atr_scope_name, links, "atr_scope_name"); + cb_assign_string(atr_collection_name, links, "atr_collection_name"); + cb_assign_string(staged_transaction_id, links, "staged_transaction_id"); + cb_assign_string(staged_attempt_id, links, "staged_attempt_id"); + cb_assign_string(staged_operation_id, links, "staged_operation_id"); + cb_assign_binary(staged_content, links, "staged_content"); + cb_assign_string(cas_pre_txn, links, "cas_pre_txn"); + cb_assign_string(revid_pre_txn, links, "revid_pre_txn"); + cb_assign_string(crc32_of_staging, links, "crc32_of_staging"); + cb_assign_string(op, links, "op"); + cb_assign_integer(exptime_pre_txn, links, "exptime_pre_txn"); + cb_assign_string(forward_compat, links, "forward_compat"); + cb_assign_boolean(is_deleted, links, "is_deleted"); + + std::optional forward_compat_json; + if (forward_compat) { + forward_compat_json = core::utils::json::parse(forward_compat.value()); + } + + return { core::transactions::transaction_links{ atr_id, + atr_bucket_name, + atr_scope_name, + atr_collection_name, + staged_transaction_id, + staged_attempt_id, + staged_operation_id, + staged_content, + cas_pre_txn, + revid_pre_txn, + exptime_pre_txn, + crc32_of_staging, + op, + forward_compat_json, + is_deleted }, + {} }; } static std::pair, core_error_info> zval_to_metadata(const zval* document) { - const zval* links = zend_symtable_str_find(Z_ARRVAL_P(document), ZEND_STRL("links")); - if (links == nullptr || Z_TYPE_P(links) == IS_NULL) { - return { {}, {} }; - } - if (Z_TYPE_P(links) != IS_ARRAY) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "expected metadata to be an array in the document" } }; - } - std::optional cas; - std::optional revid; - std::optional exptime; - std::optional crc32; - - cb_assign_string(cas, links, "cas"); - cb_assign_string(revid, links, "revid"); - cb_assign_string(crc32, links, "crc32"); - cb_assign_integer(exptime, links, "exptime"); - - return { core::transactions::document_metadata{ cas, revid, exptime, crc32 }, {} }; + const zval* links = zend_symtable_str_find(Z_ARRVAL_P(document), ZEND_STRL("links")); + if (links == nullptr || Z_TYPE_P(links) == IS_NULL) { + return { {}, {} }; + } + if (Z_TYPE_P(links) != IS_ARRAY) { + return { {}, + { errc::common::invalid_argument, + ERROR_LOCATION, + "expected metadata to be an array in the document" } }; + } + std::optional cas; + std::optional revid; + std::optional exptime; + std::optional crc32; + + cb_assign_string(cas, links, "cas"); + cb_assign_string(revid, links, "revid"); + cb_assign_string(crc32, links, "crc32"); + cb_assign_integer(exptime, links, "exptime"); + + return { core::transactions::document_metadata{ cas, revid, exptime, crc32 }, {} }; } static std::pair zval_to_transaction_get_result(const zval* document) { - if (document == nullptr || Z_TYPE_P(document) != IS_ARRAY) { - return { {}, { errc::common::invalid_argument, ERROR_LOCATION, "expected array for transaction document" } }; - } - - couchbase::cas cas{}; - if (auto e = cb_assign_cas(cas, document); e.ec) { - return { {}, e }; - } - std::vector content; - cb_assign_binary(content, document, "value"); - auto [links, e] = zval_to_links(document); - if (e.ec) { - return { {}, e }; - } - auto [metadata, err] = zval_to_metadata(document); - if (err.ec) { - return { {}, err }; - } - - return { core::transactions::transaction_get_result(zval_to_document_id(document), content, cas.value(), links, metadata), {} }; + if (document == nullptr || Z_TYPE_P(document) != IS_ARRAY) { + return { + {}, + { errc::common::invalid_argument, ERROR_LOCATION, "expected array for transaction document" } + }; + } + + couchbase::cas cas{}; + if (auto e = cb_assign_cas(cas, document); e.ec) { + return { {}, e }; + } + std::vector content; + cb_assign_binary(content, document, "value"); + auto [links, e] = zval_to_links(document); + if (e.ec) { + return { {}, e }; + } + auto [metadata, err] = zval_to_metadata(document); + if (err.ec) { + return { {}, err }; + } + + return { core::transactions::transaction_get_result( + zval_to_document_id(document), content, cas.value(), links, metadata), + {} }; } COUCHBASE_API @@ -671,22 +762,24 @@ transaction_context_resource::get(zval* return_value, const zend_string* collection, const zend_string* id) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - auto [resp, err] = impl_->get_optional(doc_id); - if (err.ec) { - return err; - } - if (!resp) { - return { errc::key_value::document_not_found, ERROR_LOCATION, fmt::format("unable to find document {} retrieve", doc_id) }; - } - transaction_get_result_to_zval(return_value, resp.value()); - return {}; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + auto [resp, err] = impl_->get_optional(doc_id); + if (err.ec) { + return err; + } + if (!resp) { + return { errc::key_value::document_not_found, + ERROR_LOCATION, + fmt::format("unable to find document {} retrieve", doc_id) }; + } + transaction_get_result_to_zval(return_value, resp.value()); + return {}; } COUCHBASE_API @@ -698,157 +791,174 @@ transaction_context_resource::insert(zval* return_value, const zend_string* id, const zend_string* value) { - couchbase::core::document_id doc_id{ - cb_string_new(bucket), - cb_string_new(scope), - cb_string_new(collection), - cb_string_new(id), - }; - - auto [resp, err] = impl_->insert(doc_id, cb_binary_new(value)); - if (err.ec) { - return err; - } - if (!resp) { - return { errc::key_value::document_not_found, ERROR_LOCATION, fmt::format("unable to find document {} to insert", doc_id) }; - } - transaction_get_result_to_zval(return_value, resp.value()); - return {}; + couchbase::core::document_id doc_id{ + cb_string_new(bucket), + cb_string_new(scope), + cb_string_new(collection), + cb_string_new(id), + }; + + auto [resp, err] = impl_->insert(doc_id, cb_binary_new(value)); + if (err.ec) { + return err; + } + if (!resp) { + return { errc::key_value::document_not_found, + ERROR_LOCATION, + fmt::format("unable to find document {} to insert", doc_id) }; + } + transaction_get_result_to_zval(return_value, resp.value()); + return {}; } COUCHBASE_API core_error_info -transaction_context_resource::replace(zval* return_value, const zval* document, const zend_string* value) +transaction_context_resource::replace(zval* return_value, + const zval* document, + const zend_string* value) { - auto [doc, e] = zval_to_transaction_get_result(document); - if (e.ec) { - return e; - } - auto [resp, err] = impl_->replace(doc, cb_binary_new(value)); - if (err.ec) { - return err; - } - if (!resp) { - return { errc::key_value::document_not_found, - ERROR_LOCATION, - fmt::format("unable to find document {} to replace its content", doc.id()) }; - } - transaction_get_result_to_zval(return_value, resp.value()); - return {}; + auto [doc, e] = zval_to_transaction_get_result(document); + if (e.ec) { + return e; + } + auto [resp, err] = impl_->replace(doc, cb_binary_new(value)); + if (err.ec) { + return err; + } + if (!resp) { + return { errc::key_value::document_not_found, + ERROR_LOCATION, + fmt::format("unable to find document {} to replace its content", doc.id()) }; + } + transaction_get_result_to_zval(return_value, resp.value()); + return {}; } COUCHBASE_API core_error_info transaction_context_resource::remove(const zval* document) { - auto [doc, e] = zval_to_transaction_get_result(document); - if (e.ec) { - return e; - } - if (auto err = impl_->remove(doc); err.ec) { - return err; - } - return {}; + auto [doc, e] = zval_to_transaction_get_result(document); + if (e.ec) { + return e; + } + if (auto err = impl_->remove(doc); err.ec) { + return err; + } + return {}; } COUCHBASE_API core_error_info -transaction_context_resource::query(zval* return_value, const zend_string* statement, const zval* options) +transaction_context_resource::query(zval* return_value, + const zend_string* statement, + const zval* options) { - auto [query_options, e] = zval_to_transactions_query_options(options); - if (e.ec) { - return e; - } - auto [resp, err] = impl_->query(cb_string_new(statement), query_options); - if (err.ec) { - return err; - } - if (resp.has_value()) { - query_response_to_zval(return_value, resp.value()); - } - return {}; + auto [query_options, e] = zval_to_transactions_query_options(options); + if (e.ec) { + return e; + } + auto [resp, err] = impl_->query(cb_string_new(statement), query_options); + if (err.ec) { + return err; + } + if (resp.has_value()) { + query_response_to_zval(return_value, resp.value()); + } + return {}; } -#define ASSIGN_DURATION_OPTION(name, setter, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - if (Z_TYPE_P(value) != IS_LONG) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected duration as a number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - zend_long ms = Z_LVAL_P(value); \ - if (ms < 0) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected duration as a positive number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - (setter)(std::chrono::milliseconds(ms)); \ - } +#define ASSIGN_DURATION_OPTION(name, setter, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + if (Z_TYPE_P(value) != IS_LONG) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected duration as a number for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + zend_long ms = Z_LVAL_P(value); \ + if (ms < 0) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected duration as a positive number for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + (setter)(std::chrono::milliseconds(ms)); \ + } static core_error_info apply_options(transactions::transaction_options& config, zval* options) { - if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for per transaction configuration" }; - } - - const zend_string* key; - const zval* value; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) - { - ASSIGN_DURATION_OPTION("timeout", config.timeout, key, value); - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("durabilityLevel")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected durabilityLevel to be a string" }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { - config.durability_level(couchbase::durability_level::none); - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majority")) == 0) { - config.durability_level(couchbase::durability_level::majority); - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majorityAndPersistToActive")) == 0) { - config.durability_level(couchbase::durability_level::majority_and_persist_to_active); - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("persistToMajority")) == 0) { - config.durability_level(couchbase::durability_level::persist_to_majority); - } else { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("unknown durabilityLevel: {}", std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }; - } - } + if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected array for per transaction configuration" }; + } + + const zend_string* key; + const zval* value; + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) + { + ASSIGN_DURATION_OPTION("timeout", config.timeout, key, value); + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("durabilityLevel")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected durabilityLevel to be a string" }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { + config.durability_level(couchbase::durability_level::none); + } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majority")) == + 0) { + config.durability_level(couchbase::durability_level::majority); + } else if (zend_binary_strcmp(Z_STRVAL_P(value), + Z_STRLEN_P(value), + ZEND_STRL("majorityAndPersistToActive")) == 0) { + config.durability_level(couchbase::durability_level::majority_and_persist_to_active); + } else if (zend_binary_strcmp( + Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("persistToMajority")) == 0) { + config.durability_level(couchbase::durability_level::persist_to_majority); + } else { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unknown durabilityLevel: {}", + std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }; + } } - ZEND_HASH_FOREACH_END(); + } + ZEND_HASH_FOREACH_END(); - return {}; + return {}; } COUCHBASE_API std::pair create_transaction_context_resource(transactions_resource* connection, zval* options) { - transactions::transaction_options configuration{}; - if (auto e = apply_options(configuration, options); e.ec) { - return { nullptr, e }; - } - auto* handle = new transaction_context_resource(connection, configuration); - return { zend_register_resource(handle, transaction_context_destructor_id_), {} }; + transactions::transaction_options configuration{}; + if (auto e = apply_options(configuration, options); e.ec) { + return { nullptr, e }; + } + auto* handle = new transaction_context_resource(connection, configuration); + return { zend_register_resource(handle, transaction_context_destructor_id_), {} }; } COUCHBASE_API void destroy_transaction_context_resource(zend_resource* res) { - if (res->type == transaction_context_destructor_id_ && res->ptr != nullptr) { - auto* handle = static_cast(res->ptr); - res->ptr = nullptr; - delete handle; - } + if (res->type == transaction_context_destructor_id_ && res->ptr != nullptr) { + auto* handle = static_cast(res->ptr); + res->ptr = nullptr; + delete handle; + } } } // namespace couchbase::php diff --git a/src/wrapper/transaction_context_resource.hxx b/src/wrapper/transaction_context_resource.hxx index 79602665..8c8fb6e4 100644 --- a/src/wrapper/transaction_context_resource.hxx +++ b/src/wrapper/transaction_context_resource.hxx @@ -36,44 +36,45 @@ namespace couchbase::php { class transaction_context_resource { - public: - COUCHBASE_API - transaction_context_resource(transactions_resource* transactions, const couchbase::transactions::transaction_options& configuration); - - COUCHBASE_API - core_error_info new_attempt(); - COUCHBASE_API - core_error_info commit(zval* return_value); - COUCHBASE_API - core_error_info rollback(); - - COUCHBASE_API - core_error_info get(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id); - - COUCHBASE_API - core_error_info insert(zval* return_value, - const zend_string* bucket, - const zend_string* scope, - const zend_string* collection, - const zend_string* id, - const zend_string* value); - - COUCHBASE_API - core_error_info replace(zval* return_value, const zval* document, const zend_string* value); - COUCHBASE_API - core_error_info remove(const zval* document); - - COUCHBASE_API - core_error_info query(zval* return_value, const zend_string* statement, const zval* options); - - private: - class impl; - - std::shared_ptr impl_; +public: + COUCHBASE_API + transaction_context_resource(transactions_resource* transactions, + const couchbase::transactions::transaction_options& configuration); + + COUCHBASE_API + core_error_info new_attempt(); + COUCHBASE_API + core_error_info commit(zval* return_value); + COUCHBASE_API + core_error_info rollback(); + + COUCHBASE_API + core_error_info get(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id); + + COUCHBASE_API + core_error_info insert(zval* return_value, + const zend_string* bucket, + const zend_string* scope, + const zend_string* collection, + const zend_string* id, + const zend_string* value); + + COUCHBASE_API + core_error_info replace(zval* return_value, const zval* document, const zend_string* value); + COUCHBASE_API + core_error_info remove(const zval* document); + + COUCHBASE_API + core_error_info query(zval* return_value, const zend_string* statement, const zval* options); + +private: + class impl; + + std::shared_ptr impl_; }; COUCHBASE_API std::pair diff --git a/src/wrapper/transactions_resource.cxx b/src/wrapper/transactions_resource.cxx index a7c96f7c..10759f68 100644 --- a/src/wrapper/transactions_resource.cxx +++ b/src/wrapper/transactions_resource.cxx @@ -34,51 +34,52 @@ COUCHBASE_API void set_transactions_destructor_id(int id) { - transactions_destructor_id_ = id; + transactions_destructor_id_ = id; } COUCHBASE_API int get_transactions_destructor_id() { - return transactions_destructor_id_; + return transactions_destructor_id_; } class transactions_resource::impl : public std::enable_shared_from_this { - public: - impl(connection_handle* connection, const couchbase::transactions::transactions_config& config) - : cluster_{ connection->cluster() } - , transactions_(*cluster_, config) - { - } +public: + impl(connection_handle* connection, const couchbase::transactions::transactions_config& config) + : cluster_{ connection->cluster() } + , transactions_(*cluster_, config) + { + } - impl(impl&& other) = delete; + impl(impl&& other) = delete; - impl(const impl& other) = delete; + impl(const impl& other) = delete; - const impl& operator=(impl&& other) = delete; + const impl& operator=(impl&& other) = delete; - const impl& operator=(const impl& other) = delete; + const impl& operator=(const impl& other) = delete; - [[nodiscard]] couchbase::core::transactions::transactions& transactions() - { - return transactions_; - } + [[nodiscard]] couchbase::core::transactions::transactions& transactions() + { + return transactions_; + } - void notify_fork(couchbase::fork_event event) - { - transactions_.notify_fork(event); - } + void notify_fork(couchbase::fork_event event) + { + transactions_.notify_fork(event); + } - private: - std::shared_ptr cluster_; - couchbase::core::transactions::transactions transactions_; +private: + std::shared_ptr cluster_; + couchbase::core::transactions::transactions transactions_; }; COUCHBASE_API -transactions_resource::transactions_resource(connection_handle* connection, - const couchbase::transactions::transactions_config& configuration) +transactions_resource::transactions_resource( + connection_handle* connection, + const couchbase::transactions::transactions_config& configuration) : impl_{ std::make_shared(connection, configuration) } { } @@ -87,222 +88,244 @@ COUCHBASE_API core::transactions::transactions& transactions_resource::transactions() { - return impl_->transactions(); + return impl_->transactions(); } void transactions_resource::notify_fork(fork_event event) const { - return impl_->notify_fork(event); + return impl_->notify_fork(event); } -#define ASSIGN_DURATION_OPTION(name, setter, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - if (Z_TYPE_P(value) != IS_LONG) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected duration as a number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - zend_long ms = Z_LVAL_P(value); \ - if (ms < 0) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected duration as a positive number for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - (setter)(std::chrono::milliseconds(ms)); \ - } - -#define ASSIGN_NEGATED_BOOLEAN_OPTION(name, setter, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - switch (Z_TYPE_P(value)) { \ - case IS_TRUE: \ - (setter)(false); \ - break; \ - case IS_FALSE: \ - (setter)(true); \ - break; \ - default: \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected boolean for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - } - -#define ASSIGN_STRING_OPTION(name, field, key, value) \ - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ - if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ - continue; \ - } \ - if (Z_TYPE_P(value) != IS_STRING) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - if (Z_STRLEN_P(value) == 0) { \ - return { errc::common::invalid_argument, \ - ERROR_LOCATION, \ - fmt::format("expected non-empty string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ - } \ - (field).assign(Z_STRVAL_P(value), Z_STRLEN_P(value)); \ - } +#define ASSIGN_DURATION_OPTION(name, setter, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + if (Z_TYPE_P(value) != IS_LONG) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected duration as a number for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + zend_long ms = Z_LVAL_P(value); \ + if (ms < 0) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected duration as a positive number for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + (setter)(std::chrono::milliseconds(ms)); \ + } + +#define ASSIGN_NEGATED_BOOLEAN_OPTION(name, setter, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + switch (Z_TYPE_P(value)) { \ + case IS_TRUE: \ + (setter)(false); \ + break; \ + case IS_FALSE: \ + (setter)(true); \ + break; \ + default: \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected boolean for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + } + +#define ASSIGN_STRING_OPTION(name, field, key, value) \ + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL(name)) == 0) { \ + if ((value) == nullptr || Z_TYPE_P(value) == IS_NULL) { \ + continue; \ + } \ + if (Z_TYPE_P(value) != IS_STRING) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected string for {}", std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + if (Z_STRLEN_P(value) == 0) { \ + return { errc::common::invalid_argument, \ + ERROR_LOCATION, \ + fmt::format("expected non-empty string for {}", \ + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; \ + } \ + (field).assign(Z_STRVAL_P(value), Z_STRLEN_P(value)); \ + } static core_error_info apply_options(couchbase::transactions::transactions_config& config, zval* options) { - if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected array for transactions configuration" }; + if (options == nullptr || Z_TYPE_P(options) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected array for transactions configuration" }; + } + + const zend_string* key; + const zval* value; + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) + { + ASSIGN_DURATION_OPTION("timeout", config.timeout, key, value); + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("durabilityLevel")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected durabilityLevel to be a string" }; + } + if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { + config.durability_level(couchbase::durability_level::none); + } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majority")) == + 0) { + config.durability_level(couchbase::durability_level::majority); + } else if (zend_binary_strcmp(Z_STRVAL_P(value), + Z_STRLEN_P(value), + ZEND_STRL("majorityAndPersistToActive")) == 0) { + config.durability_level(couchbase::durability_level::majority_and_persist_to_active); + } else if (zend_binary_strcmp( + Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("persistToMajority")) == 0) { + config.durability_level(couchbase::durability_level::persist_to_majority); + } else { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unknown durabilityLevel: {}", + std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }; + } } - const zend_string* key; - const zval* value; - - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) - { - ASSIGN_DURATION_OPTION("timeout", config.timeout, key, value); - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("durabilityLevel")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected durabilityLevel to be a string" }; - } - if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("none")) == 0) { - config.durability_level(couchbase::durability_level::none); - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majority")) == 0) { - config.durability_level(couchbase::durability_level::majority); - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("majorityAndPersistToActive")) == 0) { - config.durability_level(couchbase::durability_level::majority_and_persist_to_active); - } else if (zend_binary_strcmp(Z_STRVAL_P(value), Z_STRLEN_P(value), ZEND_STRL("persistToMajority")) == 0) { - config.durability_level(couchbase::durability_level::persist_to_majority); - } else { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("unknown durabilityLevel: {}", std::string_view(Z_STRVAL_P(value), Z_STRLEN_P(value))) }; - } - } - - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("queryOptions")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_ARRAY) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected array for {} as query options for transactions", - std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - - const zend_string* k; - const zval* v; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) - { - if (zend_binary_strcmp(ZSTR_VAL(k), ZSTR_LEN(k), ZEND_STRL("scanConsistency")) == 0) { - if (v == nullptr || Z_TYPE_P(v) == IS_NULL) { - continue; - } - if (Z_TYPE_P(v) != IS_STRING) { - return { errc::common::invalid_argument, ERROR_LOCATION, "expected scanConsistency to be a string" }; - } - if (zend_binary_strcmp(Z_STRVAL_P(v), Z_STRLEN_P(v), ZEND_STRL("notBounded")) == 0) { - config.query_config().scan_consistency(query_scan_consistency::not_bounded); - } else if (zend_binary_strcmp(Z_STRVAL_P(v), Z_STRLEN_P(v), ZEND_STRL("requestPlus")) == 0) { - config.query_config().scan_consistency(query_scan_consistency::request_plus); - } else { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("unknown scanConsistency: {}", std::string_view(Z_STRVAL_P(v), Z_STRLEN_P(v))) }; - } - } - } - ZEND_HASH_FOREACH_END(); + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("queryOptions")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected array for {} as query options for transactions", + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; + } + + const zend_string* k; + const zval* v; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) + { + if (zend_binary_strcmp(ZSTR_VAL(k), ZSTR_LEN(k), ZEND_STRL("scanConsistency")) == 0) { + if (v == nullptr || Z_TYPE_P(v) == IS_NULL) { + continue; + } + if (Z_TYPE_P(v) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected scanConsistency to be a string" }; + } + if (zend_binary_strcmp(Z_STRVAL_P(v), Z_STRLEN_P(v), ZEND_STRL("notBounded")) == 0) { + config.query_config().scan_consistency(query_scan_consistency::not_bounded); + } else if (zend_binary_strcmp(Z_STRVAL_P(v), Z_STRLEN_P(v), ZEND_STRL("requestPlus")) == + 0) { + config.query_config().scan_consistency(query_scan_consistency::request_plus); + } else { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("unknown scanConsistency: {}", + std::string_view(Z_STRVAL_P(v), Z_STRLEN_P(v))) }; + } } + } + ZEND_HASH_FOREACH_END(); + } - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("cleanupOptions")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_ARRAY) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected array for {} as cleanup options for transactions", - std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - - const zend_string* k; - const zval* v; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) - { - ASSIGN_DURATION_OPTION("cleanupWindow", config.cleanup_config().cleanup_window, k, v); - ASSIGN_NEGATED_BOOLEAN_OPTION("disableLostAttemptCleanup", config.cleanup_config().cleanup_lost_attempts, k, v); - ASSIGN_NEGATED_BOOLEAN_OPTION("disableClientAttemptCleanup", config.cleanup_config().cleanup_client_attempts, k, v); - } - ZEND_HASH_FOREACH_END(); - } + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("cleanupOptions")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected array for {} as cleanup options for transactions", + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; + } + + const zend_string* k; + const zval* v; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) + { + ASSIGN_DURATION_OPTION("cleanupWindow", config.cleanup_config().cleanup_window, k, v); + ASSIGN_NEGATED_BOOLEAN_OPTION( + "disableLostAttemptCleanup", config.cleanup_config().cleanup_lost_attempts, k, v); + ASSIGN_NEGATED_BOOLEAN_OPTION( + "disableClientAttemptCleanup", config.cleanup_config().cleanup_client_attempts, k, v); + } + ZEND_HASH_FOREACH_END(); + } - if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("metadataCollection")) == 0) { - if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { - continue; - } - if (Z_TYPE_P(value) != IS_ARRAY) { - return { errc::common::invalid_argument, - ERROR_LOCATION, - fmt::format("expected array for {} as metadata collection for transactions", - std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; - } - - const zend_string* k; - const zval* v; - std::string bucket; - std::string scope; - std::string collection; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) - { - ASSIGN_STRING_OPTION("bucket", bucket, k, v); - ASSIGN_STRING_OPTION("scope", scope, k, v); - ASSIGN_STRING_OPTION("collection", collection, k, v); - } - ZEND_HASH_FOREACH_END(); - config.metadata_collection({ bucket, scope, collection }); - } + if (zend_binary_strcmp(ZSTR_VAL(key), ZSTR_LEN(key), ZEND_STRL("metadataCollection")) == 0) { + if (value == nullptr || Z_TYPE_P(value) == IS_NULL) { + continue; + } + if (Z_TYPE_P(value) != IS_ARRAY) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + fmt::format("expected array for {} as metadata collection for transactions", + std::string(ZSTR_VAL(key), ZSTR_LEN(key))) }; + } + + const zend_string* k; + const zval* v; + std::string bucket; + std::string scope; + std::string collection; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(value), k, v) + { + ASSIGN_STRING_OPTION("bucket", bucket, k, v); + ASSIGN_STRING_OPTION("scope", scope, k, v); + ASSIGN_STRING_OPTION("collection", collection, k, v); + } + ZEND_HASH_FOREACH_END(); + config.metadata_collection({ bucket, scope, collection }); } - ZEND_HASH_FOREACH_END(); + } + ZEND_HASH_FOREACH_END(); - return {}; + return {}; } COUCHBASE_API std::pair create_transactions_resource(connection_handle* connection, zval* options) { - couchbase::transactions::transactions_config config{}; - if (auto e = apply_options(config, options); e.ec) { - return { nullptr, e }; - } - // ensure that metadata collection is opened - if (auto metadata_collection = config.metadata_collection(); metadata_collection && !metadata_collection->bucket.empty()) { - if (auto e = connection->bucket_open(metadata_collection->bucket); e.ec) { - return { nullptr, e }; - } + couchbase::transactions::transactions_config config{}; + if (auto e = apply_options(config, options); e.ec) { + return { nullptr, e }; + } + // ensure that metadata collection is opened + if (auto metadata_collection = config.metadata_collection(); + metadata_collection && !metadata_collection->bucket.empty()) { + if (auto e = connection->bucket_open(metadata_collection->bucket); e.ec) { + return { nullptr, e }; } - auto* handle = new transactions_resource(connection, config); - return { zend_register_resource(handle, transactions_destructor_id_), {} }; + } + auto* handle = new transactions_resource(connection, config); + return { zend_register_resource(handle, transactions_destructor_id_), {} }; } COUCHBASE_API void destroy_transactions_resource(zend_resource* res) { - if (res->type == transactions_destructor_id_ && res->ptr != nullptr) { - auto* handle = static_cast(res->ptr); - res->ptr = nullptr; - std::thread([handle]() { delete handle; }).detach(); - } + if (res->type == transactions_destructor_id_ && res->ptr != nullptr) { + auto* handle = static_cast(res->ptr); + res->ptr = nullptr; + std::thread([handle]() { + delete handle; + }).detach(); + } } } // namespace couchbase::php diff --git a/src/wrapper/transactions_resource.hxx b/src/wrapper/transactions_resource.hxx index 17b0a5ff..2cd60375 100644 --- a/src/wrapper/transactions_resource.hxx +++ b/src/wrapper/transactions_resource.hxx @@ -43,19 +43,20 @@ namespace couchbase::php { class transactions_resource { - public: - COUCHBASE_API - transactions_resource(connection_handle* connection, const couchbase::transactions::transactions_config& configuration); +public: + COUCHBASE_API + transactions_resource(connection_handle* connection, + const couchbase::transactions::transactions_config& configuration); - COUCHBASE_API - core::transactions::transactions& transactions(); + COUCHBASE_API + core::transactions::transactions& transactions(); - void notify_fork(fork_event event) const; + void notify_fork(fork_event event) const; - private: - class impl; +private: + class impl; - std::shared_ptr impl_; + std::shared_ptr impl_; }; COUCHBASE_API std::pair diff --git a/src/wrapper/version.cxx b/src/wrapper/version.cxx index 9e147476..a46872ea 100644 --- a/src/wrapper/version.cxx +++ b/src/wrapper/version.cxx @@ -27,34 +27,36 @@ COUCHBASE_API void core_version(zval* return_value) { - array_init(return_value); - - add_assoc_string(return_value, "extension_revision", COUCHBASE_EXTENSION_GIT_REVISION); - add_assoc_string(return_value, "cxx_client_revision", COUCHBASE_CXX_CLIENT_GIT_REVISION); - - for (const auto& [name, value] : core::meta::sdk_build_info()) { - if (name == "version_major" || name == "version_minor" || name == "version_patch" || name == "version_build" || - name == "__cplusplus" || name == "_MSC_VER" || name == "mozilla_ca_bundle_size") { - add_assoc_long_ex(return_value, name.c_str(), name.size(), std::stoi(value)); - } else if (name == "snapshot" || name == "static_stdlib" || name == "static_openssl" || name == "mozilla_ca_bundle_embedded") { - add_assoc_bool_ex(return_value, name.c_str(), name.size(), value == "true"); - } else { - add_assoc_stringl_ex(return_value, name.c_str(), name.size(), value.c_str(), value.size()); - } + array_init(return_value); + + add_assoc_string(return_value, "extension_revision", COUCHBASE_EXTENSION_GIT_REVISION); + add_assoc_string(return_value, "cxx_client_revision", COUCHBASE_CXX_CLIENT_GIT_REVISION); + + for (const auto& [name, value] : core::meta::sdk_build_info()) { + if (name == "version_major" || name == "version_minor" || name == "version_patch" || + name == "version_build" || name == "__cplusplus" || name == "_MSC_VER" || + name == "mozilla_ca_bundle_size") { + add_assoc_long_ex(return_value, name.c_str(), name.size(), std::stoi(value)); + } else if (name == "snapshot" || name == "static_stdlib" || name == "static_openssl" || + name == "mozilla_ca_bundle_embedded") { + add_assoc_bool_ex(return_value, name.c_str(), name.size(), value == "true"); + } else { + add_assoc_stringl_ex(return_value, name.c_str(), name.size(), value.c_str(), value.size()); } + } } COUCHBASE_API const char* extension_revision() { - return COUCHBASE_EXTENSION_GIT_REVISION; + return COUCHBASE_EXTENSION_GIT_REVISION; } COUCHBASE_API const char* cxx_client_revision() { - return COUCHBASE_CXX_CLIENT_GIT_REVISION; + return COUCHBASE_CXX_CLIENT_GIT_REVISION; } } // namespace couchbase::php diff --git a/src/wrapper/wrapper.hxx b/src/wrapper/wrapper.hxx index 5e637011..4ff05ae0 100644 --- a/src/wrapper/wrapper.hxx +++ b/src/wrapper/wrapper.hxx @@ -17,7 +17,8 @@ #pragma once /** - * core library depends on PHP runtime, so make sure it does not demand PHP symbols during link phase + * core library depends on PHP runtime, so make sure it does not demand PHP symbols during link + * phase */ #undef LIBZEND_EXPORTS #undef COUCHBASE_EXPORTS