From ac4ad2c3fb4b7d4d2780d3ab2e64ec4f489a4079 Mon Sep 17 00:00:00 2001 From: Sergey Avseyev Date: Fri, 19 Jul 2024 18:19:05 -0700 Subject: [PATCH] Update core to 1.0.0 https://github.com/couchbase/couchbase-cxx-client/releases/tag/1.0.0 --- couchbase.gemspec | 1 + ...-for-mingw-w64-ucrt-x86_64-toolchain.patch | 40 ++ ext/couchbase | 2 +- ext/extconf.rb | 5 + ext/rcb_analytics.cxx | 211 +++---- ext/rcb_backend.cxx | 572 +++++++++++------- ext/rcb_backend.hxx | 9 +- ext/rcb_buckets.cxx | 66 +- ext/rcb_collections.cxx | 66 +- ext/rcb_crud.cxx | 174 +++--- ext/rcb_diagnostics.cxx | 26 +- ext/rcb_exceptions.cxx | 89 +-- ext/rcb_exceptions.hxx | 21 +- ext/rcb_extras.cxx | 47 +- ext/rcb_multi.cxx | 62 +- ext/rcb_query.cxx | 142 ++--- ext/rcb_range_scan.cxx | 33 +- ext/rcb_search.cxx | 164 +++-- ext/rcb_users.cxx | 110 ++-- ext/rcb_utils.cxx | 153 +++++ ext/rcb_utils.hxx | 68 ++- ext/rcb_views.cxx | 54 +- lib/couchbase/errors.rb | 52 +- 23 files changed, 1209 insertions(+), 958 deletions(-) create mode 100644 ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch diff --git a/couchbase.gemspec b/couchbase.gemspec index bd8900aa..d47b7122 100644 --- a/couchbase.gemspec +++ b/couchbase.gemspec @@ -46,6 +46,7 @@ Gem::Specification.new do |spec| "ext/*.cxx", "ext/*.hxx", "ext/*.hxx.in", + "ext/*.patch", "ext/*.rb", "ext/CMakeLists.txt", "ext/cache/**/*", diff --git a/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch b/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch new file mode 100644 index 00000000..51e8ef9e --- /dev/null +++ b/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch @@ -0,0 +1,40 @@ +From 6bdc93aac66f2282823dceee802b60e2447c4ba9 Mon Sep 17 00:00:00 2001 +From: Sergey Avseyev +Date: Fri, 20 Oct 2023 20:48:33 -0700 +Subject: [PATCH] fix build for mingw-w64-ucrt-x86_64-toolchain + +--- + src/crypto/CMakeLists.txt | 4 ++++ + src/crypto/curve25519/internal.h | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt +index 68fb65b30..f53a9eee9 100644 +--- a/src/crypto/CMakeLists.txt ++++ b/src/crypto/CMakeLists.txt +@@ -335,6 +335,10 @@ if(WIN32) + target_link_libraries(crypto ws2_32) + endif() + ++if(MINGW) ++ target_link_libraries(crypto --static-libgcc --static-libstdc++) ++endif() ++ + if(NOT ANDROID) + find_package(Threads REQUIRED) + target_link_libraries(crypto Threads::Threads) +diff --git a/src/crypto/curve25519/internal.h b/src/crypto/curve25519/internal.h +index 0cd1a12aa..ab33badc0 100644 +--- a/src/crypto/curve25519/internal.h ++++ b/src/crypto/curve25519/internal.h +@@ -32,7 +32,7 @@ void x25519_NEON(uint8_t out[32], const uint8_t scalar[32], + #endif + + #if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && \ +- defined(__GNUC__) && defined(__x86_64__) ++ defined(__GNUC__) && defined(__x86_64__) && !defined(__MINGW32__) + #define BORINGSSL_FE25519_ADX + + // fiat_curve25519_adx_mul is defined in +-- +2.42.0.windows.2 diff --git a/ext/couchbase b/ext/couchbase index f72a089b..65c8d1ff 160000 --- a/ext/couchbase +++ b/ext/couchbase @@ -1 +1 @@ -Subproject commit f72a089b49d2eaa9cb63e414811daa44eee5a9f3 +Subproject commit 65c8d1ff65bdcb02ac83b3209b4f9e674ea593b4 diff --git a/ext/extconf.rb b/ext/extconf.rb index 0a7a5ab2..ff6d40e7 100644 --- a/ext/extconf.rb +++ b/ext/extconf.rb @@ -141,6 +141,11 @@ def sys(*cmd) cmake_flags << "-DCMAKE_AR=#{ar}" if ar project_path = File.expand_path(File.join(__dir__)) + +Dir.glob(File.join(project_path, "*.patch")).each do |path| + FileUtils.cp(path, File.join(project_path, "couchbase", "cmake"), verbose: true) +end + build_dir = ENV['CB_EXT_BUILD_DIR'] || File.join(Dir.tmpdir, "cb-#{build_type}-#{RUBY_VERSION}-#{RUBY_PATCHLEVEL}-#{RUBY_PLATFORM}-#{SDK_VERSION}") FileUtils.rm_rf(build_dir, verbose: true) unless ENV['CB_PRESERVE_BUILD_DIR'] diff --git a/ext/rcb_analytics.cxx b/ext/rcb_analytics.cxx index 6796a78d..26c6215a 100644 --- a/ext/rcb_analytics.cxx +++ b/ext/rcb_analytics.cxx @@ -53,16 +53,15 @@ namespace VALUE cb_Backend_analytics_get_pending_mutations(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_get_pending_mutations_request req{}; cb_extract_timeout(req, options); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -94,16 +93,15 @@ cb_Backend_analytics_get_pending_mutations(VALUE self, VALUE options) VALUE cb_Backend_analytics_dataset_get_all(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_dataset_get_all_request req{}; cb_extract_timeout(req, options); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -139,7 +137,7 @@ cb_Backend_analytics_dataset_get_all(VALUE self, VALUE options) VALUE cb_Backend_analytics_dataset_drop(VALUE self, VALUE dataset_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(dataset_name, T_STRING); @@ -153,11 +151,10 @@ cb_Backend_analytics_dataset_drop(VALUE self, VALUE dataset_name, VALUE options) req.dataverse_name = cb_string_new(dataverse_name); } cb_extract_option_bool(req.ignore_if_does_not_exist, options, "ignore_if_does_not_exist"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -191,7 +188,7 @@ cb_Backend_analytics_dataset_create(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(dataset_name, T_STRING); Check_Type(bucket_name, T_STRING); @@ -204,11 +201,10 @@ cb_Backend_analytics_dataset_create(VALUE self, cb_extract_option_string(req.condition, options, "condition"); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.ignore_if_exists, options, "ignore_if_exists"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -239,7 +235,7 @@ cb_Backend_analytics_dataset_create(VALUE self, VALUE cb_Backend_analytics_dataverse_drop(VALUE self, VALUE dataverse_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(dataverse_name, T_STRING); @@ -248,11 +244,10 @@ cb_Backend_analytics_dataverse_drop(VALUE self, VALUE dataverse_name, VALUE opti cb_extract_timeout(req, options); req.dataverse_name = cb_string_new(dataverse_name); cb_extract_option_bool(req.ignore_if_does_not_exist, options, "ignore_if_does_not_exist"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { if (resp.errors.empty()) { @@ -279,7 +274,7 @@ cb_Backend_analytics_dataverse_drop(VALUE self, VALUE dataverse_name, VALUE opti VALUE cb_Backend_analytics_dataverse_create(VALUE self, VALUE dataverse_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(dataverse_name, T_STRING); if (!NIL_P(dataverse_name)) { @@ -291,11 +286,10 @@ cb_Backend_analytics_dataverse_create(VALUE self, VALUE dataverse_name, VALUE op cb_extract_timeout(req, options); req.dataverse_name = cb_string_new(dataverse_name); cb_extract_option_bool(req.ignore_if_exists, options, "ignore_if_exists"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { if (resp.errors.empty()) { @@ -323,16 +317,15 @@ cb_Backend_analytics_dataverse_create(VALUE self, VALUE dataverse_name, VALUE op VALUE cb_Backend_analytics_index_get_all(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_index_get_all_request req{}; cb_extract_timeout(req, options); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -372,7 +365,7 @@ cb_Backend_analytics_index_create(VALUE self, VALUE fields, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); Check_Type(dataset_name, T_STRING); @@ -396,11 +389,10 @@ cb_Backend_analytics_index_create(VALUE self, cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.ignore_if_exists, options, "ignore_if_exists"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { if (resp.errors.empty()) { @@ -433,7 +425,7 @@ cb_Backend_analytics_index_create(VALUE self, VALUE cb_Backend_analytics_index_drop(VALUE self, VALUE index_name, VALUE dataset_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); Check_Type(dataset_name, T_STRING); @@ -445,11 +437,10 @@ cb_Backend_analytics_index_drop(VALUE self, VALUE index_name, VALUE dataset_name req.dataset_name = cb_string_new(dataset_name); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.ignore_if_does_not_exist, options, "ignore_if_does_not_exist"); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { if (resp.errors.empty()) { @@ -482,7 +473,7 @@ cb_Backend_analytics_index_drop(VALUE self, VALUE index_name, VALUE dataset_name VALUE cb_Backend_analytics_link_connect(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_link_connect_request req{}; @@ -490,11 +481,10 @@ cb_Backend_analytics_link_connect(VALUE self, VALUE options) cb_extract_option_string(req.link_name, options, "link_name"); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); cb_extract_option_bool(req.force, options, "force"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -525,18 +515,17 @@ cb_Backend_analytics_link_connect(VALUE self, VALUE options) VALUE cb_Backend_analytics_link_disconnect(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::analytics_link_disconnect_request req{}; cb_extract_timeout(req, options); cb_extract_option_string(req.link_name, options, "link_name"); cb_extract_option_string(req.dataverse_name, options, "dataverse_name"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { if (resp.errors.empty()) { @@ -616,7 +605,7 @@ cb_fill_link(core::management::analytics::s3_external_link& dst, VALUE src) VALUE cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); if (!NIL_P(options)) { Check_Type(options, T_HASH); @@ -632,11 +621,10 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -663,11 +651,10 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -695,11 +682,10 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -733,7 +719,7 @@ cb_Backend_analytics_link_create(VALUE self, VALUE link, VALUE options) VALUE cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); if (!NIL_P(options)) { Check_Type(options, T_HASH); @@ -750,11 +736,10 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -782,11 +767,10 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -814,11 +798,10 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) cb_extract_timeout(req, options); cb_fill_link(req.link, link); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -852,7 +835,7 @@ cb_Backend_analytics_link_replace(VALUE self, VALUE link, VALUE options) VALUE cb_Backend_analytics_link_drop(VALUE self, VALUE link, VALUE dataverse, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(link, T_STRING); Check_Type(dataverse, T_STRING); @@ -867,11 +850,10 @@ cb_Backend_analytics_link_drop(VALUE self, VALUE link, VALUE dataverse, VALUE op req.link_name = cb_string_new(link); req.dataverse_name = cb_string_new(dataverse); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -903,7 +885,7 @@ cb_Backend_analytics_link_drop(VALUE self, VALUE link, VALUE dataverse, VALUE op VALUE cb_Backend_analytics_link_get_all(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); if (!NIL_P(options)) { Check_Type(options, T_HASH); @@ -917,11 +899,10 @@ cb_Backend_analytics_link_get_all(VALUE self, VALUE options) cb_extract_option_string(req.link_name, options, "link_name"); cb_extract_option_string(req.dataverse_name, options, "dataverse"); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); @@ -1050,7 +1031,7 @@ cb_for_each_named_param_analytics(VALUE key, VALUE value, VALUE arg) VALUE cb_Backend_document_analytics(VALUE self, VALUE statement, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(statement, T_STRING); if (!NIL_P(options)) { @@ -1122,10 +1103,10 @@ cb_Backend_document_analytics(VALUE self, VALUE statement, VALUE options) rb_hash_foreach(raw_params, cb_for_each_named_param_analytics, reinterpret_cast(&req)); } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { diff --git a/ext/rcb_backend.cxx b/ext/rcb_backend.cxx index 68188112..c0432c07 100644 --- a/ext/rcb_backend.cxx +++ b/ext/rcb_backend.cxx @@ -15,6 +15,8 @@ * limitations under the License. */ +#include + #include #include #include @@ -24,10 +26,10 @@ #include #include -#include #include +#include "couchbase/ip_protocol.hxx" #include "rcb_backend.hxx" #include "rcb_exceptions.hxx" #include "rcb_logger.hxx" @@ -39,69 +41,19 @@ namespace couchbase::ruby namespace { struct cb_backend_data { - std::unique_ptr ctx; - std::shared_ptr cluster; - std::thread worker; + std::unique_ptr instance{ nullptr }; }; -void -cb_extract_option_milliseconds(std::chrono::milliseconds& field, VALUE options, const char* name) -{ - if (!NIL_P(options) && TYPE(options) == T_HASH) { - VALUE val = rb_hash_aref(options, rb_id2sym(rb_intern(name))); - if (NIL_P(val)) { - return; - } - switch (TYPE(val)) { - case T_FIXNUM: - field = std::chrono::milliseconds(FIX2ULONG(val)); - break; - case T_BIGNUM: - field = std::chrono::milliseconds(NUM2ULL(val)); - break; - default: - throw ruby_exception( - rb_eArgError, - rb_sprintf( - "%s must be a Integer representing milliseconds, but given %+" PRIsVALUE, name, val)); - } - } -} - -void -cb_extract_dns_config(core::io::dns::dns_config& config, VALUE options) -{ - if (!NIL_P(options) && TYPE(options) == T_HASH) { - return; - } - - auto timeout{ core::timeout_defaults::dns_srv_timeout }; - cb_extract_option_milliseconds(timeout, options, "dns_srv_timeout"); - - std::string nameserver{ core::io::dns::dns_config::default_nameserver }; - cb_extract_option_string(nameserver, options, "dns_srv_nameserver"); - - std::uint16_t port{ core::io::dns::dns_config::default_port }; - cb_extract_option_number(port, options, "dns_srv_port"); - - config = core::io::dns::dns_config(nameserver, port, timeout); -} - void cb_backend_close(cb_backend_data* backend) { - if (backend->cluster) { + if (auto instance = std::move(backend->instance); instance) { auto promise = std::make_shared>(); auto f = promise->get_future(); - backend->cluster->close([promise]() { + instance->close([promise = std::move(promise)]() mutable { promise->set_value(); }); f.wait(); - if (backend->worker.joinable()) { - backend->worker.join(); - } - backend->cluster.reset(); - backend->ctx.reset(nullptr); } } @@ -123,7 +75,7 @@ size_t cb_Backend_memsize(const void* ptr) { const auto* backend = static_cast(ptr); - return sizeof(*backend) + sizeof(*backend->cluster); + return sizeof(*backend); } const rb_data_type_t cb_backend_type{ @@ -148,199 +100,348 @@ cb_Backend_allocate(VALUE klass) { cb_backend_data* backend = nullptr; VALUE obj = TypedData_Make_Struct(klass, cb_backend_data, &cb_backend_type, backend); - backend->ctx = std::make_unique(); - backend->cluster = std::make_shared(*backend->ctx); - backend->worker = std::thread([backend]() { - backend->ctx->run(); - }); + backend->instance = nullptr; return obj; } -VALUE -cb_Backend_open(VALUE self, VALUE connection_string, VALUE credentials, VALUE options) +auto +construct_cluster_options(VALUE credentials, bool tls_enabled) -> couchbase::cluster_options { - const auto& cluster = cb_backend_to_cluster(self); + cb_check_type(credentials, T_HASH); - Check_Type(connection_string, T_STRING); - Check_Type(credentials, T_HASH); + static const auto sym_certificate_path{ rb_id2sym(rb_intern("certificate_path")) }; + static const auto sym_key_path{ rb_id2sym(rb_intern("key_path")) }; - VALUE username = Qnil; - VALUE password = Qnil; + const VALUE certificate_path = rb_hash_aref(credentials, sym_certificate_path); + const VALUE key_path = rb_hash_aref(credentials, sym_key_path); - VALUE certificate_path = rb_hash_aref(credentials, rb_id2sym(rb_intern("certificate_path"))); - VALUE key_path = rb_hash_aref(credentials, rb_id2sym(rb_intern("key_path"))); if (NIL_P(certificate_path) || NIL_P(key_path)) { - username = rb_hash_aref(credentials, rb_id2sym(rb_intern("username"))); - password = rb_hash_aref(credentials, rb_id2sym(rb_intern("password"))); - Check_Type(username, T_STRING); - Check_Type(password, T_STRING); - } else { - Check_Type(certificate_path, T_STRING); - Check_Type(key_path, T_STRING); + static const auto sym_username = rb_id2sym(rb_intern("username")); + static const auto sym_password = rb_id2sym(rb_intern("password")); + + const VALUE username = rb_hash_aref(credentials, sym_username); + const VALUE password = rb_hash_aref(credentials, sym_password); + + cb_check_type(username, T_STRING); + cb_check_type(password, T_STRING); + + return cluster_options{ + password_authenticator{ + cb_string_new(username), + cb_string_new(password), + }, + }; } - if (!NIL_P(options)) { - Check_Type(options, T_HASH); + + if (!tls_enabled) { + throw ruby_exception( + exc_invalid_argument(), + "Certificate authenticator requires TLS connection, check the connection string"); } - try { - auto input = cb_string_new(connection_string); - auto connstr = core::utils::parse_connection_string(input); - if (connstr.error) { + cb_check_type(certificate_path, T_STRING); + cb_check_type(key_path, T_STRING); + + return cluster_options{ + certificate_authenticator{ + cb_string_new(certificate_path), + cb_string_new(key_path), + }, + }; +} + +auto +initialize_cluster_options(const core::utils::connection_string& connstr, + VALUE credentials, + VALUE options) -> couchbase::cluster_options +{ + auto cluster_options = construct_cluster_options(credentials, connstr.tls); + cluster_options.behavior().append_to_user_agent(user_agent_extra()); + + if (NIL_P(options)) { + return cluster_options; + } + + cb_check_type(options, T_HASH); + + static const auto sym_dns_srv_timeout = rb_id2sym(rb_intern("dns_srv_timeout")); + if (auto param = options::get_milliseconds(options, sym_dns_srv_timeout); param) { + cluster_options.dns().timeout(param.value()); + } + static const auto sym_dns_srv_nameserver = rb_id2sym(rb_intern("dns_srv_nameserver")); + if (auto param = options::get_string(options, sym_dns_srv_nameserver); param) { + static const auto sym_dns_srv_port = rb_id2sym(rb_intern("dns_srv_port")); + if (auto port = options::get_uint16_t(options, sym_dns_srv_port); port) { + cluster_options.dns().nameserver(param.value(), port.value()); + } else { + cluster_options.dns().nameserver(param.value()); + } + } + + static const auto sym_trust_certificate = rb_id2sym(rb_intern("trust_certificate")); + if (auto param = options::get_string(options, sym_trust_certificate); param) { + cluster_options.security().trust_certificate(param.value()); + } + + static const auto sym_trust_certificate_value = rb_id2sym(rb_intern("trust_certificate_value")); + if (auto param = options::get_string(options, sym_trust_certificate_value); param) { + cluster_options.security().trust_certificate_value(param.value()); + } + + static const auto sym_tls_verify = rb_id2sym(rb_intern("tls_verify")); + if (auto mode = options::get_symbol(options, sym_tls_verify); mode) { + static const auto sym_none = rb_id2sym(rb_intern("none")); + static const auto sym_peer = rb_id2sym(rb_intern("peer")); + if (*mode == sym_none) { + cluster_options.security().tls_verify(tls_verify_mode::none); + } else if (*mode == sym_peer) { + cluster_options.security().tls_verify(tls_verify_mode::peer); + } else { throw ruby_exception( exc_invalid_argument(), - fmt::format(R"(Failed to parse connection string "{}": {})", input, connstr.error.value())); + rb_sprintf("Failed to select verification mode for TLS: %+" PRIsVALUE, mode.value())); } - core::cluster_credentials auth{}; - if (NIL_P(certificate_path) || NIL_P(key_path)) { - auth.username = cb_string_new(username); - auth.password = cb_string_new(password); - if (!NIL_P(options)) { - VALUE allowed_mechanisms = - rb_hash_aref(options, rb_id2sym(rb_intern("allowed_sasl_mechanisms"))); - if (!NIL_P(allowed_mechanisms)) { - cb_check_type(allowed_mechanisms, T_ARRAY); - auto allowed_mechanisms_size = static_cast(RARRAY_LEN(allowed_mechanisms)); - if (allowed_mechanisms_size < 1) { - throw ruby_exception(exc_invalid_argument(), - "allowed_sasl_mechanisms list cannot be empty"); - } - std::vector mechanisms{}; - mechanisms.reserve(allowed_mechanisms_size); - for (std::size_t i = 0; i < allowed_mechanisms_size; ++i) { - VALUE mechanism = rb_ary_entry(allowed_mechanisms, static_cast(i)); - if (mechanism == rb_id2sym(rb_intern("scram_sha512"))) { - mechanisms.emplace_back("SCRAM-SHA512"); - } else if (mechanism == rb_id2sym(rb_intern("scram_sha256"))) { - mechanisms.emplace_back("SCRAM-SHA256"); - } else if (mechanism == rb_id2sym(rb_intern("scram_sha1"))) { - mechanisms.emplace_back("SCRAM-SHA1"); - } else if (mechanism == rb_id2sym(rb_intern("plain"))) { - mechanisms.emplace_back("PLAIN"); - } - } - auth.allowed_sasl_mechanisms.emplace(mechanisms); - } - } + } + + static const auto sym_network = rb_id2sym(rb_intern("network")); + if (auto param = options::get_string(options, sym_network); param) { + cluster_options.network().preferred_network(param.value()); + cluster_options.behavior().network(param.value()); + } + + static const auto sym_use_ip_protocol = rb_id2sym(rb_intern("use_ip_protocol")); + if (auto proto = options::get_symbol(options, sym_use_ip_protocol); proto) { + static const auto sym_any = rb_id2sym(rb_intern("any")); + static const auto sym_force_ipv4 = rb_id2sym(rb_intern("force_ipv4")); + static const auto sym_force_ipv6 = rb_id2sym(rb_intern("force_ipv6")); + if (*proto == sym_any) { + cluster_options.network().force_ip_protocol(ip_protocol::any); + } else if (*proto == sym_force_ipv4) { + cluster_options.network().force_ip_protocol(ip_protocol::force_ipv4); + } else if (*proto == sym_force_ipv6) { + cluster_options.network().force_ip_protocol(ip_protocol::force_ipv6); } else { - if (!connstr.tls) { - throw ruby_exception(exc_invalid_argument(), - "Certificate authenticator requires TLS connection, check the schema " - "of the connection string"); - } - auth.certificate_path = cb_string_new(certificate_path); - auth.key_path = cb_string_new(key_path); - } - core::origin origin(auth, connstr); - - cb_extract_option_bool(origin.options().enable_tracing, options, "enable_tracing"); - if (origin.options().enable_tracing) { - cb_extract_option_milliseconds( - origin.options().tracing_options.orphaned_emit_interval, options, "orphaned_emit_interval"); - cb_extract_option_number( - origin.options().tracing_options.orphaned_sample_size, options, "orphaned_sample_size"); - cb_extract_option_milliseconds(origin.options().tracing_options.threshold_emit_interval, - options, - "threshold_emit_interval"); - cb_extract_option_number( - origin.options().tracing_options.threshold_sample_size, options, "threshold_sample_size"); - cb_extract_option_milliseconds( - origin.options().tracing_options.key_value_threshold, options, "key_value_threshold"); - cb_extract_option_milliseconds( - origin.options().tracing_options.query_threshold, options, "query_threshold"); - cb_extract_option_milliseconds( - origin.options().tracing_options.view_threshold, options, "view_threshold"); - cb_extract_option_milliseconds( - origin.options().tracing_options.search_threshold, options, "search_threshold"); - cb_extract_option_milliseconds( - origin.options().tracing_options.analytics_threshold, options, "analytics_threshold"); - cb_extract_option_milliseconds( - origin.options().tracing_options.management_threshold, options, "management_threshold"); - } - cb_extract_option_bool(origin.options().enable_metrics, options, "enable_metrics"); - if (origin.options().enable_metrics) { - cb_extract_option_milliseconds( - origin.options().metrics_options.emit_interval, options, "metrics_emit_interval"); - } - cb_extract_option_milliseconds( - origin.options().bootstrap_timeout, options, "bootstrap_timeout"); - cb_extract_option_milliseconds(origin.options().resolve_timeout, options, "resolve_timeout"); - cb_extract_option_milliseconds(origin.options().connect_timeout, options, "connect_timeout"); - cb_extract_option_milliseconds( - origin.options().key_value_timeout, options, "key_value_timeout"); - cb_extract_option_milliseconds( - origin.options().key_value_durable_timeout, options, "key_value_durable_timeout"); - cb_extract_option_milliseconds(origin.options().view_timeout, options, "view_timeout"); - cb_extract_option_milliseconds(origin.options().query_timeout, options, "query_timeout"); - cb_extract_option_milliseconds( - origin.options().analytics_timeout, options, "analytics_timeout"); - cb_extract_option_milliseconds(origin.options().search_timeout, options, "search_timeout"); - cb_extract_option_milliseconds( - origin.options().management_timeout, options, "management_timeout"); - cb_extract_option_milliseconds( - origin.options().tcp_keep_alive_interval, options, "tcp_keep_alive_interval"); - cb_extract_option_milliseconds( - origin.options().config_poll_interval, options, "config_poll_interval"); - cb_extract_option_milliseconds( - origin.options().config_poll_floor, options, "config_poll_floor"); - cb_extract_option_milliseconds( - origin.options().config_idle_redial_timeout, options, "config_idle_redial_timeout"); - cb_extract_option_milliseconds( - origin.options().idle_http_connection_timeout, options, "idle_http_connection_timeout"); - - cb_extract_dns_config(origin.options().dns_config, options); - - cb_extract_option_number( - origin.options().max_http_connections, options, "max_http_connections"); - - cb_extract_option_bool(origin.options().enable_tls, options, "enable_tls"); - cb_extract_option_bool( - origin.options().enable_mutation_tokens, options, "enable_mutation_tokens"); - cb_extract_option_bool( - origin.options().enable_tcp_keep_alive, options, "enable_tcp_keep_alive"); - cb_extract_option_bool(origin.options().enable_dns_srv, options, "enable_dns_srv"); - cb_extract_option_bool(origin.options().show_queries, options, "show_queries"); - cb_extract_option_bool( - origin.options().enable_unordered_execution, options, "enable_unordered_execution"); - cb_extract_option_bool( - origin.options().enable_clustermap_notification, options, "enable_clustermap_notification"); - cb_extract_option_bool(origin.options().enable_compression, options, "enable_compression"); - - cb_extract_option_string(origin.options().trust_certificate, options, "trust_certificate"); - cb_extract_option_string(origin.options().network, options, "network"); - - VALUE proto = Qnil; - cb_extract_option_symbol(proto, options, "use_ip_protocol"); - if (proto == rb_id2sym(rb_intern("any"))) { - origin.options().use_ip_protocol = core::io::ip_protocol::any; - } else if (proto == rb_id2sym(rb_intern("force_ipv4"))) { - origin.options().use_ip_protocol = core::io::ip_protocol::force_ipv4; - } else if (proto == rb_id2sym(rb_intern("force_ipv6"))) { - origin.options().use_ip_protocol = core::io::ip_protocol::force_ipv6; - } else if (!NIL_P(proto)) { - throw ruby_exception(exc_invalid_argument(), "Failed to detect preferred IP protocol"); + throw ruby_exception( + exc_invalid_argument(), + rb_sprintf("Failed to setect preferred IP protocol: %+" PRIsVALUE, proto.value())); } + } + + static const auto sym_enable_mutation_tokens = rb_id2sym(rb_intern("enable_mutation_tokens")); + if (auto param = options::get_bool(options, sym_enable_mutation_tokens); param) { + cluster_options.behavior().enable_mutation_tokens(param.value()); + } + + static const auto sym_show_queries = rb_id2sym(rb_intern("show_queries")); + if (auto param = options::get_bool(options, sym_show_queries); param) { + cluster_options.behavior().show_queries(param.value()); + } + + static const auto sym_enable_tcp_keep_alive = rb_id2sym(rb_intern("enable_tcp_keep_alive")); + if (auto param = options::get_bool(options, sym_enable_tcp_keep_alive); param) { + cluster_options.network().enable_tcp_keep_alive(param.value()); + } + + static const auto sym_enable_unordered_execution = + rb_id2sym(rb_intern("enable_unordered_execution")); + if (auto param = options::get_bool(options, sym_enable_unordered_execution); param) { + cluster_options.behavior().enable_unordered_execution(param.value()); + } + + static const auto sym_enable_compression = rb_id2sym(rb_intern("enable_compression")); + if (auto param = options::get_bool(options, sym_enable_compression); param) { + cluster_options.compression().enabled(param.value()); + } + + static const auto sym_enable_clustermap_notification = + rb_id2sym(rb_intern("enable_clustermap_notification")); + if (auto param = options::get_bool(options, sym_enable_clustermap_notification); param) { + cluster_options.behavior().enable_clustermap_notification(param.value()); + } + + static const auto sym_bootstrap_timeout = rb_id2sym(rb_intern("bootstrap_timeout")); + if (auto param = options::get_milliseconds(options, sym_bootstrap_timeout); param) { + cluster_options.timeouts().bootstrap_timeout(param.value()); + } - VALUE mode = Qnil; - cb_extract_option_symbol(mode, options, "tls_verify"); - if (mode == rb_id2sym(rb_intern("none"))) { - origin.options().tls_verify = core::tls_verify_mode::none; - } else if (mode == rb_id2sym(rb_intern("peer"))) { - origin.options().tls_verify = core::tls_verify_mode::peer; - } else if (!NIL_P(mode)) { - throw ruby_exception(exc_invalid_argument(), "Failed to select verification mode for TLS"); + static const auto sym_resolve_timeout = rb_id2sym(rb_intern("resolve_timeout")); + if (auto param = options::get_milliseconds(options, sym_resolve_timeout); param) { + cluster_options.timeouts().resolve_timeout(param.value()); + } + + static const auto sym_connect_timeout = rb_id2sym(rb_intern("connect_timeout")); + if (auto param = options::get_milliseconds(options, sym_connect_timeout); param) { + cluster_options.timeouts().connect_timeout(param.value()); + } + + static const auto sym_key_value_timeout = rb_id2sym(rb_intern("key_value_timeout")); + if (auto param = options::get_milliseconds(options, sym_key_value_timeout); param) { + cluster_options.timeouts().key_value_timeout(param.value()); + } + + static const auto sym_key_value_durable_timeout = + rb_id2sym(rb_intern("key_value_durable_timeout")); + if (auto param = options::get_milliseconds(options, sym_key_value_durable_timeout); param) { + cluster_options.timeouts().key_value_durable_timeout(param.value()); + } + + static const auto sym_view_timeout = rb_id2sym(rb_intern("view_timeout")); + if (auto param = options::get_milliseconds(options, sym_view_timeout); param) { + cluster_options.timeouts().view_timeout(param.value()); + } + + static const auto sym_query_timeout = rb_id2sym(rb_intern("query_timeout")); + if (auto param = options::get_milliseconds(options, sym_query_timeout); param) { + cluster_options.timeouts().query_timeout(param.value()); + } + + static const auto sym_analytics_timeout = rb_id2sym(rb_intern("analytics_timeout")); + if (auto param = options::get_milliseconds(options, sym_analytics_timeout); param) { + cluster_options.timeouts().analytics_timeout(param.value()); + } + + static const auto sym_search_timeout = rb_id2sym(rb_intern("search_timeout")); + if (auto param = options::get_milliseconds(options, sym_search_timeout); param) { + cluster_options.timeouts().search_timeout(param.value()); + } + + static const auto sym_management_timeout = rb_id2sym(rb_intern("management_timeout")); + if (auto param = options::get_milliseconds(options, sym_management_timeout); param) { + cluster_options.timeouts().management_timeout(param.value()); + } + + static const auto sym_tcp_keep_alive_interval = rb_id2sym(rb_intern("tcp_keep_alive_interval")); + if (auto param = options::get_milliseconds(options, sym_tcp_keep_alive_interval); param) { + cluster_options.network().tcp_keep_alive_interval(param.value()); + } + + static const auto sym_config_poll_interval = rb_id2sym(rb_intern("config_poll_interval")); + if (auto param = options::get_milliseconds(options, sym_config_poll_interval); param) { + cluster_options.network().config_poll_interval(param.value()); + } + + static const auto sym_idle_http_connection_timeout = + rb_id2sym(rb_intern("idle_http_connection_timeout")); + if (auto param = options::get_milliseconds(options, sym_idle_http_connection_timeout); param) { + cluster_options.network().idle_http_connection_timeout(param.value()); + } + + static const auto sym_max_http_connections = rb_id2sym(rb_intern("max_http_connections")); + if (auto param = options::get_size_t(options, sym_max_http_connections); param) { + cluster_options.network().max_http_connections(param.value()); + } + + static const auto sym_enable_tracing = rb_id2sym(rb_intern("enable_tracing")); + if (auto param = options::get_bool(options, sym_enable_tracing); param) { + cluster_options.tracing().enable(param.value()); + } + static const auto sym_orphaned_emit_interval = rb_id2sym(rb_intern("orphaned_emit_interval")); + if (auto param = options::get_milliseconds(options, sym_orphaned_emit_interval); param) { + cluster_options.tracing().orphaned_emit_interval(param.value()); + } + + static const auto sym_orphaned_sample_size = rb_id2sym(rb_intern("orphaned_sample_size")); + if (auto param = options::get_size_t(options, sym_orphaned_sample_size); param) { + cluster_options.tracing().orphaned_sample_size(param.value()); + } + + static const auto sym_threshold_emit_interval = rb_id2sym(rb_intern("threshold_emit_interval")); + if (auto param = options::get_milliseconds(options, sym_threshold_emit_interval); param) { + cluster_options.tracing().threshold_emit_interval(param.value()); + } + + static const auto sym_threshold_sample_size = rb_id2sym(rb_intern("threshold_sample_size")); + if (auto param = options::get_size_t(options, sym_threshold_sample_size); param) { + cluster_options.tracing().threshold_sample_size(param.value()); + } + + static const auto sym_key_value_threshold = rb_id2sym(rb_intern("key_value_threshold")); + if (auto param = options::get_milliseconds(options, sym_key_value_threshold); param) { + cluster_options.tracing().key_value_threshold(param.value()); + } + + static const auto sym_query_threshold = rb_id2sym(rb_intern("query_threshold")); + if (auto param = options::get_milliseconds(options, sym_query_threshold); param) { + cluster_options.tracing().query_threshold(param.value()); + } + + static const auto sym_view_threshold = rb_id2sym(rb_intern("view_threshold")); + if (auto param = options::get_milliseconds(options, sym_view_threshold); param) { + cluster_options.tracing().view_threshold(param.value()); + } + + static const auto sym_search_threshold = rb_id2sym(rb_intern("search_threshold")); + if (auto param = options::get_milliseconds(options, sym_search_threshold); param) { + cluster_options.tracing().search_threshold(param.value()); + } + + static const auto sym_analytics_threshold = rb_id2sym(rb_intern("analytics_threshold")); + if (auto param = options::get_milliseconds(options, sym_analytics_threshold); param) { + cluster_options.tracing().analytics_threshold(param.value()); + } + + static const auto sym_management_threshold = rb_id2sym(rb_intern("management_threshold")); + if (auto param = options::get_milliseconds(options, sym_management_threshold); param) { + cluster_options.tracing().management_threshold(param.value()); + } + + static const auto sym_enable_metrics = rb_id2sym(rb_intern("enable_metrics")); + if (auto param = options::get_bool(options, sym_enable_metrics); param) { + cluster_options.metrics().enable(param.value()); + } + + static const auto sym_metrics_emit_interval = rb_id2sym(rb_intern("metrics_emit_interval")); + if (auto param = options::get_milliseconds(options, sym_metrics_emit_interval); param) { + cluster_options.metrics().emit_interval(param.value()); + } + + return cluster_options; +} + +VALUE +cb_Backend_open(VALUE self, VALUE connstr, VALUE credentials, VALUE options) +{ + cb_backend_data* backend = nullptr; + TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend); + + if (backend->instance != nullptr) { + CB_LOG_TRACE("Trying to open the same backend twice: {}, instance={}", + rb_sprintf("%+" PRIsVALUE ", connection_string=%+" PRIsVALUE, self, connstr), + static_cast(backend->instance.get())); + return Qnil; + } + + Check_Type(connstr, T_STRING); + + try { + auto connection_string = cb_string_new(connstr); + auto parsed_connection_string = core::utils::parse_connection_string(connection_string); + if (parsed_connection_string.error) { + throw ruby_exception(exc_invalid_argument(), + fmt::format(R"(Failed to parse connection string "{}": {})", + connection_string, + parsed_connection_string.error.value())); } - origin.options().user_agent_extra = user_agent_extra(); + auto cluster_options = + initialize_cluster_options(parsed_connection_string, credentials, options); - auto promise = std::make_shared>(); + auto promise = + std::make_shared>>(); auto f = promise->get_future(); - cluster->open(origin, [promise](std::error_code ec) { - promise->set_value(ec); - }); - if (auto ec = cb_wait_for_future(f)) { - cb_throw_error_code(ec, - fmt::format("unable open cluster at {}", origin.next_address().first)); + couchbase::cluster::connect( + connection_string, cluster_options, [promise](auto&& error, auto&& cluster) { + promise->set_value({ + std::forward(error), + std::forward(cluster), + }); + }); + auto [error, cluster] = cb_wait_for_future(f); + if (error) { + cb_throw_error( + error, fmt::format("failed to connect to the Couchbase Server \"{}\"", connection_string)); } + backend->instance = std::make_unique(std::move(cluster)); } catch (const std::system_error& se) { rb_exc_raise(cb_map_error_code( se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false)); @@ -363,7 +464,7 @@ cb_Backend_close(VALUE self) VALUE cb_Backend_open_bucket(VALUE self, VALUE bucket, VALUE wait_until_ready) { - const auto& cluster = cb_backend_to_cluster(self); + const auto& cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); bool wait = RTEST(wait_until_ready); @@ -374,14 +475,14 @@ cb_Backend_open_bucket(VALUE self, VALUE bucket, VALUE wait_until_ready) if (wait) { auto promise = std::make_shared>(); auto f = promise->get_future(); - cluster->open_bucket(name, [promise](std::error_code ec) { + cluster.open_bucket(name, [promise](std::error_code ec) { promise->set_value(ec); }); if (auto ec = cb_wait_for_future(f)) { cb_throw_error_code(ec, fmt::format("unable open bucket \"{}\"", name)); } } else { - cluster->open_bucket(name, [name](std::error_code ec) { + cluster.open_bucket(name, [name](std::error_code ec) { CB_LOG_WARNING("unable open bucket \"{}\": {}", name, ec.message()); }); } @@ -408,15 +509,22 @@ init_backend(VALUE mCouchbase) } auto -cb_backend_to_cluster(VALUE self) -> const std::shared_ptr& +cb_backend_to_public_api_cluster(VALUE self) -> couchbase::cluster { const cb_backend_data* backend = nullptr; TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend); - if (!backend->cluster) { + if (backend->instance == nullptr) { rb_raise(exc_cluster_closed(), "Cluster has been closed already"); } - return backend->cluster; + + return *backend->instance; +} + +auto +cb_backend_to_core_api_cluster(VALUE self) -> core::cluster +{ + return core::get_core_cluster(cb_backend_to_public_api_cluster(self)); } } // namespace couchbase::ruby diff --git a/ext/rcb_backend.hxx b/ext/rcb_backend.hxx index a5888f3f..64bc9b7c 100644 --- a/ext/rcb_backend.hxx +++ b/ext/rcb_backend.hxx @@ -22,15 +22,22 @@ #include +namespace couchbase +{ +class cluster; namespace core { class cluster; } // namespace core +} // namespace couchbase namespace couchbase::ruby { auto -cb_backend_to_cluster(VALUE self) -> const std::shared_ptr&; +cb_backend_to_public_api_cluster(VALUE self) -> couchbase::cluster; + +auto +cb_backend_to_core_api_cluster(VALUE self) -> core::cluster; VALUE init_backend(VALUE mCouchbase); diff --git a/ext/rcb_buckets.cxx b/ext/rcb_buckets.cxx index 4c82246f..cd908179 100644 --- a/ext/rcb_buckets.cxx +++ b/ext/rcb_buckets.cxx @@ -264,7 +264,7 @@ cb_generate_bucket_settings(VALUE bucket, VALUE cb_Backend_bucket_create(VALUE self, VALUE bucket_settings, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_settings, T_HASH); if (!NIL_P(options)) { @@ -275,11 +275,10 @@ cb_Backend_bucket_create(VALUE self, VALUE bucket_settings, VALUE options) core::operations::management::bucket_create_request req{}; cb_extract_timeout(req, options); cb_generate_bucket_settings(bucket_settings, req.bucket, true); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](core::operations::management::bucket_create_response&& resp) { - promise->set_value(std::move(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { cb_throw_error(resp.ctx, @@ -301,7 +300,7 @@ cb_Backend_bucket_create(VALUE self, VALUE bucket_settings, VALUE options) VALUE cb_Backend_bucket_update(VALUE self, VALUE bucket_settings, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_settings, T_HASH); if (!NIL_P(options)) { @@ -311,11 +310,10 @@ cb_Backend_bucket_update(VALUE self, VALUE bucket_settings, VALUE options) core::operations::management::bucket_update_request req{}; cb_extract_timeout(req, options); cb_generate_bucket_settings(bucket_settings, req.bucket, false); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](core::operations::management::bucket_update_response&& resp) { - promise->set_value(std::move(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { cb_throw_error(resp.ctx, @@ -336,7 +334,7 @@ cb_Backend_bucket_update(VALUE self, VALUE bucket_settings, VALUE options) VALUE cb_Backend_bucket_drop(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -346,11 +344,10 @@ cb_Backend_bucket_drop(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::bucket_drop_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](core::operations::management::bucket_drop_response&& resp) { - promise->set_value(std::move(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { cb_throw_error(resp.ctx, @@ -369,7 +366,7 @@ cb_Backend_bucket_drop(VALUE self, VALUE bucket_name, VALUE options) VALUE cb_Backend_bucket_flush(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -379,11 +376,10 @@ cb_Backend_bucket_flush(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::bucket_flush_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](core::operations::management::bucket_flush_response&& resp) { - promise->set_value(std::move(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { cb_throw_error(resp.ctx, @@ -542,7 +538,7 @@ cb_extract_bucket_settings(const core::management::cluster::bucket_settings& ent VALUE cb_Backend_bucket_get_all(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); if (!NIL_P(options)) { Check_Type(options, T_HASH); @@ -551,11 +547,10 @@ cb_Backend_bucket_get_all(VALUE self, VALUE options) try { core::operations::management::bucket_get_all_request req{}; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](core::operations::management::bucket_get_all_response&& resp) { - promise->set_value(std::move(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -582,7 +577,7 @@ cb_Backend_bucket_get_all(VALUE self, VALUE options) VALUE cb_Backend_bucket_get(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -592,11 +587,10 @@ cb_Backend_bucket_get(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::bucket_get_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](core::operations::management::bucket_get_response&& resp) { - promise->set_value(std::move(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { diff --git a/ext/rcb_collections.cxx b/ext/rcb_collections.cxx index 6e07a3da..dd494921 100644 --- a/ext/rcb_collections.cxx +++ b/ext/rcb_collections.cxx @@ -40,7 +40,7 @@ namespace VALUE cb_Backend_scope_get_all(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -50,11 +50,10 @@ cb_Backend_scope_get_all(VALUE self, VALUE bucket_name, VALUE options) try { core::operations::management::scope_get_all_request req{ cb_string_new(bucket_name) }; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -100,7 +99,7 @@ cb_Backend_scope_get_all(VALUE self, VALUE bucket_name, VALUE options) VALUE cb_Backend_scope_create(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -112,11 +111,10 @@ cb_Backend_scope_create(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE o core::operations::management::scope_create_request req{ cb_string_new(bucket_name), cb_string_new(scope_name) }; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); @@ -139,7 +137,7 @@ cb_Backend_scope_create(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE o VALUE cb_Backend_scope_drop(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -151,11 +149,10 @@ cb_Backend_scope_drop(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE opt core::operations::management::scope_drop_request req{ cb_string_new(bucket_name), cb_string_new(scope_name) }; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -182,7 +179,7 @@ cb_Backend_collection_create(VALUE self, VALUE settings, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -224,11 +221,10 @@ cb_Backend_collection_create(VALUE self, } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -256,7 +252,7 @@ cb_Backend_collection_update(VALUE self, VALUE settings, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -298,11 +294,10 @@ cb_Backend_collection_update(VALUE self, } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -329,7 +324,7 @@ cb_Backend_collection_drop(VALUE self, VALUE collection_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -344,11 +339,10 @@ cb_Backend_collection_drop(VALUE self, cb_string_new(collection_name) }; cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { diff --git a/ext/rcb_crud.cxx b/ext/rcb_crud.cxx index 3d2cfbb5..d6891859 100644 --- a/ext/rcb_crud.cxx +++ b/ext/rcb_crud.cxx @@ -35,7 +35,6 @@ #include #include -#include #include @@ -78,7 +77,7 @@ cb_Backend_document_get(VALUE self, VALUE id, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -95,10 +94,10 @@ cb_Backend_document_get(VALUE self, core::operations::get_request req{ doc_id }; cb_extract_timeout(req, options); - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -127,7 +126,7 @@ cb_Backend_document_get_any_replica(VALUE self, VALUE id, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -138,8 +137,7 @@ cb_Backend_document_get_any_replica(VALUE self, couchbase::get_any_replica_options opts; set_timeout(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .get_any_replica(cb_string_new(id), opts); @@ -171,7 +169,7 @@ cb_Backend_document_get_all_replicas(VALUE self, VALUE id, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -182,8 +180,7 @@ cb_Backend_document_get_all_replicas(VALUE self, couchbase::get_all_replicas_options opts; set_timeout(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .get_all_replicas(cb_string_new(id), opts); @@ -219,7 +216,7 @@ cb_Backend_document_get_projected(VALUE self, VALUE id, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -256,10 +253,10 @@ cb_Backend_document_get_projected(VALUE self, } } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -292,7 +289,7 @@ cb_Backend_document_get_and_lock(VALUE self, VALUE lock_time, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -315,10 +312,10 @@ cb_Backend_document_get_and_lock(VALUE self, cb_extract_timeout(req, options); req.lock_time = NUM2UINT(lock_time); - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -348,7 +345,7 @@ cb_Backend_document_get_and_touch(VALUE self, VALUE expiry, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -371,10 +368,10 @@ cb_Backend_document_get_and_touch(VALUE self, auto [type, duration] = unpack_expiry(expiry, false); req.expiry = static_cast(duration.count()); - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -404,7 +401,7 @@ cb_Backend_document_touch(VALUE self, VALUE expiry, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -427,10 +424,10 @@ cb_Backend_document_touch(VALUE self, auto [type, duration] = unpack_expiry(expiry, false); req.expiry = static_cast(duration.count()); - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -457,7 +454,7 @@ cb_Backend_document_exists(VALUE self, VALUE id, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -478,10 +475,10 @@ cb_Backend_document_exists(VALUE self, core::operations::exists_request req{ doc_id }; cb_extract_timeout(req, options); - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec() && resp.ctx.ec() != couchbase::errc::key_value::document_not_found) { @@ -515,7 +512,7 @@ cb_Backend_document_unlock(VALUE self, VALUE cas, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(collection, T_STRING); @@ -537,10 +534,10 @@ cb_Backend_document_unlock(VALUE self, cb_extract_timeout(req, options); cb_extract_cas(req.cas, cas); - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -569,7 +566,7 @@ cb_Backend_document_upsert(VALUE self, VALUE flags, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -588,8 +585,7 @@ cb_Backend_document_upsert(VALUE self, set_durability(opts, options); set_preserve_expiry(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .upsert(cb_string_new(id), @@ -620,7 +616,7 @@ cb_Backend_document_append(VALUE self, VALUE content, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -636,8 +632,7 @@ cb_Backend_document_append(VALUE self, set_timeout(opts, options); set_durability(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .binary() @@ -667,7 +662,7 @@ cb_Backend_document_prepend(VALUE self, VALUE content, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -683,8 +678,7 @@ cb_Backend_document_prepend(VALUE self, set_timeout(opts, options); set_durability(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .binary() @@ -715,7 +709,7 @@ cb_Backend_document_replace(VALUE self, VALUE flags, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -735,8 +729,7 @@ cb_Backend_document_replace(VALUE self, set_preserve_expiry(opts, options); set_cas(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .replace(cb_string_new(id), @@ -768,7 +761,7 @@ cb_Backend_document_insert(VALUE self, VALUE flags, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -786,8 +779,7 @@ cb_Backend_document_insert(VALUE self, set_expiry(opts, options); set_durability(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .insert(cb_string_new(id), @@ -817,7 +809,7 @@ cb_Backend_document_remove(VALUE self, VALUE id, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -833,8 +825,7 @@ cb_Backend_document_remove(VALUE self, set_durability(opts, options); set_cas(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .remove(cb_string_new(id), opts); @@ -862,7 +853,7 @@ cb_Backend_document_increment(VALUE self, VALUE id, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -880,8 +871,7 @@ cb_Backend_document_increment(VALUE self, set_delta(opts, options); set_initial_value(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .binary() @@ -912,7 +902,7 @@ cb_Backend_document_decrement(VALUE self, VALUE id, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -930,10 +920,8 @@ cb_Backend_document_decrement(VALUE self, set_delta(opts, options); set_initial_value(opts, options); - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) - .collection(cb_string_new(collection)) .binary() .decrement(cb_string_new(id), opts); @@ -965,7 +953,7 @@ cb_Backend_document_lookup_in(VALUE self, VALUE specs, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -1022,13 +1010,16 @@ cb_Backend_document_lookup_in(VALUE self, cb_check_type(path, T_STRING); req.specs.emplace_back(core::impl::subdoc::command{ - opcode, cb_string_new(path), {}, core::impl::subdoc::build_lookup_in_path_flags(xattr) }); + opcode, + cb_string_new(path), + {}, + core::impl::subdoc::build_lookup_in_path_flags(xattr, false) }); } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -1089,7 +1080,7 @@ cb_Backend_document_lookup_in_any_replica(VALUE self, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -1144,14 +1135,16 @@ cb_Backend_document_lookup_in_any_replica(VALUE self, } cb_check_type(path, T_STRING); req.specs.emplace_back(core::impl::subdoc::command{ - opcode, cb_string_new(path), {}, core::impl::subdoc::build_lookup_in_path_flags(xattr) }); + opcode, + cb_string_new(path), + {}, + core::impl::subdoc::build_lookup_in_path_flags(xattr, false) }); } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -1214,7 +1207,7 @@ cb_Backend_document_lookup_in_all_replicas(VALUE self, VALUE specs, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -1271,13 +1264,15 @@ cb_Backend_document_lookup_in_all_replicas(VALUE self, cb_check_type(path, T_STRING); req.specs.emplace_back(core::impl::subdoc::command{ - opcode, cb_string_new(path), {}, core::impl::subdoc::build_lookup_in_path_flags(xattr) }); + opcode, + cb_string_new(path), + {}, + core::impl::subdoc::build_lookup_in_path_flags(xattr, false) }); } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -1349,7 +1344,7 @@ cb_Backend_document_mutate_in(VALUE self, VALUE specs, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -1471,8 +1466,7 @@ cb_Backend_document_mutate_in(VALUE self, } } - auto f = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto f = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)) .mutate_in(cb_string_new(id), cxx_specs, opts); diff --git a/ext/rcb_diagnostics.cxx b/ext/rcb_diagnostics.cxx index 6f970a16..11845ccf 100644 --- a/ext/rcb_diagnostics.cxx +++ b/ext/rcb_diagnostics.cxx @@ -33,7 +33,7 @@ namespace VALUE cb_Backend_diagnostics(VALUE self, VALUE report_id) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); if (!NIL_P(report_id)) { Check_Type(report_id, T_STRING); @@ -44,10 +44,10 @@ cb_Backend_diagnostics(VALUE self, VALUE report_id) if (!NIL_P(report_id)) { id.emplace(cb_string_new(report_id)); } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->diagnostics(id, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.diagnostics(id, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); @@ -128,7 +128,7 @@ cb_Backend_diagnostics(VALUE self, VALUE report_id) VALUE cb_Backend_ping(VALUE self, VALUE bucket, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); if (!NIL_P(bucket)) { Check_Type(bucket, T_STRING); @@ -175,11 +175,15 @@ cb_Backend_ping(VALUE self, VALUE bucket, VALUE options) std::optional timeout{}; cb_extract_timeout(timeout, options); - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->ping(report_id, bucket_name, selected_services, timeout, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); - }); + std::promise promise; + auto f = promise.get_future(); + cluster.ping(report_id, + bucket_name, + selected_services, + timeout, + [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); + }); auto resp = cb_wait_for_future(f); VALUE res = rb_hash_new(); diff --git a/ext/rcb_exceptions.cxx b/ext/rcb_exceptions.cxx index fa515ec0..8cce91d8 100644 --- a/ext/rcb_exceptions.cxx +++ b/ext/rcb_exceptions.cxx @@ -15,17 +15,17 @@ * limitations under the License. */ +#include +#include +#include + #include #include +#include #include #include #include -#include -#include -#include -#include -#include -#include +#include #include @@ -631,7 +631,7 @@ exc_invalid_argument() -> VALUE } [[nodiscard]] VALUE -cb_map_error(const key_value_error_context& ctx, const std::string& message) +cb_map_error(const core::key_value_error_context& ctx, const std::string& message) { VALUE exc = cb_map_error_code(ctx.ec(), message); VALUE error_context = rb_hash_new(); @@ -691,25 +691,6 @@ cb_map_error(const key_value_error_context& ctx, const std::string& message) namespace { -[[nodiscard]] VALUE -cb_map_error(const subdocument_error_context& ctx, const std::string& message) -{ - VALUE exc = ruby::cb_map_error(static_cast(ctx), message); - VALUE error_context = rb_iv_get(exc, "@context"); - rb_hash_aset(error_context, rb_id2sym(rb_intern("deleted")), ctx.deleted() ? Qtrue : Qfalse); - if (ctx.first_error_index()) { - rb_hash_aset(error_context, - rb_id2sym(rb_intern("first_error_index")), - ULL2NUM(ctx.first_error_index().value())); - } - if (ctx.first_error_path()) { - rb_hash_aset(error_context, - rb_id2sym(rb_intern("first_error_path")), - cb_str_new(ctx.first_error_path().value())); - } - return exc; -} - [[nodiscard]] VALUE cb_map_error(const core::error_context::query& ctx, const std::string& message) { @@ -881,43 +862,6 @@ cb_map_error(const core::error_context::http& ctx, const std::string& message) return exc; } -[[nodiscard]] VALUE -cb_map_error(const manager_error_context& ctx, const std::string& message) -{ - VALUE exc = cb_map_error_code(ctx.ec(), message); - VALUE error_context = rb_hash_new(); - rb_hash_aset(error_context, rb_id2sym(rb_intern("error")), cb_str_new(ctx.ec().message())); - rb_hash_aset( - error_context, rb_id2sym(rb_intern("client_context_id")), cb_str_new(ctx.client_context_id())); - rb_hash_aset(error_context, rb_id2sym(rb_intern("path")), cb_str_new(ctx.path())); - rb_hash_aset(error_context, rb_id2sym(rb_intern("http_status")), INT2FIX(ctx.http_status())); - rb_hash_aset(error_context, rb_id2sym(rb_intern("http_body")), cb_str_new(ctx.content())); - if (ctx.retry_attempts() > 0) { - rb_hash_aset( - error_context, rb_id2sym(rb_intern("retry_attempts")), ULONG2NUM(ctx.retry_attempts())); - if (!ctx.retry_reasons().empty()) { - VALUE retry_reasons = rb_ary_new_capa(static_cast(ctx.retry_reasons().size())); - for (const auto& reason : ctx.retry_reasons()) { - auto reason_str = fmt::format("{}", reason); - rb_ary_push(retry_reasons, rb_id2sym(rb_intern(reason_str.c_str()))); - } - rb_hash_aset(error_context, rb_id2sym(rb_intern("retry_reasons")), retry_reasons); - } - } - if (ctx.last_dispatched_to()) { - rb_hash_aset(error_context, - rb_id2sym(rb_intern("last_dispatched_to")), - cb_str_new(ctx.last_dispatched_to().value())); - } - if (ctx.last_dispatched_from()) { - rb_hash_aset(error_context, - rb_id2sym(rb_intern("last_dispatched_from")), - cb_str_new(ctx.last_dispatched_from().value())); - } - rb_iv_set(exc, "@context", error_context); - return exc; -} - [[nodiscard]] VALUE cb_map_error(const core::error_context::search& ctx, const std::string& message) { @@ -960,16 +904,23 @@ cb_map_error(const core::error_context::search& ctx, const std::string& message) rb_iv_set(exc, "@context", error_context); return exc; } + } // namespace -void -cb_throw_error(const core::error_context::search& ctx, const std::string& message) +[[nodiscard]] VALUE +cb_map_error(const error& err, const std::string& message) { - throw ruby_exception(cb_map_error(ctx, message)); + VALUE exc = cb_map_error_code(err.ec(), fmt::format("{}: {}", message, err.message()), true); + static const auto id_context_eq = rb_intern("context="); + rb_funcall(exc, id_context_eq, 1, cb_str_new(err.ctx().to_json())); + if (auto cause = err.cause(); cause) { + rb_iv_set(exc, "@cause", cb_map_error(cause.value(), "Caused by")); + } + return exc; } void -cb_throw_error(const manager_error_context& ctx, const std::string& message) +cb_throw_error(const core::error_context::search& ctx, const std::string& message) { throw ruby_exception(cb_map_error(ctx, message)); } @@ -999,13 +950,13 @@ cb_throw_error(const core::error_context::query& ctx, const std::string& message } void -cb_throw_error(const subdocument_error_context& ctx, const std::string& message) +cb_throw_error(const core::key_value_error_context& ctx, const std::string& message) { throw ruby_exception(cb_map_error(ctx, message)); } void -cb_throw_error(const key_value_error_context& ctx, const std::string& message) +cb_throw_error(const error& ctx, const std::string& message) { throw ruby_exception(cb_map_error(ctx, message)); } diff --git a/ext/rcb_exceptions.hxx b/ext/rcb_exceptions.hxx index 7a4db0f4..6580e058 100644 --- a/ext/rcb_exceptions.hxx +++ b/ext/rcb_exceptions.hxx @@ -26,17 +26,20 @@ namespace couchbase { +class error; +namespace core +{ class key_value_error_context; class subdocument_error_context; -class manager_error_context; -namespace core::error_context +namespace error_context { class query; class analytics; class view; class http; class search; -} // namespace core::error_context +} // namespace error_context +} // namespace core } // namespace couchbase namespace couchbase::ruby @@ -72,19 +75,19 @@ cb_map_error_code(std::error_code ec, bool include_error_code = true) -> VALUE; [[nodiscard]] VALUE -cb_map_error(const key_value_error_context& ctx, const std::string& message); +cb_map_error(const core::key_value_error_context& ctx, const std::string& message); -[[noreturn]] void -cb_throw_error_code(std::error_code ec, const std::string& message); +[[nodiscard]] VALUE +cb_map_error(const error& err, const std::string& message); [[noreturn]] void -cb_throw_error(const key_value_error_context& ctx, const std::string& message); +cb_throw_error_code(std::error_code ec, const std::string& message); [[noreturn]] void -cb_throw_error(const subdocument_error_context& ctx, const std::string& message); +cb_throw_error(const error& ctx, const std::string& message); [[noreturn]] void -cb_throw_error(const manager_error_context& ctx, const std::string& message); +cb_throw_error(const core::key_value_error_context& ctx, const std::string& message); [[noreturn]] void cb_throw_error(const core::error_context::query& ctx, const std::string& message); diff --git a/ext/rcb_extras.cxx b/ext/rcb_extras.cxx index 3b718dc2..7000e73e 100644 --- a/ext/rcb_extras.cxx +++ b/ext/rcb_extras.cxx @@ -49,7 +49,7 @@ namespace VALUE cb_Backend_collections_manifest_get(VALUE self, VALUE bucket_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); @@ -57,11 +57,10 @@ cb_Backend_collections_manifest_get(VALUE self, VALUE bucket_name, VALUE timeout core::operations::management::collections_manifest_get_request req{ core::document_id{ cb_string_new(bucket_name), "_default", "_default", "" } }; cb_extract_timeout(req, timeout); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec()) { @@ -126,12 +125,14 @@ cb_Backend_dns_srv(VALUE self, VALUE hostname, VALUE service) if (tls) { service_name = "_couchbases"; } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - client.query_srv( - host_name, service_name, core::io::dns::dns_config::system_config(), [promise](auto&& resp) { - promise->set_value(std::forward(resp)); - }); + std::promise promise; + auto f = promise.get_future(); + client.query_srv(host_name, + service_name, + core::io::dns::dns_config::system_config(), + [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); + }); ctx.run(); auto resp = cb_wait_for_future(f); if (resp.ec) { @@ -343,29 +344,27 @@ cb_Backend_form_encode(VALUE self, VALUE data) VALUE cb_Backend_cluster_enable_developer_preview(VALUE self) { - const auto& cluster = couchbase::ruby::cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { - couchbase::core::operations::management::cluster_developer_preview_enable_request req{}; - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + core::operations::management::cluster_developer_preview_enable_request req{}; + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); - if (auto resp = couchbase::ruby::cb_wait_for_future(f); resp.ctx.ec) { - couchbase::ruby::cb_throw_error(resp.ctx, - "unable to enable developer preview for this cluster"); + if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { + cb_throw_error(resp.ctx, "unable to enable developer preview for this cluster"); } CB_LOG_CRITICAL_RAW("Developer preview cannot be disabled once it is enabled. If you enter " "developer preview mode you will not be able to " "upgrade. DO NOT USE IN PRODUCTION."); return Qtrue; } catch (const std::system_error& se) { - rb_exc_raise(couchbase::ruby::cb_map_error_code( + rb_exc_raise(cb_map_error_code( se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false)); - } catch (const couchbase::ruby::ruby_exception& e) { + } catch (const ruby_exception& e) { rb_exc_raise(e.exception_object()); } return Qnil; diff --git a/ext/rcb_multi.cxx b/ext/rcb_multi.cxx index ef332565..fb0f7ea1 100644 --- a/ext/rcb_multi.cxx +++ b/ext/rcb_multi.cxx @@ -22,7 +22,6 @@ #include #include -#include #include @@ -164,7 +163,7 @@ cb_extract_array_of_id_cas(std::vector>& VALUE cb_Backend_document_get_multi(VALUE self, VALUE keys, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { std::chrono::milliseconds timeout{ 0 }; @@ -174,24 +173,24 @@ cb_Backend_document_get_multi(VALUE self, VALUE keys, VALUE options) cb_extract_array_of_ids(ids, keys); auto num_of_ids = ids.size(); - std::vector>> promises; - promises.reserve(num_of_ids); + std::vector> futures; + futures.reserve(num_of_ids); for (auto& id : ids) { core::operations::get_request req{ std::move(id) }; if (timeout.count() > 0) { req.timeout = timeout; } - auto promise = std::make_shared>(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + futures.emplace_back(promise.get_future()); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); - promises.emplace_back(promise); } VALUE res = rb_ary_new_capa(static_cast(num_of_ids)); - for (const auto& promise : promises) { - auto resp = promise->get_future().get(); + for (auto& future : futures) { + auto resp = future.get(); VALUE entry = rb_hash_new(); if (resp.ctx.ec()) { rb_hash_aset(entry, @@ -223,7 +222,7 @@ cb_Backend_document_upsert_multi(VALUE self, VALUE id_content, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); try { couchbase::upsert_options opts; @@ -232,8 +231,7 @@ cb_Backend_document_upsert_multi(VALUE self, set_durability(opts, options); set_preserve_expiry(opts, options); - auto c = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto c = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)); @@ -242,23 +240,24 @@ cb_Backend_document_upsert_multi(VALUE self, auto num_of_tuples = tuples.size(); std::vector< - std::future>> + std::pair>>> futures; futures.reserve(num_of_tuples); for (auto& [id, content] : tuples) { - futures.emplace_back(c.upsert(std::move(id), content, opts)); + futures.emplace_back(id, c.upsert(id, std::move(content), opts)); } VALUE res = rb_ary_new_capa(static_cast(num_of_tuples)); - for (auto& f : futures) { - auto [ctx, resp] = f.get(); + for (auto& [id, f] : futures) { + auto [err, resp] = f.get(); VALUE entry = to_mutation_result_value(resp); - if (ctx.ec()) { - rb_hash_aset( - entry, rb_id2sym(rb_intern("error")), cb_map_error(ctx, "unable (multi)upsert")); + if (err.ec()) { + static const auto sym_error = rb_id2sym(rb_intern("error")); + rb_hash_aset(entry, sym_error, cb_map_error(err, "unable (multi)upsert")); } - rb_hash_aset(entry, rb_id2sym(rb_intern("id")), cb_str_new(ctx.id())); + static const auto sym_id = rb_id2sym(rb_intern("id")); + rb_hash_aset(entry, sym_id, cb_str_new(id)); rb_ary_push(res, entry); } return res; @@ -279,7 +278,7 @@ cb_Backend_document_remove_multi(VALUE self, VALUE id_cas, VALUE options) { - const auto& core = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_public_api_cluster(self); if (!NIL_P(options)) { Check_Type(options, T_HASH); @@ -293,31 +292,32 @@ cb_Backend_document_remove_multi(VALUE self, std::vector> tuples{}; cb_extract_array_of_id_cas(tuples, id_cas); - auto c = couchbase::cluster(*core) - .bucket(cb_string_new(bucket)) + auto c = cluster.bucket(cb_string_new(bucket)) .scope(cb_string_new(scope)) .collection(cb_string_new(collection)); auto num_of_tuples = tuples.size(); std::vector< - std::future>> + std::pair>>> futures; futures.reserve(num_of_tuples); - for (auto& [id, cas] : tuples) { + for (const auto& [id, cas] : tuples) { opts.cas(cas); - futures.emplace_back(c.remove(std::move(id), opts)); + futures.emplace_back(id, c.remove(id, opts)); } VALUE res = rb_ary_new_capa(static_cast(num_of_tuples)); - for (auto& f : futures) { + for (auto& [id, f] : futures) { auto [ctx, resp] = f.get(); VALUE entry = to_mutation_result_value(resp); if (ctx.ec()) { - rb_hash_aset( - entry, rb_id2sym(rb_intern("error")), cb_map_error(ctx, "unable (multi)remove")); + static const auto sym_error = rb_id2sym(rb_intern("error")); + rb_hash_aset(entry, sym_error, cb_map_error(ctx, "unable (multi)remove")); } - rb_hash_aset(entry, rb_id2sym(rb_intern("id")), cb_str_new(ctx.id())); + static const auto sym_id = rb_id2sym(rb_intern("id")); + rb_hash_aset(entry, sym_id, cb_str_new(id)); + rb_ary_push(res, entry); } diff --git a/ext/rcb_query.cxx b/ext/rcb_query.cxx index 553026d2..e1cdca85 100644 --- a/ext/rcb_query.cxx +++ b/ext/rcb_query.cxx @@ -39,7 +39,7 @@ namespace VALUE cb_Backend_query_index_get_all(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -60,11 +60,10 @@ cb_Backend_query_index_get_all(VALUE self, VALUE bucket_name, VALUE options) req.collection_name = cb_string_new(collection_name); } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -123,7 +122,7 @@ cb_Backend_query_index_create(VALUE self, VALUE keys, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(index_name, T_STRING); @@ -175,11 +174,10 @@ cb_Backend_query_index_create(VALUE self, } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -223,7 +221,7 @@ cb_Backend_query_index_create(VALUE self, VALUE cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(index_name, T_STRING); @@ -255,11 +253,10 @@ cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VAL } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -303,7 +300,7 @@ cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VAL VALUE cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -346,11 +343,10 @@ cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE optio } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -393,7 +389,7 @@ cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE optio VALUE cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -429,11 +425,10 @@ cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -475,7 +470,7 @@ cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options VALUE cb_Backend_query_index_build_deferred(VALUE self, VALUE bucket_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); if (!NIL_P(options)) { @@ -498,12 +493,11 @@ cb_Backend_query_index_build_deferred(VALUE self, VALUE bucket_name, VALUE optio } } - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); + std::promise promise; + auto f = promise.get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -576,7 +570,7 @@ cb_for_each_raw_param(VALUE key, VALUE value, VALUE arg) VALUE cb_Backend_document_query(VALUE self, VALUE statement, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(statement, T_STRING); Check_Type(options, T_HASH); @@ -686,10 +680,10 @@ cb_Backend_document_query(VALUE self, VALUE statement, VALUE options) rb_hash_foreach(raw_params, cb_for_each_raw_param, reinterpret_cast(&req)); } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -765,7 +759,7 @@ cb_Backend_collection_query_index_get_all(VALUE self, VALUE collection_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -780,11 +774,10 @@ cb_Backend_collection_query_index_get_all(VALUE self, req.scope_name = cb_string_new(scope_name); req.collection_name = cb_string_new(collection_name); cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -845,7 +838,7 @@ cb_Backend_collection_query_index_create(VALUE self, VALUE keys, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); Check_Type(collection_name, T_STRING); @@ -900,11 +893,10 @@ cb_Backend_collection_query_index_create(VALUE self, } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -953,7 +945,7 @@ cb_Backend_collection_query_index_drop(VALUE self, VALUE index_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -988,11 +980,10 @@ cb_Backend_collection_query_index_drop(VALUE self, } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -1041,7 +1032,7 @@ cb_Backend_collection_query_index_create_primary(VALUE self, VALUE collection_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -1088,11 +1079,10 @@ cb_Backend_collection_query_index_create_primary(VALUE self, } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -1139,7 +1129,7 @@ cb_Backend_collection_query_index_drop_primary(VALUE self, VALUE collection_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -1179,11 +1169,10 @@ cb_Backend_collection_query_index_drop_primary(VALUE self, } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -1230,7 +1219,7 @@ cb_Backend_collection_query_index_build_deferred(VALUE self, VALUE collection_name, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(scope_name, T_STRING); @@ -1246,11 +1235,10 @@ cb_Backend_collection_query_index_build_deferred(VALUE self, req.scope_name = cb_string_new(scope_name); req.collection_name = cb_string_new(collection_name); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { diff --git a/ext/rcb_range_scan.cxx b/ext/rcb_range_scan.cxx index 4818356b..b5ce40de 100644 --- a/ext/rcb_range_scan.cxx +++ b/ext/rcb_range_scan.cxx @@ -108,14 +108,14 @@ cb_CoreScanResult_next_item(VALUE self) try { cb_core_scan_result_data* data = nullptr; TypedData_Get_Struct(self, cb_core_scan_result_data, &cb_core_scan_result_type, data); - auto barrier = std::make_shared< - std::promise>>(); - auto f = barrier->get_future(); - data->scan_result->next([barrier](couchbase::core::range_scan_item item, std::error_code ec) { + std::promise> promise; + auto f = promise.get_future(); + data->scan_result->next([promise = std::move(promise)](couchbase::core::range_scan_item item, + std::error_code ec) mutable { if (ec) { - return barrier->set_value(tl::unexpected(ec)); + return promise.set_value(tl::unexpected(ec)); } - return barrier->set_value(item); + return promise.set_value(item); }); auto resp = cb_wait_for_future(f); if (!resp.has_value()) { @@ -161,7 +161,7 @@ cb_Backend_document_scan_create(VALUE self, VALUE scan_type, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket, T_STRING); Check_Type(scope, T_STRING); @@ -228,7 +228,7 @@ cb_Backend_document_scan_create(VALUE self, // Getting the operation agent auto agent_group = couchbase::core::agent_group( - cluster->io_context(), couchbase::core::agent_group_config{ { *cluster } }); + cluster.io_context(), couchbase::core::agent_group_config{ { cluster } }); auto err = agent_group.open_bucket(bucket_name); if (err) { cb_throw_error_code(err, "unable to open bucket for range scan"); @@ -242,17 +242,16 @@ cb_Backend_document_scan_create(VALUE self, } // Getting the vbucket map - auto barrier = std::make_shared< - std::promise>>(); - auto f = barrier->get_future(); - cluster->with_bucket_configuration( + std::promise> promise; + auto f = promise.get_future(); + cluster.with_bucket_configuration( bucket_name, - [barrier](std::error_code ec, - const couchbase::core::topology::configuration& config) mutable { + [promise = std::move(promise)]( + std::error_code ec, const couchbase::core::topology::configuration& config) mutable { if (ec) { - return barrier->set_value(tl::unexpected(ec)); + return promise.set_value(tl::unexpected(ec)); } - barrier->set_value(config); + promise.set_value(config); }); auto config = cb_wait_for_future(f); if (!config.has_value()) { @@ -309,7 +308,7 @@ cb_Backend_document_scan_create(VALUE self, rb_raise(exc_invalid_argument(), "Invalid scan operation type"); } - auto orchestrator = couchbase::core::range_scan_orchestrator(cluster->io_context(), + auto orchestrator = couchbase::core::range_scan_orchestrator(cluster.io_context(), agent.value(), vbucket_map.value(), scope_name, diff --git a/ext/rcb_search.cxx b/ext/rcb_search.cxx index 77cc8871..3a277f0b 100644 --- a/ext/rcb_search.cxx +++ b/ext/rcb_search.cxx @@ -73,7 +73,7 @@ cb_extract_search_index(VALUE index, const core::management::search::index& idx) VALUE cb_Backend_search_index_get_all(VALUE self, VALUE bucket, VALUE scope, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::search_index_get_all_request req{}; @@ -87,11 +87,10 @@ cb_Backend_search_index_get_all(VALUE self, VALUE bucket, VALUE scope, VALUE opt } cb_extract_timeout(req, options); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -120,7 +119,7 @@ cb_Backend_search_index_get_all(VALUE self, VALUE bucket, VALUE scope, VALUE opt VALUE cb_Backend_search_index_get(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -136,11 +135,10 @@ cb_Backend_search_index_get(VALUE self, VALUE bucket, VALUE scope, VALUE index_n } cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -171,7 +169,7 @@ cb_Backend_search_index_upsert(VALUE self, VALUE index_definition, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_definition, T_HASH); @@ -235,11 +233,10 @@ cb_Backend_search_index_upsert(VALUE self, req.index.plan_params_json = cb_string_new(plan_params); } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -267,7 +264,7 @@ cb_Backend_search_index_upsert(VALUE self, VALUE cb_Backend_search_index_drop(VALUE self, VALUE bucket, VALUE scope, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -283,11 +280,10 @@ cb_Backend_search_index_drop(VALUE self, VALUE bucket, VALUE scope, VALUE index_ } cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -319,7 +315,7 @@ cb_Backend_search_index_get_documents_count(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -335,11 +331,10 @@ cb_Backend_search_index_get_documents_count(VALUE self, } cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -373,7 +368,7 @@ cb_Backend_search_index_get_documents_count(VALUE self, VALUE cb_Backend_search_index_get_stats(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -381,11 +376,10 @@ cb_Backend_search_index_get_stats(VALUE self, VALUE index_name, VALUE timeout) core::operations::management::search_index_get_stats_request req{}; cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -412,16 +406,15 @@ cb_Backend_search_index_get_stats(VALUE self, VALUE index_name, VALUE timeout) VALUE cb_Backend_search_get_stats(VALUE self, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::search_get_stats_request req{}; cb_extract_timeout(req, timeout); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -444,7 +437,7 @@ cb_Backend_search_index_pause_ingest(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -461,11 +454,10 @@ cb_Backend_search_index_pause_ingest(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.pause = true; - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -499,7 +491,7 @@ cb_Backend_search_index_resume_ingest(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -516,11 +508,10 @@ cb_Backend_search_index_resume_ingest(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.pause = false; - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -554,7 +545,7 @@ cb_Backend_search_index_allow_querying(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -571,11 +562,10 @@ cb_Backend_search_index_allow_querying(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.allow = true; - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -609,7 +599,7 @@ cb_Backend_search_index_disallow_querying(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -626,11 +616,10 @@ cb_Backend_search_index_disallow_querying(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.allow = false; - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -664,7 +653,7 @@ cb_Backend_search_index_freeze_plan(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -681,11 +670,10 @@ cb_Backend_search_index_freeze_plan(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.freeze = true; - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -718,7 +706,7 @@ cb_Backend_search_index_unfreeze_plan(VALUE self, VALUE index_name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); @@ -735,11 +723,10 @@ cb_Backend_search_index_unfreeze_plan(VALUE self, cb_extract_timeout(req, timeout); req.index_name = cb_string_new(index_name); req.freeze = false; - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -774,7 +761,7 @@ cb_Backend_search_index_analyze_document(VALUE self, VALUE encoded_document, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); Check_Type(encoded_document, T_STRING); @@ -794,11 +781,10 @@ cb_Backend_search_index_analyze_document(VALUE self, req.index_name = cb_string_new(index_name); req.encoded_document = cb_string_new(encoded_document); - auto promise = std::make_shared< - std::promise>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -850,7 +836,7 @@ cb_Backend_document_search(VALUE self, VALUE search_request, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(index_name, T_STRING); Check_Type(query, T_STRING); @@ -1031,10 +1017,10 @@ cb_Backend_document_search(VALUE self, rb_hash_foreach(raw_params, cb_for_each_raw_param, reinterpret_cast(&req)); } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { diff --git a/ext/rcb_users.cxx b/ext/rcb_users.cxx index 822a7176..fccabc7a 100644 --- a/ext/rcb_users.cxx +++ b/ext/rcb_users.cxx @@ -63,16 +63,15 @@ cb_extract_role(const core::management::rbac::role_and_description& entry, VALUE VALUE cb_Backend_role_get_all(VALUE self, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::role_get_all_request req{}; cb_extract_timeout(req, timeout); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -175,7 +174,7 @@ cb_extract_user(const core::management::rbac::user_and_metadata& entry, VALUE us VALUE cb_Backend_user_get_all(VALUE self, VALUE domain, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(domain, T_SYMBOL); @@ -190,11 +189,10 @@ cb_Backend_user_get_all(VALUE self, VALUE domain, VALUE timeout) throw ruby_exception(exc_invalid_argument(), rb_sprintf("unsupported authentication domain: %+" PRIsVALUE, domain)); } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -220,7 +218,7 @@ cb_Backend_user_get_all(VALUE self, VALUE domain, VALUE timeout) VALUE cb_Backend_user_get(VALUE self, VALUE domain, VALUE username, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(domain, T_SYMBOL); Check_Type(username, T_STRING); @@ -237,11 +235,10 @@ cb_Backend_user_get(VALUE self, VALUE domain, VALUE username, VALUE timeout) rb_sprintf("unsupported authentication domain: %+" PRIsVALUE, domain)); } req.username = cb_string_new(username); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -263,7 +260,7 @@ cb_Backend_user_get(VALUE self, VALUE domain, VALUE username, VALUE timeout) VALUE cb_Backend_user_drop(VALUE self, VALUE domain, VALUE username, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(domain, T_SYMBOL); Check_Type(username, T_STRING); @@ -280,11 +277,10 @@ cb_Backend_user_drop(VALUE self, VALUE domain, VALUE username, VALUE timeout) rb_sprintf("unsupported authentication domain: %+" PRIsVALUE, domain)); } req.username = cb_string_new(username); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { cb_throw_error(resp.ctx, fmt::format(R"(unable to fetch user "{}")", req.username)); @@ -303,7 +299,7 @@ cb_Backend_user_drop(VALUE self, VALUE domain, VALUE username, VALUE timeout) VALUE cb_Backend_user_upsert(VALUE self, VALUE domain, VALUE user, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(domain, T_SYMBOL); Check_Type(user, T_HASH); @@ -369,11 +365,10 @@ cb_Backend_user_upsert(VALUE self, VALUE domain, VALUE user, VALUE timeout) } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -396,7 +391,7 @@ cb_Backend_user_upsert(VALUE self, VALUE domain, VALUE user, VALUE timeout) VALUE cb_Backend_change_password(VALUE self, VALUE new_password, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(new_password, T_STRING); @@ -404,11 +399,10 @@ cb_Backend_change_password(VALUE self, VALUE new_password, VALUE timeout) core::operations::management::change_password_request req{}; cb_extract_timeout(req, timeout); req.newPassword = cb_string_new(new_password); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { cb_throw_error(resp.ctx, "unable to change password"); @@ -457,16 +451,15 @@ cb_extract_group(const core::management::rbac::group& entry, VALUE group) VALUE cb_Backend_group_get_all(VALUE self, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); try { core::operations::management::group_get_all_request req{}; cb_extract_timeout(req, timeout); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -492,7 +485,7 @@ cb_Backend_group_get_all(VALUE self, VALUE timeout) VALUE cb_Backend_group_get(VALUE self, VALUE name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(name, T_STRING); @@ -500,11 +493,10 @@ cb_Backend_group_get(VALUE self, VALUE name, VALUE timeout) core::operations::management::group_get_request req{}; cb_extract_timeout(req, timeout); req.name = cb_string_new(name); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -526,7 +518,7 @@ cb_Backend_group_get(VALUE self, VALUE name, VALUE timeout) VALUE cb_Backend_group_drop(VALUE self, VALUE name, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(name, T_STRING); @@ -534,11 +526,10 @@ cb_Backend_group_drop(VALUE self, VALUE name, VALUE timeout) core::operations::management::group_drop_request req{}; cb_extract_timeout(req, timeout); req.name = cb_string_new(name); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -557,7 +548,7 @@ cb_Backend_group_drop(VALUE self, VALUE name, VALUE timeout) VALUE cb_Backend_group_upsert(VALUE self, VALUE group, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(group, T_HASH); @@ -605,11 +596,10 @@ cb_Backend_group_upsert(VALUE self, VALUE group, VALUE timeout) } } - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { cb_throw_error(resp.ctx, diff --git a/ext/rcb_utils.cxx b/ext/rcb_utils.cxx index 185c4fe3..bfc513a2 100644 --- a/ext/rcb_utils.cxx +++ b/ext/rcb_utils.cxx @@ -20,6 +20,7 @@ #include "rcb_exceptions.hxx" #include "rcb_utils.hxx" +#include #include namespace couchbase::ruby @@ -434,4 +435,156 @@ extract_legacy_durability_constraints(VALUE options) replicate_to.value_or(couchbase::replicate_to::none), } }; } + +namespace options +{ +std::optional +get_bool(VALUE options, VALUE name) +{ + if (!NIL_P(options) && TYPE(options) == T_HASH) { + cb_check_type(name, T_SYMBOL); + VALUE val = rb_hash_aref(options, name); + if (NIL_P(val)) { + return {}; + } + switch (TYPE(val)) { + case T_TRUE: + return true; + case T_FALSE: + return false; + default: + throw ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE " must be a Boolean, but given %+" PRIsVALUE, name, val)); + } + } + return {}; +} + +std::optional +get_milliseconds(VALUE options, VALUE name) +{ + if (!NIL_P(options) && TYPE(options) == T_HASH) { + cb_check_type(name, T_SYMBOL); + VALUE val = rb_hash_aref(options, name); + if (NIL_P(val)) { + return {}; + } + switch (TYPE(val)) { + case T_FIXNUM: + return std::chrono::milliseconds(FIX2ULONG(val)); + case T_BIGNUM: + return std::chrono::milliseconds(NUM2ULL(val)); + default: + throw ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE + " must be a Integer representing milliseconds, but given %+" PRIsVALUE, + name, + val)); + } + } + return {}; +} + +std::optional +get_size_t(VALUE options, VALUE name) +{ + if (!NIL_P(options) && TYPE(options) == T_HASH) { + cb_check_type(name, T_SYMBOL); + VALUE val = rb_hash_aref(options, name); + if (NIL_P(val)) { + return {}; + } + switch (TYPE(val)) { + case T_FIXNUM: + return static_cast(FIX2ULONG(val)); + case T_BIGNUM: + return static_cast(NUM2ULL(val)); + default: + throw ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE " must be a Integer, but given %+" PRIsVALUE, name, val)); + } + } + return {}; +} + +std::optional +get_uint16_t(VALUE options, VALUE name) +{ + if (!NIL_P(options) && TYPE(options) == T_HASH) { + cb_check_type(name, T_SYMBOL); + VALUE val = rb_hash_aref(options, name); + if (NIL_P(val)) { + return {}; + } + switch (TYPE(val)) { + case T_FIXNUM: + if (FIX2ULONG(val) > std::numeric_limits::max()) { + throw ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE " must not be larger than %d , but given %+" PRIsVALUE, + name, + static_cast(std::numeric_limits::max()), + val)); + } + return static_cast(FIX2ULONG(val)); + case T_BIGNUM: + if (NUM2ULL(val) > std::numeric_limits::max()) { + throw ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE " must not be larger than %d , but given %+" PRIsVALUE, + name, + static_cast(std::numeric_limits::max()), + val)); + } + return static_cast(NUM2ULL(val)); + default: + throw ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE " must be a Integer, but given %+" PRIsVALUE, name, val)); + } + } + return {}; +} + +std::optional +get_symbol(VALUE options, VALUE name) +{ + if (!NIL_P(options) && TYPE(options) == T_HASH) { + cb_check_type(name, T_SYMBOL); + VALUE val = rb_hash_aref(options, name); + if (NIL_P(val)) { + return {}; + } + if (TYPE(val) == T_SYMBOL) { + return val; + } + throw couchbase::ruby::ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE " must be an Symbol, but given %+" PRIsVALUE, name, val)); + } + return {}; +} + +std::optional +get_string(VALUE options, VALUE name) +{ + if (!NIL_P(options) && TYPE(options) == T_HASH) { + cb_check_type(name, T_SYMBOL); + VALUE val = rb_hash_aref(options, name); + if (NIL_P(val)) { + return {}; + } + if (TYPE(val) == T_STRING) { + return cb_string_new(val); + } + throw couchbase::ruby::ruby_exception( + rb_eArgError, + rb_sprintf("%+" PRIsVALUE " must be an String, but given %+" PRIsVALUE, name, val)); + } + return {}; +} +} // namespace options } // namespace couchbase::ruby diff --git a/ext/rcb_utils.hxx b/ext/rcb_utils.hxx index f037c28a..ba16da80 100644 --- a/ext/rcb_utils.hxx +++ b/ext/rcb_utils.hxx @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -87,6 +88,27 @@ cb_str_new(const char* data); VALUE cb_str_new(const std::optional& str); +namespace options +{ +std::optional +get_bool(VALUE options, VALUE name); + +std::optional +get_milliseconds(VALUE options, VALUE name); + +std::optional +get_size_t(VALUE options, VALUE name); + +std::optional +get_uint16_t(VALUE options, VALUE name); + +std::optional +get_symbol(VALUE options, VALUE name); + +std::optional +get_string(VALUE options, VALUE name); +} // namespace options + template inline void cb_extract_timeout(Request& req, VALUE options) @@ -180,6 +202,29 @@ cb_extract_option_uint64(T& field, VALUE options, const char* name) } } +template +inline void +cb_extract_option_number(Integer& field, VALUE options, const char* name) +{ + if (!NIL_P(options) && TYPE(options) == T_HASH) { + VALUE val = rb_hash_aref(options, rb_id2sym(rb_intern(name))); + if (NIL_P(val)) { + return; + } + switch (TYPE(val)) { + case T_FIXNUM: + field = static_cast(FIX2ULONG(val)); + break; + case T_BIGNUM: + field = static_cast(NUM2ULL(val)); + break; + default: + throw ruby_exception(rb_eArgError, + rb_sprintf("%s must be a Integer, but given %+" PRIsVALUE, name, val)); + } + } +} + void cb_extract_option_array(VALUE& val, VALUE options, const char* name); @@ -514,29 +559,6 @@ set_store_semantics(CommandOptions& opts, VALUE options) } } -template -inline void -cb_extract_option_number(Integer& field, VALUE options, const char* name) -{ - if (!NIL_P(options) && TYPE(options) == T_HASH) { - VALUE val = rb_hash_aref(options, rb_id2sym(rb_intern(name))); - if (NIL_P(val)) { - return; - } - switch (TYPE(val)) { - case T_FIXNUM: - field = static_cast(FIX2ULONG(val)); - break; - case T_BIGNUM: - field = static_cast(NUM2ULL(val)); - break; - default: - throw ruby_exception(rb_eArgError, - rb_sprintf("%s must be a Integer, but given %+" PRIsVALUE, name, val)); - } - } -} - } // namespace couchbase::ruby #endif diff --git a/ext/rcb_views.cxx b/ext/rcb_views.cxx index 8b8aae25..dcc8ca44 100644 --- a/ext/rcb_views.cxx +++ b/ext/rcb_views.cxx @@ -37,7 +37,7 @@ namespace VALUE cb_Backend_view_index_get_all(VALUE self, VALUE bucket_name, VALUE name_space, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(name_space, T_SYMBOL); @@ -57,11 +57,10 @@ cb_Backend_view_index_get_all(VALUE self, VALUE bucket_name, VALUE name_space, V req.bucket_name = cb_string_new(bucket_name); req.ns = ns; cb_extract_timeout(req, timeout); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -113,7 +112,7 @@ cb_Backend_view_index_get(VALUE self, VALUE name_space, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(document_name, T_STRING); @@ -135,11 +134,10 @@ cb_Backend_view_index_get(VALUE self, req.document_name = cb_string_new(document_name); req.ns = ns; cb_extract_timeout(req, timeout); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { @@ -191,7 +189,7 @@ cb_Backend_view_index_drop(VALUE self, VALUE name_space, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(document_name, T_STRING); @@ -213,11 +211,10 @@ cb_Backend_view_index_drop(VALUE self, req.document_name = cb_string_new(document_name); req.ns = ns; cb_extract_timeout(req, timeout); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -244,7 +241,7 @@ cb_Backend_view_index_upsert(VALUE self, VALUE name_space, VALUE timeout) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(document, T_HASH); @@ -290,11 +287,10 @@ cb_Backend_view_index_upsert(VALUE self, } cb_extract_timeout(req, timeout); - auto promise = - std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); if (auto resp = cb_wait_for_future(f); resp.ctx.ec) { @@ -322,7 +318,7 @@ cb_Backend_document_view(VALUE self, VALUE name_space, VALUE options) { - const auto& cluster = cb_backend_to_cluster(self); + auto cluster = cb_backend_to_core_api_cluster(self); Check_Type(bucket_name, T_STRING); Check_Type(design_document_name, T_STRING); @@ -424,10 +420,10 @@ cb_Backend_document_view(VALUE self, } } - auto promise = std::make_shared>(); - auto f = promise->get_future(); - cluster->execute(req, [promise](auto&& resp) { - promise->set_value(std::forward(resp)); + std::promise promise; + auto f = promise.get_future(); + cluster.execute(req, [promise = std::move(promise)](auto&& resp) mutable { + promise.set_value(std::forward(resp)); }); auto resp = cb_wait_for_future(f); if (resp.ctx.ec) { diff --git a/lib/couchbase/errors.rb b/lib/couchbase/errors.rb index fe1930e8..c1bc7170 100644 --- a/lib/couchbase/errors.rb +++ b/lib/couchbase/errors.rb @@ -20,30 +20,66 @@ module Couchbase # This namespace contains all error types that the library might raise. module Error class CouchbaseError < StandardError - # @return [Hash] attributes associated with the error + # @return [Hash, nil] attributes associated with the error attr_reader :context - def initialize(msg = nil, context = nil) - @context = context unless context.nil? + # @return [CouchbaseError, nil] original error that caused this one + attr_reader :cause + + def initialize(msg = nil, context = nil, cause = nil) + @context = context + @cause = cause super(msg) end + def context=(context) + return unless context.is_a?(String) + + @context = + begin + JSON.parse(context) + rescue StandardError + context + end + end + def to_s - defined?(@context) ? "#{super}, context=#{JSON.generate(@context)}" : super + result = super + result << ", context=#{JSON.generate(@context)}" if @context + result << ", cause=#{@cause}" if @cause + result end end class InvalidArgument < ArgumentError - # @return [Hash] attributes associated with the error + # @return [Hash, nil] attributes associated with the error attr_reader :context - def initialize(msg = nil, context = nil) - @context = context unless context.nil? + # @return [CouchbaseError, nil] original error that caused this one + attr_reader :cause + + def initialize(msg = nil, context = nil, cause = nil) + @context = context + @cause = cause super(msg) end + def context=(context) + return unless context.is_a?(String) + + @context = + begin + JSON.parse(context) + rescue StandardError + context + end + end + def to_s - defined?(@context) ? "#{super}, context=#{JSON.generate(@context)}" : super + result = super + result << ", context=#{JSON.generate(@context)}" if @context + result << ", cause=#{@cause}" if @cause + result end end