couchbase 3.0.0.alpha.1-universal-darwin-19 → 3.0.0.alpha.2-universal-darwin-19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/tests-6.0.3.yml +49 -0
- data/.github/workflows/tests.yml +47 -0
- data/.gitmodules +3 -0
- data/.idea/dictionaries/gem_terms.xml +5 -0
- data/.idea/inspectionProfiles/Project_Default.xml +1 -0
- data/.idea/vcs.xml +1 -0
- data/Gemfile +1 -0
- data/README.md +55 -2
- data/Rakefile +18 -0
- data/bin/init-cluster +62 -0
- data/bin/setup +1 -0
- data/couchbase.gemspec +3 -2
- data/examples/crud.rb +1 -2
- data/examples/managing_buckets.rb +47 -0
- data/examples/managing_collections.rb +58 -0
- data/examples/managing_query_indexes.rb +63 -0
- data/examples/query.rb +3 -2
- data/examples/query_with_consistency.rb +76 -0
- data/examples/subdocument.rb +23 -1
- data/ext/.clang-format +1 -1
- data/ext/.idea/dictionaries/couchbase_terms.xml +2 -0
- data/ext/.idea/vcs.xml +1 -0
- data/ext/CMakeLists.txt +30 -12
- data/ext/build_version.hxx.in +26 -0
- data/ext/couchbase/bucket.hxx +69 -8
- data/ext/couchbase/cluster.hxx +70 -54
- data/ext/couchbase/collections_manifest.hxx +3 -3
- data/ext/couchbase/configuration.hxx +14 -0
- data/ext/couchbase/couchbase.cxx +2044 -383
- data/ext/couchbase/{operations/document_id.hxx → document_id.hxx} +5 -4
- data/ext/couchbase/io/http_message.hxx +5 -1
- data/ext/couchbase/io/http_parser.hxx +2 -1
- data/ext/couchbase/io/http_session.hxx +6 -3
- data/ext/couchbase/io/{binary_message.hxx → mcbp_message.hxx} +15 -12
- data/ext/couchbase/io/mcbp_parser.hxx +99 -0
- data/ext/couchbase/io/{key_value_session.hxx → mcbp_session.hxx} +200 -95
- data/ext/couchbase/io/session_manager.hxx +37 -22
- data/ext/couchbase/mutation_token.hxx +2 -1
- data/ext/couchbase/operations.hxx +38 -8
- data/ext/couchbase/operations/bucket_create.hxx +138 -0
- data/ext/couchbase/operations/bucket_drop.hxx +65 -0
- data/ext/couchbase/operations/bucket_flush.hxx +65 -0
- data/ext/couchbase/operations/bucket_get.hxx +69 -0
- data/ext/couchbase/operations/bucket_get_all.hxx +62 -0
- data/ext/couchbase/operations/bucket_settings.hxx +111 -0
- data/ext/couchbase/operations/bucket_update.hxx +115 -0
- data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +60 -0
- data/ext/couchbase/operations/collection_create.hxx +86 -0
- data/ext/couchbase/operations/collection_drop.hxx +82 -0
- data/ext/couchbase/operations/command.hxx +10 -10
- data/ext/couchbase/operations/document_decrement.hxx +80 -0
- data/ext/couchbase/operations/document_exists.hxx +80 -0
- data/ext/couchbase/operations/{get.hxx → document_get.hxx} +4 -2
- data/ext/couchbase/operations/document_get_and_lock.hxx +64 -0
- data/ext/couchbase/operations/document_get_and_touch.hxx +64 -0
- data/ext/couchbase/operations/document_increment.hxx +80 -0
- data/ext/couchbase/operations/document_insert.hxx +74 -0
- data/ext/couchbase/operations/{lookup_in.hxx → document_lookup_in.hxx} +2 -2
- data/ext/couchbase/operations/{mutate_in.hxx → document_mutate_in.hxx} +11 -2
- data/ext/couchbase/operations/{query.hxx → document_query.hxx} +101 -6
- data/ext/couchbase/operations/document_remove.hxx +67 -0
- data/ext/couchbase/operations/document_replace.hxx +76 -0
- data/ext/couchbase/operations/{upsert.hxx → document_touch.hxx} +14 -14
- data/ext/couchbase/operations/{remove.hxx → document_unlock.hxx} +12 -10
- data/ext/couchbase/operations/document_upsert.hxx +74 -0
- data/ext/couchbase/operations/query_index_build_deferred.hxx +85 -0
- data/ext/couchbase/operations/query_index_create.hxx +134 -0
- data/ext/couchbase/operations/query_index_drop.hxx +108 -0
- data/ext/couchbase/operations/query_index_get_all.hxx +106 -0
- data/ext/couchbase/operations/scope_create.hxx +81 -0
- data/ext/couchbase/operations/scope_drop.hxx +79 -0
- data/ext/couchbase/operations/scope_get_all.hxx +72 -0
- data/ext/couchbase/protocol/client_opcode.hxx +35 -0
- data/ext/couchbase/protocol/client_request.hxx +56 -9
- data/ext/couchbase/protocol/client_response.hxx +52 -15
- data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +81 -0
- data/ext/couchbase/protocol/cmd_decrement.hxx +187 -0
- data/ext/couchbase/protocol/cmd_exists.hxx +171 -0
- data/ext/couchbase/protocol/cmd_get.hxx +31 -8
- data/ext/couchbase/protocol/cmd_get_and_lock.hxx +142 -0
- data/ext/couchbase/protocol/cmd_get_and_touch.hxx +142 -0
- data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +16 -3
- data/ext/couchbase/protocol/cmd_get_collections_manifest.hxx +16 -3
- data/ext/couchbase/protocol/cmd_get_error_map.hxx +16 -3
- data/ext/couchbase/protocol/cmd_hello.hxx +24 -8
- data/ext/couchbase/protocol/cmd_increment.hxx +187 -0
- data/ext/couchbase/protocol/cmd_info.hxx +1 -0
- data/ext/couchbase/protocol/cmd_insert.hxx +172 -0
- data/ext/couchbase/protocol/cmd_lookup_in.hxx +28 -13
- data/ext/couchbase/protocol/cmd_mutate_in.hxx +65 -13
- data/ext/couchbase/protocol/cmd_remove.hxx +59 -4
- data/ext/couchbase/protocol/cmd_replace.hxx +172 -0
- data/ext/couchbase/protocol/cmd_sasl_auth.hxx +15 -3
- data/ext/couchbase/protocol/cmd_sasl_list_mechs.hxx +15 -3
- data/ext/couchbase/protocol/cmd_sasl_step.hxx +15 -3
- data/ext/couchbase/protocol/cmd_select_bucket.hxx +14 -2
- data/ext/couchbase/protocol/cmd_touch.hxx +102 -0
- data/ext/couchbase/protocol/cmd_unlock.hxx +95 -0
- data/ext/couchbase/protocol/cmd_upsert.hxx +50 -14
- data/ext/couchbase/protocol/durability_level.hxx +67 -0
- data/ext/couchbase/protocol/frame_info_id.hxx +187 -0
- data/ext/couchbase/protocol/hello_feature.hxx +137 -0
- data/ext/couchbase/protocol/server_opcode.hxx +57 -0
- data/ext/couchbase/protocol/server_request.hxx +122 -0
- data/ext/couchbase/protocol/unsigned_leb128.h +15 -15
- data/ext/couchbase/utils/byteswap.hxx +1 -2
- data/ext/couchbase/utils/url_codec.hxx +225 -0
- data/ext/couchbase/version.hxx +3 -1
- data/ext/extconf.rb +4 -1
- data/ext/test/main.cxx +37 -113
- data/ext/third_party/snappy/.appveyor.yml +36 -0
- data/ext/third_party/snappy/.gitignore +8 -0
- data/ext/third_party/snappy/.travis.yml +98 -0
- data/ext/third_party/snappy/AUTHORS +1 -0
- data/ext/third_party/snappy/CMakeLists.txt +345 -0
- data/ext/third_party/snappy/CONTRIBUTING.md +26 -0
- data/ext/third_party/snappy/COPYING +54 -0
- data/ext/third_party/snappy/NEWS +188 -0
- data/ext/third_party/snappy/README.md +148 -0
- data/ext/third_party/snappy/cmake/SnappyConfig.cmake.in +33 -0
- data/ext/third_party/snappy/cmake/config.h.in +59 -0
- data/ext/third_party/snappy/docs/README.md +72 -0
- data/ext/third_party/snappy/format_description.txt +110 -0
- data/ext/third_party/snappy/framing_format.txt +135 -0
- data/ext/third_party/snappy/snappy-c.cc +90 -0
- data/ext/third_party/snappy/snappy-c.h +138 -0
- data/ext/third_party/snappy/snappy-internal.h +315 -0
- data/ext/third_party/snappy/snappy-sinksource.cc +121 -0
- data/ext/third_party/snappy/snappy-sinksource.h +182 -0
- data/ext/third_party/snappy/snappy-stubs-internal.cc +42 -0
- data/ext/third_party/snappy/snappy-stubs-internal.h +493 -0
- data/ext/third_party/snappy/snappy-stubs-public.h.in +63 -0
- data/ext/third_party/snappy/snappy-test.cc +613 -0
- data/ext/third_party/snappy/snappy-test.h +526 -0
- data/ext/third_party/snappy/snappy.cc +1770 -0
- data/ext/third_party/snappy/snappy.h +209 -0
- data/ext/third_party/snappy/snappy_compress_fuzzer.cc +60 -0
- data/ext/third_party/snappy/snappy_uncompress_fuzzer.cc +58 -0
- data/ext/third_party/snappy/snappy_unittest.cc +1512 -0
- data/ext/third_party/snappy/testdata/alice29.txt +3609 -0
- data/ext/third_party/snappy/testdata/asyoulik.txt +4122 -0
- data/ext/third_party/snappy/testdata/baddata1.snappy +0 -0
- data/ext/third_party/snappy/testdata/baddata2.snappy +0 -0
- data/ext/third_party/snappy/testdata/baddata3.snappy +0 -0
- data/ext/third_party/snappy/testdata/fireworks.jpeg +0 -0
- data/ext/third_party/snappy/testdata/geo.protodata +0 -0
- data/ext/third_party/snappy/testdata/html +1 -0
- data/ext/third_party/snappy/testdata/html_x_4 +1 -0
- data/ext/third_party/snappy/testdata/kppkn.gtb +0 -0
- data/ext/third_party/snappy/testdata/lcet10.txt +7519 -0
- data/ext/third_party/snappy/testdata/paper-100k.pdf +600 -2
- data/ext/third_party/snappy/testdata/plrabn12.txt +10699 -0
- data/ext/third_party/snappy/testdata/urls.10K +10000 -0
- data/lib/couchbase/binary_collection.rb +33 -76
- data/lib/couchbase/binary_collection_options.rb +94 -0
- data/lib/couchbase/bucket.rb +9 -3
- data/lib/couchbase/cluster.rb +161 -23
- data/lib/couchbase/collection.rb +108 -191
- data/lib/couchbase/collection_options.rb +430 -0
- data/lib/couchbase/errors.rb +136 -134
- data/lib/couchbase/json_transcoder.rb +32 -0
- data/lib/couchbase/management/analytics_index_manager.rb +185 -9
- data/lib/couchbase/management/bucket_manager.rb +84 -33
- data/lib/couchbase/management/collection_manager.rb +166 -1
- data/lib/couchbase/management/query_index_manager.rb +261 -0
- data/lib/couchbase/management/search_index_manager.rb +291 -0
- data/lib/couchbase/management/user_manager.rb +12 -10
- data/lib/couchbase/management/view_index_manager.rb +151 -1
- data/lib/couchbase/mutation_state.rb +11 -1
- data/lib/couchbase/scope.rb +4 -4
- data/lib/couchbase/version.rb +1 -1
- metadata +113 -18
- data/.travis.yml +0 -7
- data/ext/couchbase/io/binary_parser.hxx +0 -64
- data/lib/couchbase/results.rb +0 -307
@@ -69,14 +69,14 @@ struct traits
|
|
69
69
|
(void)v;
|
70
70
|
couchbase::collections_manifest result;
|
71
71
|
result.id = couchbase::uuid::random();
|
72
|
-
result.uid = std::stoull(v.at("uid").get_string());
|
72
|
+
result.uid = std::stoull(v.at("uid").get_string(), 0, 16);
|
73
73
|
for (const auto& s : v.at("scopes").get_array()) {
|
74
74
|
couchbase::collections_manifest::scope scope;
|
75
|
-
scope.uid = std::stoull(s.at("uid").get_string());
|
75
|
+
scope.uid = std::stoull(s.at("uid").get_string(), 0, 16);
|
76
76
|
scope.name = s.at("name").get_string();
|
77
77
|
for (const auto& c : s.at("collections").get_array()) {
|
78
78
|
couchbase::collections_manifest::collection collection;
|
79
|
-
collection.uid = std::stoull(c.at("uid").get_string());
|
79
|
+
collection.uid = std::stoull(c.at("uid").get_string(), 0, 16);
|
80
80
|
collection.name = c.at("name").get_string();
|
81
81
|
scope.collections.emplace_back(collection);
|
82
82
|
}
|
@@ -84,6 +84,20 @@ struct configuration {
|
|
84
84
|
return std::make_pair(vbucket, static_cast<std::size_t>(vbmap->at(vbucket)[0]));
|
85
85
|
}
|
86
86
|
};
|
87
|
+
|
88
|
+
configuration
|
89
|
+
make_blank_configuration(const std::string& hostname, std::uint16_t plain_port, std::uint16_t tls_port)
|
90
|
+
{
|
91
|
+
configuration result;
|
92
|
+
result.id = couchbase::uuid::random();
|
93
|
+
result.rev = 0;
|
94
|
+
result.nodes.resize(1);
|
95
|
+
result.nodes[0].hostname = hostname;
|
96
|
+
result.nodes[0].this_node = true;
|
97
|
+
result.nodes[0].services_plain.key_value = plain_port;
|
98
|
+
result.nodes[0].services_tls.key_value = tls_port;
|
99
|
+
return result;
|
100
|
+
}
|
87
101
|
} // namespace couchbase
|
88
102
|
|
89
103
|
template<>
|
data/ext/couchbase/couchbase.cxx
CHANGED
@@ -23,11 +23,16 @@
|
|
23
23
|
|
24
24
|
#include <http_parser.h>
|
25
25
|
|
26
|
+
#include <snappy.h>
|
27
|
+
|
26
28
|
#include <version.hxx>
|
27
29
|
#include <cluster.hxx>
|
28
30
|
#include <operations.hxx>
|
29
31
|
|
30
32
|
#include <ruby.h>
|
33
|
+
#if defined(HAVE_RUBY_VERSION_H)
|
34
|
+
#include <ruby/version.h>
|
35
|
+
#endif
|
31
36
|
|
32
37
|
#if !defined(RB_METHOD_DEFINITION_DECL)
|
33
38
|
#define VALUE_FUNC(f) reinterpret_cast<VALUE (*)(ANYARGS)>(f)
|
@@ -50,14 +55,26 @@ init_versions(VALUE mCouchbase)
|
|
50
55
|
#define VERSION_SPLIT_(VER) (VER) / 100000, (VER) / 100 % 1000, (VER) % 100
|
51
56
|
|
52
57
|
std::string ver;
|
58
|
+
ver = fmt::format("{}.{}.{}", BACKEND_VERSION_MAJOR, BACKEND_VERSION_MINOR, BACKEND_VERSION_PATCH);
|
59
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("backend")), rb_str_freeze(rb_str_new(ver.c_str(), static_cast<long>(ver.size()))));
|
60
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("build_timestamp")), rb_str_freeze(rb_str_new_cstr(BACKEND_BUILD_TIMESTAMP)));
|
61
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("revision")), rb_str_freeze(rb_str_new_cstr(BACKEND_GIT_REVISION)));
|
62
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("platform")), rb_str_freeze(rb_str_new_cstr(BACKEND_SYSTEM)));
|
63
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("cpu")), rb_str_freeze(rb_str_new_cstr(BACKEND_SYSTEM_PROCESSOR)));
|
64
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("cc")), rb_str_freeze(rb_str_new_cstr(BACKEND_C_COMPILER)));
|
65
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("cxx")), rb_str_freeze(rb_str_new_cstr(BACKEND_CXX_COMPILER)));
|
66
|
+
#if defined(HAVE_RUBY_VERSION_H)
|
67
|
+
ver = fmt::format("{}.{}.{}", RUBY_API_VERSION_MAJOR, RUBY_API_VERSION_MINOR, RUBY_API_VERSION_TEENY);
|
68
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("ruby")), rb_str_freeze(rb_str_new(ver.c_str(), static_cast<long>(ver.size()))));
|
69
|
+
#endif
|
53
70
|
ver = fmt::format("{}.{}.{}", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH);
|
54
71
|
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("spdlog")), rb_str_freeze(rb_str_new(ver.c_str(), static_cast<long>(ver.size()))));
|
55
72
|
ver = fmt::format("{}.{}.{}", VERSION_SPLIT_(ASIO_VERSION));
|
56
73
|
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("asio")), rb_str_freeze(rb_str_new(ver.c_str(), static_cast<long>(ver.size()))));
|
74
|
+
ver = fmt::format("{}.{}.{}", SNAPPY_MAJOR, SNAPPY_MINOR, SNAPPY_PATCHLEVEL);
|
75
|
+
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("snappy")), rb_str_freeze(rb_str_new(ver.c_str(), static_cast<long>(ver.size()))));
|
57
76
|
ver = fmt::format("{}.{}.{}", HTTP_PARSER_VERSION_MAJOR, HTTP_PARSER_VERSION_MINOR, HTTP_PARSER_VERSION_PATCH);
|
58
77
|
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("http_parser")), rb_str_freeze(rb_str_new(ver.c_str(), static_cast<long>(ver.size()))));
|
59
|
-
ver = fmt::format("{}.{}.{}", BACKEND_VERSION_MAJOR, BACKEND_VERSION_MINOR, BACKEND_VERSION_PATCH);
|
60
|
-
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("backend")), rb_str_freeze(rb_str_new(ver.c_str(), static_cast<long>(ver.size()))));
|
61
78
|
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("openssl_headers")), rb_str_freeze(rb_str_new_cstr(OPENSSL_VERSION_TEXT)));
|
62
79
|
#if defined(OPENSSL_VERSION)
|
63
80
|
rb_hash_aset(cb_Version, rb_id2sym(rb_intern("openssl_runtime")), rb_str_freeze(rb_str_new_cstr(OpenSSL_version(OPENSSL_VERSION))));
|
@@ -78,6 +95,10 @@ static void
|
|
78
95
|
cb__backend_close(cb_backend_data* backend)
|
79
96
|
{
|
80
97
|
if (backend->cluster) {
|
98
|
+
auto barrier = std::make_shared<std::promise<void>>();
|
99
|
+
auto f = barrier->get_future();
|
100
|
+
backend->cluster->close([barrier]() { barrier->set_value(); });
|
101
|
+
f.wait();
|
81
102
|
backend->cluster.reset(nullptr);
|
82
103
|
if (backend->worker.joinable()) {
|
83
104
|
backend->worker.join();
|
@@ -202,70 +223,71 @@ static VALUE eXattrUnknownVirtualAttribute;
|
|
202
223
|
static void
|
203
224
|
init_exceptions(VALUE mCouchbase)
|
204
225
|
{
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
226
|
+
VALUE mError = rb_define_module_under(mCouchbase, "Error");
|
227
|
+
eBackendError = rb_define_class_under(mError, "BackendError", rb_eStandardError);
|
228
|
+
eAmbiguousTimeout = rb_define_class_under(mError, "AmbiguousTimeout", rb_eStandardError);
|
229
|
+
eAuthenticationFailure = rb_define_class_under(mError, "AuthenticationFailure", rb_eStandardError);
|
230
|
+
eBucketExists = rb_define_class_under(mError, "BucketExists", rb_eStandardError);
|
231
|
+
eBucketNotFlushable = rb_define_class_under(mError, "BucketNotFlushable", rb_eStandardError);
|
232
|
+
eBucketNotFound = rb_define_class_under(mError, "BucketNotFound", rb_eStandardError);
|
233
|
+
eCasMismatch = rb_define_class_under(mError, "CasMismatch", rb_eStandardError);
|
234
|
+
eCollectionExists = rb_define_class_under(mError, "CollectionExists", rb_eStandardError);
|
235
|
+
eCollectionNotFound = rb_define_class_under(mError, "CollectionNotFound", rb_eStandardError);
|
236
|
+
eCompilationFailure = rb_define_class_under(mError, "CompilationFailure", rb_eStandardError);
|
237
|
+
eDatasetExists = rb_define_class_under(mError, "DatasetExists", rb_eStandardError);
|
238
|
+
eDatasetNotFound = rb_define_class_under(mError, "DatasetNotFound", rb_eStandardError);
|
239
|
+
eDataverseExists = rb_define_class_under(mError, "DataverseExists", rb_eStandardError);
|
240
|
+
eDataverseNotFound = rb_define_class_under(mError, "DataverseNotFound", rb_eStandardError);
|
241
|
+
eDecodingFailure = rb_define_class_under(mError, "DecodingFailure", rb_eStandardError);
|
242
|
+
eDeltaInvalid = rb_define_class_under(mError, "DeltaInvalid", rb_eStandardError);
|
243
|
+
eDesignDocumentNotFound = rb_define_class_under(mError, "DesignDocumentNotFound", rb_eStandardError);
|
244
|
+
eDocumentExists = rb_define_class_under(mError, "DocumentExists", rb_eStandardError);
|
245
|
+
eDocumentIrretrievable = rb_define_class_under(mError, "DocumentIrretrievable", rb_eStandardError);
|
246
|
+
eDocumentLocked = rb_define_class_under(mError, "DocumentLocked", rb_eStandardError);
|
247
|
+
eDocumentNotFound = rb_define_class_under(mError, "DocumentNotFound", rb_eStandardError);
|
248
|
+
eDocumentNotJson = rb_define_class_under(mError, "DocumentNotJson", rb_eStandardError);
|
249
|
+
eDurabilityAmbiguous = rb_define_class_under(mError, "DurabilityAmbiguous", rb_eStandardError);
|
250
|
+
eDurabilityImpossible = rb_define_class_under(mError, "DurabilityImpossible", rb_eStandardError);
|
251
|
+
eDurabilityLevelNotAvailable = rb_define_class_under(mError, "DurabilityLevelNotAvailable", rb_eStandardError);
|
252
|
+
eDurableWriteInProgress = rb_define_class_under(mError, "DurableWriteInProgress", rb_eStandardError);
|
253
|
+
eDurableWriteReCommitInProgress = rb_define_class_under(mError, "DurableWriteReCommitInProgress", rb_eStandardError);
|
254
|
+
eEncodingFailure = rb_define_class_under(mError, "EncodingFailure", rb_eStandardError);
|
255
|
+
eFeatureNotAvailable = rb_define_class_under(mError, "FeatureNotAvailable", rb_eStandardError);
|
256
|
+
eGroupNotFound = rb_define_class_under(mError, "GroupNotFound", rb_eStandardError);
|
257
|
+
eIndexExists = rb_define_class_under(mError, "IndexExists", rb_eStandardError);
|
258
|
+
eIndexFailure = rb_define_class_under(mError, "IndexFailure", rb_eStandardError);
|
259
|
+
eIndexNotFound = rb_define_class_under(mError, "IndexNotFound", rb_eStandardError);
|
260
|
+
eInternalServerFailure = rb_define_class_under(mError, "InternalServerFailure", rb_eStandardError);
|
261
|
+
eInvalidArgument = rb_define_class_under(mError, "InvalidArgument", rb_eStandardError);
|
262
|
+
eJobQueueFull = rb_define_class_under(mError, "JobQueueFull", rb_eStandardError);
|
263
|
+
eLinkNotFound = rb_define_class_under(mError, "LinkNotFound", rb_eStandardError);
|
264
|
+
eNumberTooBig = rb_define_class_under(mError, "NumberTooBig", rb_eStandardError);
|
265
|
+
eParsingFailure = rb_define_class_under(mError, "ParsingFailure", rb_eStandardError);
|
266
|
+
ePathExists = rb_define_class_under(mError, "PathExists", rb_eStandardError);
|
267
|
+
ePathInvalid = rb_define_class_under(mError, "PathInvalid", rb_eStandardError);
|
268
|
+
ePathMismatch = rb_define_class_under(mError, "PathMismatch", rb_eStandardError);
|
269
|
+
ePathNotFound = rb_define_class_under(mError, "PathNotFound", rb_eStandardError);
|
270
|
+
ePathTooBig = rb_define_class_under(mError, "PathTooBig", rb_eStandardError);
|
271
|
+
ePathTooDeep = rb_define_class_under(mError, "PathTooDeep", rb_eStandardError);
|
272
|
+
ePlanningFailure = rb_define_class_under(mError, "PlanningFailure", rb_eStandardError);
|
273
|
+
ePreparedStatementFailure = rb_define_class_under(mError, "PreparedStatementFailure", rb_eStandardError);
|
274
|
+
eRequestCanceled = rb_define_class_under(mError, "RequestCanceled", rb_eStandardError);
|
275
|
+
eScopeExists = rb_define_class_under(mError, "ScopeExists", rb_eStandardError);
|
276
|
+
eScopeNotFound = rb_define_class_under(mError, "ScopeNotFound", rb_eStandardError);
|
277
|
+
eServiceNotAvailable = rb_define_class_under(mError, "ServiceNotAvailable", rb_eStandardError);
|
278
|
+
eTemporaryFailure = rb_define_class_under(mError, "TemporaryFailure", rb_eStandardError);
|
279
|
+
eUnambiguousTimeout = rb_define_class_under(mError, "UnambiguousTimeout", rb_eStandardError);
|
280
|
+
eUnsupportedOperation = rb_define_class_under(mError, "UnsupportedOperation", rb_eStandardError);
|
281
|
+
eUserNotFound = rb_define_class_under(mError, "UserNotFound", rb_eStandardError);
|
282
|
+
eUserExists = rb_define_class_under(mError, "UserExists", rb_eStandardError);
|
283
|
+
eValueInvalid = rb_define_class_under(mError, "ValueInvalid", rb_eStandardError);
|
284
|
+
eValueTooDeep = rb_define_class_under(mError, "ValueTooDeep", rb_eStandardError);
|
285
|
+
eValueTooLarge = rb_define_class_under(mError, "ValueTooLarge", rb_eStandardError);
|
286
|
+
eViewNotFound = rb_define_class_under(mError, "ViewNotFound", rb_eStandardError);
|
287
|
+
eXattrCannotModifyVirtualAttribute = rb_define_class_under(mError, "XattrCannotModifyVirtualAttribute", rb_eStandardError);
|
288
|
+
eXattrInvalidKeyCombo = rb_define_class_under(mError, "XattrInvalidKeyCombo", rb_eStandardError);
|
289
|
+
eXattrUnknownMacro = rb_define_class_under(mError, "XattrUnknownMacro", rb_eStandardError);
|
290
|
+
eXattrUnknownVirtualAttribute = rb_define_class_under(mError, "XattrUnknownVirtualAttribute", rb_eStandardError);
|
269
291
|
}
|
270
292
|
|
271
293
|
static NORETURN(void cb_raise_error_code(std::error_code ec, const std::string& message))
|
@@ -498,7 +520,7 @@ cb_Backend_open(VALUE self, VALUE hostname, VALUE username, VALUE password)
|
|
498
520
|
auto f = barrier->get_future();
|
499
521
|
backend->cluster->open(options, [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
|
500
522
|
if (auto ec = f.get()) {
|
501
|
-
cb_raise_error_code(ec, "unable open cluster");
|
523
|
+
cb_raise_error_code(ec, fmt::format("unable open cluster at {}", options.hostname));
|
502
524
|
}
|
503
525
|
|
504
526
|
return Qnil;
|
@@ -530,14 +552,14 @@ cb_Backend_open_bucket(VALUE self, VALUE bucket)
|
|
530
552
|
auto f = barrier->get_future();
|
531
553
|
backend->cluster->open_bucket(name, [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
|
532
554
|
if (auto ec = f.get()) {
|
533
|
-
cb_raise_error_code(ec, "unable open
|
555
|
+
cb_raise_error_code(ec, fmt::format("unable open bucket \"{}\"", name));
|
534
556
|
}
|
535
557
|
|
536
558
|
return Qtrue;
|
537
559
|
}
|
538
560
|
|
539
561
|
static VALUE
|
540
|
-
|
562
|
+
cb_Backend_document_get(VALUE self, VALUE bucket, VALUE collection, VALUE id)
|
541
563
|
{
|
542
564
|
cb_backend_data* backend = nullptr;
|
543
565
|
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
@@ -550,15 +572,15 @@ cb_Backend_get(VALUE self, VALUE bucket, VALUE collection, VALUE id)
|
|
550
572
|
Check_Type(collection, T_STRING);
|
551
573
|
Check_Type(id, T_STRING);
|
552
574
|
|
553
|
-
couchbase::
|
575
|
+
couchbase::document_id doc_id;
|
554
576
|
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
555
577
|
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
556
578
|
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
557
579
|
|
580
|
+
couchbase::operations::get_request req{ doc_id };
|
558
581
|
auto barrier = std::make_shared<std::promise<couchbase::operations::get_response>>();
|
559
582
|
auto f = barrier->get_future();
|
560
|
-
backend->cluster->execute(couchbase::operations::
|
561
|
-
[barrier](couchbase::operations::get_response resp) mutable { barrier->set_value(resp); });
|
583
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::get_response resp) mutable { barrier->set_value(resp); });
|
562
584
|
auto resp = f.get();
|
563
585
|
if (resp.ec) {
|
564
586
|
cb_raise_error_code(resp.ec, fmt::format("unable fetch {}", doc_id));
|
@@ -566,12 +588,13 @@ cb_Backend_get(VALUE self, VALUE bucket, VALUE collection, VALUE id)
|
|
566
588
|
|
567
589
|
VALUE res = rb_hash_new();
|
568
590
|
rb_hash_aset(res, rb_id2sym(rb_intern("content")), rb_str_new(resp.value.data(), static_cast<long>(resp.value.size())));
|
569
|
-
rb_hash_aset(res, rb_id2sym(rb_intern("cas")),
|
591
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
592
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("flags")), UINT2NUM(resp.flags));
|
570
593
|
return res;
|
571
594
|
}
|
572
595
|
|
573
596
|
static VALUE
|
574
|
-
|
597
|
+
cb_Backend_document_get_and_lock(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE lock_time)
|
575
598
|
{
|
576
599
|
cb_backend_data* backend = nullptr;
|
577
600
|
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
@@ -583,29 +606,33 @@ cb_Backend_upsert(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE co
|
|
583
606
|
Check_Type(bucket, T_STRING);
|
584
607
|
Check_Type(collection, T_STRING);
|
585
608
|
Check_Type(id, T_STRING);
|
609
|
+
Check_Type(lock_time, T_FIXNUM);
|
586
610
|
|
587
|
-
couchbase::
|
611
|
+
couchbase::document_id doc_id;
|
588
612
|
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
589
613
|
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
590
614
|
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
591
|
-
std::string value(RSTRING_PTR(content), static_cast<size_t>(RSTRING_LEN(content)));
|
592
615
|
|
593
|
-
|
616
|
+
couchbase::operations::get_and_lock_request req{ doc_id };
|
617
|
+
req.lock_time = NUM2UINT(lock_time);
|
618
|
+
|
619
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::get_and_lock_response>>();
|
594
620
|
auto f = barrier->get_future();
|
595
|
-
backend->cluster->execute(couchbase::operations::
|
596
|
-
[barrier](couchbase::operations::upsert_response resp) mutable { barrier->set_value(resp); });
|
621
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::get_and_lock_response resp) mutable { barrier->set_value(resp); });
|
597
622
|
auto resp = f.get();
|
598
623
|
if (resp.ec) {
|
599
|
-
cb_raise_error_code(resp.ec, fmt::format("unable
|
624
|
+
cb_raise_error_code(resp.ec, fmt::format("unable lock and fetch {}", doc_id));
|
600
625
|
}
|
601
626
|
|
602
627
|
VALUE res = rb_hash_new();
|
603
|
-
rb_hash_aset(res, rb_id2sym(rb_intern("
|
628
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("content")), rb_str_new(resp.value.data(), static_cast<long>(resp.value.size())));
|
629
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
630
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("flags")), UINT2NUM(resp.flags));
|
604
631
|
return res;
|
605
632
|
}
|
606
633
|
|
607
634
|
static VALUE
|
608
|
-
|
635
|
+
cb_Backend_document_get_and_touch(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE expiration)
|
609
636
|
{
|
610
637
|
cb_backend_data* backend = nullptr;
|
611
638
|
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
@@ -617,128 +644,319 @@ cb_Backend_remove(VALUE self, VALUE bucket, VALUE collection, VALUE id)
|
|
617
644
|
Check_Type(bucket, T_STRING);
|
618
645
|
Check_Type(collection, T_STRING);
|
619
646
|
Check_Type(id, T_STRING);
|
647
|
+
Check_Type(expiration, T_FIXNUM);
|
620
648
|
|
621
|
-
couchbase::
|
649
|
+
couchbase::document_id doc_id;
|
622
650
|
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
623
651
|
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
624
652
|
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
625
653
|
|
626
|
-
|
654
|
+
couchbase::operations::get_and_touch_request req{ doc_id };
|
655
|
+
req.expiration = NUM2UINT(expiration);
|
656
|
+
|
657
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::get_and_touch_response>>();
|
627
658
|
auto f = barrier->get_future();
|
628
|
-
backend->cluster->execute(couchbase::operations::
|
629
|
-
[barrier](couchbase::operations::remove_response resp) mutable { barrier->set_value(resp); });
|
659
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::get_and_touch_response resp) mutable { barrier->set_value(resp); });
|
630
660
|
auto resp = f.get();
|
631
661
|
if (resp.ec) {
|
632
|
-
cb_raise_error_code(resp.ec, fmt::format("unable
|
662
|
+
cb_raise_error_code(resp.ec, fmt::format("unable fetch and touch {}", doc_id));
|
633
663
|
}
|
634
664
|
|
635
665
|
VALUE res = rb_hash_new();
|
636
|
-
rb_hash_aset(res, rb_id2sym(rb_intern("
|
666
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("content")), rb_str_new(resp.value.data(), static_cast<long>(resp.value.size())));
|
667
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
668
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("flags")), UINT2NUM(resp.flags));
|
637
669
|
return res;
|
638
670
|
}
|
639
671
|
|
672
|
+
template<typename Response>
|
640
673
|
static VALUE
|
641
|
-
|
674
|
+
cb__extract_mutation_result(Response resp)
|
642
675
|
{
|
643
|
-
|
644
|
-
|
645
|
-
|
676
|
+
VALUE res = rb_hash_new();
|
677
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
678
|
+
VALUE token = rb_hash_new();
|
679
|
+
rb_hash_aset(token, rb_id2sym(rb_intern("partition_uuid")), ULL2NUM(resp.token.partition_uuid));
|
680
|
+
rb_hash_aset(token, rb_id2sym(rb_intern("sequence_number")), ULONG2NUM(resp.token.sequence_number));
|
681
|
+
rb_hash_aset(token, rb_id2sym(rb_intern("partition_id")), UINT2NUM(resp.token.partition_id));
|
682
|
+
rb_hash_aset(token,
|
683
|
+
rb_id2sym(rb_intern("bucket_name")),
|
684
|
+
rb_str_new(resp.token.bucket_name.c_str(), static_cast<long>(resp.token.bucket_name.size())));
|
685
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("mutation_token")), token);
|
686
|
+
return res;
|
687
|
+
}
|
646
688
|
|
647
|
-
|
648
|
-
|
689
|
+
static VALUE
|
690
|
+
cb_Backend_document_touch(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE expiration)
|
691
|
+
{
|
692
|
+
cb_backend_data* backend = nullptr;
|
693
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
649
694
|
|
650
|
-
|
651
|
-
|
695
|
+
if (!backend->cluster) {
|
696
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
697
|
+
}
|
652
698
|
|
653
|
-
|
654
|
-
|
699
|
+
Check_Type(bucket, T_STRING);
|
700
|
+
Check_Type(collection, T_STRING);
|
701
|
+
Check_Type(id, T_STRING);
|
702
|
+
Check_Type(expiration, T_FIXNUM);
|
655
703
|
|
656
|
-
|
657
|
-
|
704
|
+
couchbase::document_id doc_id;
|
705
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
706
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
707
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
658
708
|
|
659
|
-
|
660
|
-
|
709
|
+
couchbase::operations::touch_request req{ doc_id };
|
710
|
+
req.expiration = NUM2UINT(expiration);
|
661
711
|
|
662
|
-
|
663
|
-
|
712
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::touch_response>>();
|
713
|
+
auto f = barrier->get_future();
|
714
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::touch_response resp) mutable { barrier->set_value(resp); });
|
715
|
+
auto resp = f.get();
|
716
|
+
if (resp.ec) {
|
717
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to touch {}", doc_id));
|
718
|
+
}
|
664
719
|
|
665
|
-
|
666
|
-
|
720
|
+
VALUE res = rb_hash_new();
|
721
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
722
|
+
return res;
|
723
|
+
}
|
667
724
|
|
668
|
-
|
669
|
-
|
725
|
+
static VALUE
|
726
|
+
cb_Backend_document_exists(VALUE self, VALUE bucket, VALUE collection, VALUE id)
|
727
|
+
{
|
728
|
+
cb_backend_data* backend = nullptr;
|
729
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
670
730
|
|
671
|
-
|
672
|
-
|
731
|
+
if (!backend->cluster) {
|
732
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
733
|
+
}
|
673
734
|
|
674
|
-
|
675
|
-
|
735
|
+
Check_Type(bucket, T_STRING);
|
736
|
+
Check_Type(collection, T_STRING);
|
737
|
+
Check_Type(id, T_STRING);
|
676
738
|
|
677
|
-
|
678
|
-
|
739
|
+
couchbase::document_id doc_id;
|
740
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
741
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
742
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
743
|
+
|
744
|
+
couchbase::operations::exists_request req{ doc_id };
|
745
|
+
|
746
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::exists_response>>();
|
747
|
+
auto f = barrier->get_future();
|
748
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::exists_response resp) mutable { barrier->set_value(resp); });
|
749
|
+
auto resp = f.get();
|
750
|
+
if (resp.ec) {
|
751
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to exists {}", doc_id));
|
679
752
|
}
|
680
|
-
|
753
|
+
|
754
|
+
VALUE res = rb_hash_new();
|
755
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
756
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("partition_id")), UINT2NUM(resp.partition_id));
|
757
|
+
switch (resp.status) {
|
758
|
+
case couchbase::operations::exists_response::observe_status::invalid:
|
759
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_id2sym(rb_intern("invalid")));
|
760
|
+
break;
|
761
|
+
case couchbase::operations::exists_response::observe_status::found:
|
762
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_id2sym(rb_intern("found")));
|
763
|
+
break;
|
764
|
+
case couchbase::operations::exists_response::observe_status::not_found:
|
765
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_id2sym(rb_intern("not_found")));
|
766
|
+
break;
|
767
|
+
case couchbase::operations::exists_response::observe_status::persisted:
|
768
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_id2sym(rb_intern("persisted")));
|
769
|
+
break;
|
770
|
+
case couchbase::operations::exists_response::observe_status::logically_deleted:
|
771
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_id2sym(rb_intern("logically_deleted")));
|
772
|
+
break;
|
773
|
+
}
|
774
|
+
return res;
|
681
775
|
}
|
682
776
|
|
683
777
|
static VALUE
|
684
|
-
|
778
|
+
cb_Backend_document_unlock(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE cas)
|
685
779
|
{
|
686
|
-
|
687
|
-
|
688
|
-
return rb_id2sym(rb_intern("success"));
|
780
|
+
cb_backend_data* backend = nullptr;
|
781
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
689
782
|
|
690
|
-
|
691
|
-
|
783
|
+
if (!backend->cluster) {
|
784
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
785
|
+
}
|
692
786
|
|
693
|
-
|
694
|
-
|
787
|
+
Check_Type(bucket, T_STRING);
|
788
|
+
Check_Type(collection, T_STRING);
|
789
|
+
Check_Type(id, T_STRING);
|
695
790
|
|
696
|
-
|
697
|
-
|
791
|
+
couchbase::document_id doc_id;
|
792
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
793
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
794
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
698
795
|
|
699
|
-
|
700
|
-
|
796
|
+
couchbase::operations::unlock_request req{ doc_id };
|
797
|
+
switch (TYPE(cas)) {
|
798
|
+
case T_FIXNUM:
|
799
|
+
case T_BIGNUM:
|
800
|
+
req.cas = NUM2ULL(cas);
|
801
|
+
break;
|
802
|
+
default:
|
803
|
+
rb_raise(rb_eArgError, "CAS must be an Integer");
|
804
|
+
}
|
701
805
|
|
702
|
-
|
703
|
-
|
806
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::unlock_response>>();
|
807
|
+
auto f = barrier->get_future();
|
808
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::unlock_response resp) mutable { barrier->set_value(resp); });
|
809
|
+
auto resp = f.get();
|
810
|
+
if (resp.ec) {
|
811
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to unlock {}", doc_id));
|
812
|
+
}
|
704
813
|
|
705
|
-
|
706
|
-
|
814
|
+
VALUE res = rb_hash_new();
|
815
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
816
|
+
return res;
|
817
|
+
}
|
707
818
|
|
708
|
-
|
709
|
-
|
819
|
+
static VALUE
|
820
|
+
cb_Backend_document_upsert(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE content, VALUE flags, VALUE options)
|
821
|
+
{
|
822
|
+
cb_backend_data* backend = nullptr;
|
823
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
710
824
|
|
711
|
-
|
712
|
-
|
825
|
+
if (!backend->cluster) {
|
826
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
827
|
+
}
|
713
828
|
|
714
|
-
|
715
|
-
|
829
|
+
Check_Type(bucket, T_STRING);
|
830
|
+
Check_Type(collection, T_STRING);
|
831
|
+
Check_Type(id, T_STRING);
|
832
|
+
Check_Type(content, T_STRING);
|
833
|
+
Check_Type(flags, T_FIXNUM);
|
716
834
|
|
717
|
-
|
718
|
-
|
835
|
+
couchbase::document_id doc_id;
|
836
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
837
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
838
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
839
|
+
std::string value(RSTRING_PTR(content), static_cast<size_t>(RSTRING_LEN(content)));
|
719
840
|
|
720
|
-
|
721
|
-
|
841
|
+
couchbase::operations::upsert_request req{ doc_id, value };
|
842
|
+
req.flags = FIX2UINT(flags);
|
843
|
+
|
844
|
+
if (!NIL_P(options)) {
|
845
|
+
Check_Type(options, T_HASH);
|
846
|
+
VALUE durability_level = rb_hash_aref(options, rb_id2sym(rb_intern("durability_level")));
|
847
|
+
if (!NIL_P(durability_level)) {
|
848
|
+
Check_Type(durability_level, T_SYMBOL);
|
849
|
+
ID level = rb_sym2id(durability_level);
|
850
|
+
if (level == rb_intern("none")) {
|
851
|
+
req.durability_level = couchbase::protocol::durability_level::none;
|
852
|
+
} else if (level == rb_intern("majority_and_persist_to_active")) {
|
853
|
+
req.durability_level = couchbase::protocol::durability_level::majority_and_persist_to_active;
|
854
|
+
} else if (level == rb_intern("persist_to_majority")) {
|
855
|
+
req.durability_level = couchbase::protocol::durability_level::persist_to_majority;
|
856
|
+
} else {
|
857
|
+
rb_raise(rb_eArgError, "Unknown durability level");
|
858
|
+
}
|
859
|
+
VALUE durability_timeout = rb_hash_aref(options, rb_id2sym(rb_intern("durability_timeout")));
|
860
|
+
if (!NIL_P(durability_timeout)) {
|
861
|
+
Check_Type(durability_timeout, T_FIXNUM);
|
862
|
+
req.durability_timeout = FIX2UINT(durability_timeout);
|
863
|
+
}
|
864
|
+
}
|
865
|
+
VALUE expiration = rb_hash_aref(options, rb_id2sym(rb_intern("expiration")));
|
866
|
+
if (!NIL_P(expiration)) {
|
867
|
+
Check_Type(expiration, T_FIXNUM);
|
868
|
+
req.expiration = FIX2UINT(expiration);
|
869
|
+
}
|
870
|
+
}
|
722
871
|
|
723
|
-
|
724
|
-
|
872
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::upsert_response>>();
|
873
|
+
auto f = barrier->get_future();
|
874
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::upsert_response resp) mutable { barrier->set_value(resp); });
|
875
|
+
auto resp = f.get();
|
876
|
+
if (resp.ec) {
|
877
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to upsert {}", doc_id));
|
878
|
+
}
|
725
879
|
|
726
|
-
|
727
|
-
|
880
|
+
return cb__extract_mutation_result(resp);
|
881
|
+
}
|
728
882
|
|
729
|
-
|
730
|
-
|
883
|
+
static VALUE
|
884
|
+
cb_Backend_document_replace(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE content, VALUE flags, VALUE options)
|
885
|
+
{
|
886
|
+
cb_backend_data* backend = nullptr;
|
887
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
731
888
|
|
732
|
-
|
733
|
-
|
889
|
+
if (!backend->cluster) {
|
890
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
891
|
+
}
|
734
892
|
|
735
|
-
|
736
|
-
|
893
|
+
Check_Type(bucket, T_STRING);
|
894
|
+
Check_Type(collection, T_STRING);
|
895
|
+
Check_Type(id, T_STRING);
|
896
|
+
Check_Type(content, T_STRING);
|
897
|
+
Check_Type(flags, T_FIXNUM);
|
898
|
+
|
899
|
+
couchbase::document_id doc_id;
|
900
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
901
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
902
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
903
|
+
std::string value(RSTRING_PTR(content), static_cast<size_t>(RSTRING_LEN(content)));
|
904
|
+
|
905
|
+
couchbase::operations::replace_request req{ doc_id, value };
|
906
|
+
req.flags = FIX2UINT(flags);
|
907
|
+
|
908
|
+
if (!NIL_P(options)) {
|
909
|
+
Check_Type(options, T_HASH);
|
910
|
+
VALUE durability_level = rb_hash_aref(options, rb_id2sym(rb_intern("durability_level")));
|
911
|
+
if (!NIL_P(durability_level)) {
|
912
|
+
Check_Type(durability_level, T_SYMBOL);
|
913
|
+
ID level = rb_sym2id(durability_level);
|
914
|
+
if (level == rb_intern("none")) {
|
915
|
+
req.durability_level = couchbase::protocol::durability_level::none;
|
916
|
+
} else if (level == rb_intern("majority_and_persist_to_active")) {
|
917
|
+
req.durability_level = couchbase::protocol::durability_level::majority_and_persist_to_active;
|
918
|
+
} else if (level == rb_intern("persist_to_majority")) {
|
919
|
+
req.durability_level = couchbase::protocol::durability_level::persist_to_majority;
|
920
|
+
} else {
|
921
|
+
rb_raise(rb_eArgError, "Unknown durability level");
|
922
|
+
}
|
923
|
+
VALUE durability_timeout = rb_hash_aref(options, rb_id2sym(rb_intern("durability_timeout")));
|
924
|
+
if (!NIL_P(durability_timeout)) {
|
925
|
+
Check_Type(durability_timeout, T_FIXNUM);
|
926
|
+
req.durability_timeout = FIX2UINT(durability_timeout);
|
927
|
+
}
|
928
|
+
}
|
929
|
+
VALUE expiration = rb_hash_aref(options, rb_id2sym(rb_intern("expiration")));
|
930
|
+
if (!NIL_P(expiration)) {
|
931
|
+
Check_Type(expiration, T_FIXNUM);
|
932
|
+
req.expiration = FIX2UINT(expiration);
|
933
|
+
}
|
934
|
+
VALUE cas = rb_hash_aref(options, rb_id2sym(rb_intern("cas")));
|
935
|
+
if (!NIL_P(cas)) {
|
936
|
+
switch (TYPE(cas)) {
|
937
|
+
case T_FIXNUM:
|
938
|
+
case T_BIGNUM:
|
939
|
+
req.cas = NUM2ULL(cas);
|
940
|
+
break;
|
941
|
+
default:
|
942
|
+
rb_raise(rb_eArgError, "CAS must be an Integer");
|
943
|
+
}
|
944
|
+
}
|
945
|
+
}
|
946
|
+
|
947
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::replace_response>>();
|
948
|
+
auto f = barrier->get_future();
|
949
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::replace_response resp) mutable { barrier->set_value(resp); });
|
950
|
+
auto resp = f.get();
|
951
|
+
if (resp.ec) {
|
952
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to replace {}", doc_id));
|
737
953
|
}
|
954
|
+
|
955
|
+
return cb__extract_mutation_result(resp);
|
738
956
|
}
|
739
957
|
|
740
958
|
static VALUE
|
741
|
-
|
959
|
+
cb_Backend_document_insert(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE content, VALUE flags, VALUE options)
|
742
960
|
{
|
743
961
|
cb_backend_data* backend = nullptr;
|
744
962
|
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
@@ -750,74 +968,59 @@ cb_Backend_lookup_in(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE
|
|
750
968
|
Check_Type(bucket, T_STRING);
|
751
969
|
Check_Type(collection, T_STRING);
|
752
970
|
Check_Type(id, T_STRING);
|
753
|
-
Check_Type(
|
754
|
-
|
755
|
-
rb_raise(rb_eArgError, "Array with specs cannot be empty");
|
756
|
-
}
|
971
|
+
Check_Type(content, T_STRING);
|
972
|
+
Check_Type(flags, T_FIXNUM);
|
757
973
|
|
758
|
-
couchbase::
|
974
|
+
couchbase::document_id doc_id;
|
759
975
|
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
760
976
|
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
761
977
|
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
978
|
+
std::string value(RSTRING_PTR(content), static_cast<size_t>(RSTRING_LEN(content)));
|
762
979
|
|
763
|
-
couchbase::operations::
|
764
|
-
req.
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
VALUE
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
980
|
+
couchbase::operations::insert_request req{ doc_id, value };
|
981
|
+
req.flags = FIX2UINT(flags);
|
982
|
+
|
983
|
+
if (!NIL_P(options)) {
|
984
|
+
Check_Type(options, T_HASH);
|
985
|
+
VALUE durability_level = rb_hash_aref(options, rb_id2sym(rb_intern("durability_level")));
|
986
|
+
if (!NIL_P(durability_level)) {
|
987
|
+
Check_Type(durability_level, T_SYMBOL);
|
988
|
+
ID level = rb_sym2id(durability_level);
|
989
|
+
if (level == rb_intern("none")) {
|
990
|
+
req.durability_level = couchbase::protocol::durability_level::none;
|
991
|
+
} else if (level == rb_intern("majority_and_persist_to_active")) {
|
992
|
+
req.durability_level = couchbase::protocol::durability_level::majority_and_persist_to_active;
|
993
|
+
} else if (level == rb_intern("persist_to_majority")) {
|
994
|
+
req.durability_level = couchbase::protocol::durability_level::persist_to_majority;
|
995
|
+
} else {
|
996
|
+
rb_raise(rb_eArgError, "Unknown durability level");
|
997
|
+
}
|
998
|
+
VALUE durability_timeout = rb_hash_aref(options, rb_id2sym(rb_intern("durability_timeout")));
|
999
|
+
if (!NIL_P(durability_timeout)) {
|
1000
|
+
Check_Type(durability_timeout, T_FIXNUM);
|
1001
|
+
req.durability_timeout = FIX2UINT(durability_timeout);
|
1002
|
+
}
|
1003
|
+
}
|
1004
|
+
VALUE expiration = rb_hash_aref(options, rb_id2sym(rb_intern("expiration")));
|
1005
|
+
if (!NIL_P(expiration)) {
|
1006
|
+
Check_Type(expiration, T_FIXNUM);
|
1007
|
+
req.expiration = FIX2UINT(expiration);
|
782
1008
|
}
|
783
|
-
bool xattr = RTEST(rb_hash_aref(entry, rb_id2sym(rb_intern("xattr"))));
|
784
|
-
VALUE path = rb_hash_aref(entry, rb_id2sym(rb_intern("path")));
|
785
|
-
Check_Type(path, T_STRING);
|
786
|
-
req.specs.add_spec(opcode, xattr, std::string(RSTRING_PTR(path), static_cast<size_t>(RSTRING_LEN(path))));
|
787
1009
|
}
|
788
1010
|
|
789
|
-
auto barrier = std::make_shared<std::promise<couchbase::operations::
|
1011
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::insert_response>>();
|
790
1012
|
auto f = barrier->get_future();
|
791
|
-
backend->cluster->execute(req, [barrier](couchbase::operations::
|
1013
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::insert_response resp) mutable { barrier->set_value(resp); });
|
792
1014
|
auto resp = f.get();
|
793
1015
|
if (resp.ec) {
|
794
|
-
cb_raise_error_code(resp.ec, fmt::format("unable
|
1016
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to insert {}", doc_id));
|
795
1017
|
}
|
796
1018
|
|
797
|
-
|
798
|
-
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULONG2NUM(resp.cas));
|
799
|
-
VALUE fields = rb_ary_new_capa(static_cast<long>(resp.fields.size()));
|
800
|
-
rb_hash_aset(res, rb_id2sym(rb_intern("fields")), fields);
|
801
|
-
for (size_t i = 0; i < resp.fields.size(); ++i) {
|
802
|
-
VALUE entry = rb_hash_new();
|
803
|
-
rb_hash_aset(entry, rb_id2sym(rb_intern("exists")), resp.fields[i].exists ? Qtrue : Qfalse);
|
804
|
-
rb_hash_aset(
|
805
|
-
entry, rb_id2sym(rb_intern("path")), rb_str_new(resp.fields[i].path.data(), static_cast<long>(resp.fields[i].path.size())));
|
806
|
-
rb_hash_aset(
|
807
|
-
entry, rb_id2sym(rb_intern("value")), rb_str_new(resp.fields[i].value.data(), static_cast<long>(resp.fields[i].value.size())));
|
808
|
-
rb_hash_aset(entry, rb_id2sym(rb_intern("status")), cb__map_subdoc_status(resp.fields[i].status));
|
809
|
-
if (resp.fields[i].opcode == couchbase::protocol::subdoc_opcode::get && resp.fields[i].path.empty()) {
|
810
|
-
rb_hash_aset(entry, rb_id2sym(rb_intern("type")), rb_id2sym(rb_intern("get_doc")));
|
811
|
-
} else {
|
812
|
-
rb_hash_aset(entry, rb_id2sym(rb_intern("type")), cb__map_subdoc_opcode(resp.fields[i].opcode));
|
813
|
-
}
|
814
|
-
rb_ary_store(fields, static_cast<long>(i), entry);
|
815
|
-
}
|
816
|
-
return res;
|
1019
|
+
return cb__extract_mutation_result(resp);
|
817
1020
|
}
|
818
1021
|
|
819
1022
|
static VALUE
|
820
|
-
|
1023
|
+
cb_Backend_document_remove(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE options)
|
821
1024
|
{
|
822
1025
|
cb_backend_data* backend = nullptr;
|
823
1026
|
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
@@ -829,122 +1032,1414 @@ cb_Backend_mutate_in(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE
|
|
829
1032
|
Check_Type(bucket, T_STRING);
|
830
1033
|
Check_Type(collection, T_STRING);
|
831
1034
|
Check_Type(id, T_STRING);
|
832
|
-
Check_Type(specs, T_ARRAY);
|
833
|
-
if (RARRAY_LEN(specs) <= 0) {
|
834
|
-
rb_raise(rb_eArgError, "Array with specs cannot be empty");
|
835
|
-
}
|
836
1035
|
|
837
|
-
couchbase::
|
1036
|
+
couchbase::document_id doc_id;
|
838
1037
|
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
839
1038
|
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
840
1039
|
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
841
1040
|
|
842
|
-
couchbase::operations::
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
1041
|
+
couchbase::operations::remove_request req{ doc_id };
|
1042
|
+
if (!NIL_P(options)) {
|
1043
|
+
Check_Type(options, T_HASH);
|
1044
|
+
VALUE durability_level = rb_hash_aref(options, rb_id2sym(rb_intern("durability_level")));
|
1045
|
+
if (!NIL_P(durability_level)) {
|
1046
|
+
Check_Type(durability_level, T_SYMBOL);
|
1047
|
+
ID level = rb_sym2id(durability_level);
|
1048
|
+
if (level == rb_intern("none")) {
|
1049
|
+
req.durability_level = couchbase::protocol::durability_level::none;
|
1050
|
+
} else if (level == rb_intern("majority_and_persist_to_active")) {
|
1051
|
+
req.durability_level = couchbase::protocol::durability_level::majority_and_persist_to_active;
|
1052
|
+
} else if (level == rb_intern("persist_to_majority")) {
|
1053
|
+
req.durability_level = couchbase::protocol::durability_level::persist_to_majority;
|
1054
|
+
} else {
|
1055
|
+
rb_raise(rb_eArgError, "Unknown durability level");
|
1056
|
+
}
|
1057
|
+
VALUE durability_timeout = rb_hash_aref(options, rb_id2sym(rb_intern("durability_timeout")));
|
1058
|
+
if (!NIL_P(durability_timeout)) {
|
1059
|
+
Check_Type(durability_timeout, T_FIXNUM);
|
1060
|
+
req.durability_timeout = FIX2UINT(durability_timeout);
|
1061
|
+
}
|
1062
|
+
}
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::remove_response>>();
|
1066
|
+
auto f = barrier->get_future();
|
1067
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::remove_response resp) mutable { barrier->set_value(resp); });
|
1068
|
+
auto resp = f.get();
|
1069
|
+
if (resp.ec) {
|
1070
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to remove {}", doc_id));
|
1071
|
+
}
|
1072
|
+
return cb__extract_mutation_result(resp);
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
static VALUE
|
1076
|
+
cb_Backend_document_increment(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE options)
|
1077
|
+
{
|
1078
|
+
cb_backend_data* backend = nullptr;
|
1079
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1080
|
+
|
1081
|
+
if (!backend->cluster) {
|
1082
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
Check_Type(bucket, T_STRING);
|
1086
|
+
Check_Type(collection, T_STRING);
|
1087
|
+
Check_Type(id, T_STRING);
|
1088
|
+
|
1089
|
+
couchbase::document_id doc_id;
|
1090
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
1091
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
1092
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
1093
|
+
|
1094
|
+
couchbase::operations::increment_request req{ doc_id };
|
1095
|
+
if (!NIL_P(options)) {
|
1096
|
+
Check_Type(options, T_HASH);
|
1097
|
+
VALUE durability_level = rb_hash_aref(options, rb_id2sym(rb_intern("durability_level")));
|
1098
|
+
if (!NIL_P(durability_level)) {
|
1099
|
+
Check_Type(durability_level, T_SYMBOL);
|
1100
|
+
ID level = rb_sym2id(durability_level);
|
1101
|
+
if (level == rb_intern("none")) {
|
1102
|
+
req.durability_level = couchbase::protocol::durability_level::none;
|
1103
|
+
} else if (level == rb_intern("majority_and_persist_to_active")) {
|
1104
|
+
req.durability_level = couchbase::protocol::durability_level::majority_and_persist_to_active;
|
1105
|
+
} else if (level == rb_intern("persist_to_majority")) {
|
1106
|
+
req.durability_level = couchbase::protocol::durability_level::persist_to_majority;
|
1107
|
+
} else {
|
1108
|
+
rb_raise(rb_eArgError, "Unknown durability level");
|
1109
|
+
}
|
1110
|
+
VALUE durability_timeout = rb_hash_aref(options, rb_id2sym(rb_intern("durability_timeout")));
|
1111
|
+
if (!NIL_P(durability_timeout)) {
|
1112
|
+
Check_Type(durability_timeout, T_FIXNUM);
|
1113
|
+
req.durability_timeout = FIX2UINT(durability_timeout);
|
1114
|
+
}
|
1115
|
+
}
|
1116
|
+
VALUE delta = rb_hash_aref(options, rb_id2sym(rb_intern("delta")));
|
1117
|
+
if (!NIL_P(delta)) {
|
1118
|
+
switch (TYPE(delta)) {
|
1119
|
+
case T_FIXNUM:
|
1120
|
+
case T_BIGNUM:
|
1121
|
+
req.delta = NUM2ULL(delta);
|
1122
|
+
break;
|
1123
|
+
default:
|
1124
|
+
rb_raise(rb_eArgError, "delta must be an Integer");
|
1125
|
+
}
|
1126
|
+
}
|
1127
|
+
VALUE initial_value = rb_hash_aref(options, rb_id2sym(rb_intern("initial_value")));
|
1128
|
+
if (!NIL_P(initial_value)) {
|
1129
|
+
switch (TYPE(initial_value)) {
|
1130
|
+
case T_FIXNUM:
|
1131
|
+
case T_BIGNUM:
|
1132
|
+
req.initial_value = NUM2ULL(initial_value);
|
1133
|
+
break;
|
1134
|
+
default:
|
1135
|
+
rb_raise(rb_eArgError, "initial_value must be an Integer");
|
1136
|
+
}
|
1137
|
+
}
|
1138
|
+
VALUE expiration = rb_hash_aref(options, rb_id2sym(rb_intern("expiration")));
|
1139
|
+
if (!NIL_P(expiration)) {
|
1140
|
+
Check_Type(expiration, T_FIXNUM);
|
1141
|
+
req.expiration = FIX2UINT(expiration);
|
1142
|
+
}
|
1143
|
+
}
|
1144
|
+
|
1145
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::increment_response>>();
|
1146
|
+
auto f = barrier->get_future();
|
1147
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::increment_response resp) mutable { barrier->set_value(resp); });
|
1148
|
+
auto resp = f.get();
|
1149
|
+
if (resp.ec) {
|
1150
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to increment {} by {}", doc_id, req.delta));
|
1151
|
+
}
|
1152
|
+
VALUE res = cb__extract_mutation_result(resp);
|
1153
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("content")), ULL2NUM(resp.content));
|
1154
|
+
return res;
|
1155
|
+
}
|
1156
|
+
|
1157
|
+
static VALUE
|
1158
|
+
cb_Backend_document_decrement(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE options)
|
1159
|
+
{
|
1160
|
+
cb_backend_data* backend = nullptr;
|
1161
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1162
|
+
|
1163
|
+
if (!backend->cluster) {
|
1164
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1165
|
+
}
|
1166
|
+
|
1167
|
+
Check_Type(bucket, T_STRING);
|
1168
|
+
Check_Type(collection, T_STRING);
|
1169
|
+
Check_Type(id, T_STRING);
|
1170
|
+
Check_Type(options, T_HASH);
|
1171
|
+
|
1172
|
+
couchbase::document_id doc_id;
|
1173
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
1174
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
1175
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
1176
|
+
|
1177
|
+
couchbase::operations::decrement_request req{ doc_id };
|
1178
|
+
if (!NIL_P(options)) {
|
1179
|
+
Check_Type(options, T_HASH);
|
1180
|
+
VALUE durability_level = rb_hash_aref(options, rb_id2sym(rb_intern("durability_level")));
|
1181
|
+
if (!NIL_P(durability_level)) {
|
1182
|
+
Check_Type(durability_level, T_SYMBOL);
|
1183
|
+
ID level = rb_sym2id(durability_level);
|
1184
|
+
if (level == rb_intern("none")) {
|
1185
|
+
req.durability_level = couchbase::protocol::durability_level::none;
|
1186
|
+
} else if (level == rb_intern("majority_and_persist_to_active")) {
|
1187
|
+
req.durability_level = couchbase::protocol::durability_level::majority_and_persist_to_active;
|
1188
|
+
} else if (level == rb_intern("persist_to_majority")) {
|
1189
|
+
req.durability_level = couchbase::protocol::durability_level::persist_to_majority;
|
1190
|
+
} else {
|
1191
|
+
rb_raise(rb_eArgError, "Unknown durability level");
|
1192
|
+
}
|
1193
|
+
VALUE durability_timeout = rb_hash_aref(options, rb_id2sym(rb_intern("durability_timeout")));
|
1194
|
+
if (!NIL_P(durability_timeout)) {
|
1195
|
+
Check_Type(durability_timeout, T_FIXNUM);
|
1196
|
+
req.durability_timeout = FIX2UINT(durability_timeout);
|
1197
|
+
}
|
1198
|
+
}
|
1199
|
+
VALUE delta = rb_hash_aref(options, rb_id2sym(rb_intern("delta")));
|
1200
|
+
if (!NIL_P(delta)) {
|
1201
|
+
switch (TYPE(delta)) {
|
1202
|
+
case T_FIXNUM:
|
1203
|
+
case T_BIGNUM:
|
1204
|
+
req.delta = NUM2ULL(delta);
|
1205
|
+
break;
|
1206
|
+
default:
|
1207
|
+
rb_raise(rb_eArgError, "delta must be an Integer");
|
1208
|
+
}
|
1209
|
+
}
|
1210
|
+
VALUE initial_value = rb_hash_aref(options, rb_id2sym(rb_intern("initial_value")));
|
1211
|
+
if (!NIL_P(initial_value)) {
|
1212
|
+
switch (TYPE(initial_value)) {
|
1213
|
+
case T_FIXNUM:
|
1214
|
+
case T_BIGNUM:
|
1215
|
+
req.initial_value = NUM2ULL(initial_value);
|
1216
|
+
break;
|
1217
|
+
default:
|
1218
|
+
rb_raise(rb_eArgError, "initial_value must be an Integer");
|
1219
|
+
}
|
1220
|
+
}
|
1221
|
+
VALUE expiration = rb_hash_aref(options, rb_id2sym(rb_intern("expiration")));
|
1222
|
+
if (!NIL_P(expiration)) {
|
1223
|
+
Check_Type(expiration, T_FIXNUM);
|
1224
|
+
req.expiration = FIX2UINT(expiration);
|
1225
|
+
}
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::decrement_response>>();
|
1229
|
+
auto f = barrier->get_future();
|
1230
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::decrement_response resp) mutable { barrier->set_value(resp); });
|
1231
|
+
auto resp = f.get();
|
1232
|
+
if (resp.ec) {
|
1233
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to decrement {} by {}", doc_id, req.delta));
|
1234
|
+
}
|
1235
|
+
VALUE res = cb__extract_mutation_result(resp);
|
1236
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("content")), ULL2NUM(resp.content));
|
1237
|
+
return res;
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
static VALUE
|
1241
|
+
cb__map_subdoc_opcode(couchbase::protocol::subdoc_opcode opcode)
|
1242
|
+
{
|
1243
|
+
switch (opcode) {
|
1244
|
+
case couchbase::protocol::subdoc_opcode::get:
|
1245
|
+
return rb_id2sym(rb_intern("get"));
|
1246
|
+
|
1247
|
+
case couchbase::protocol::subdoc_opcode::exists:
|
1248
|
+
return rb_id2sym(rb_intern("exists"));
|
1249
|
+
|
1250
|
+
case couchbase::protocol::subdoc_opcode::dict_add:
|
1251
|
+
return rb_id2sym(rb_intern("dict_add"));
|
1252
|
+
|
1253
|
+
case couchbase::protocol::subdoc_opcode::dict_upsert:
|
1254
|
+
return rb_id2sym(rb_intern("dict_upsert"));
|
1255
|
+
|
1256
|
+
case couchbase::protocol::subdoc_opcode::remove:
|
1257
|
+
return rb_id2sym(rb_intern("remove"));
|
1258
|
+
|
1259
|
+
case couchbase::protocol::subdoc_opcode::replace:
|
1260
|
+
return rb_id2sym(rb_intern("replace"));
|
1261
|
+
|
1262
|
+
case couchbase::protocol::subdoc_opcode::array_push_last:
|
1263
|
+
return rb_id2sym(rb_intern("array_push_last"));
|
1264
|
+
|
1265
|
+
case couchbase::protocol::subdoc_opcode::array_push_first:
|
1266
|
+
return rb_id2sym(rb_intern("array_push_first"));
|
1267
|
+
|
1268
|
+
case couchbase::protocol::subdoc_opcode::array_insert:
|
1269
|
+
return rb_id2sym(rb_intern("array_insert"));
|
1270
|
+
|
1271
|
+
case couchbase::protocol::subdoc_opcode::array_add_unique:
|
1272
|
+
return rb_id2sym(rb_intern("array_add_unique"));
|
1273
|
+
|
1274
|
+
case couchbase::protocol::subdoc_opcode::counter:
|
1275
|
+
return rb_id2sym(rb_intern("counter"));
|
1276
|
+
|
1277
|
+
case couchbase::protocol::subdoc_opcode::get_count:
|
1278
|
+
return rb_id2sym(rb_intern("count"));
|
1279
|
+
}
|
1280
|
+
return rb_id2sym(rb_intern("unknown"));
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
static VALUE
|
1284
|
+
cb__map_subdoc_status(couchbase::protocol::status status)
|
1285
|
+
{
|
1286
|
+
switch (status) {
|
1287
|
+
case couchbase::protocol::status::success:
|
1288
|
+
return rb_id2sym(rb_intern("success"));
|
1289
|
+
|
1290
|
+
case couchbase::protocol::status::subdoc_path_mismatch:
|
1291
|
+
return rb_id2sym(rb_intern("path_mismatch"));
|
1292
|
+
|
1293
|
+
case couchbase::protocol::status::subdoc_path_invalid:
|
1294
|
+
return rb_id2sym(rb_intern("path_invalid"));
|
1295
|
+
|
1296
|
+
case couchbase::protocol::status::subdoc_path_too_big:
|
1297
|
+
return rb_id2sym(rb_intern("path_too_big"));
|
1298
|
+
|
1299
|
+
case couchbase::protocol::status::subdoc_value_cannot_insert:
|
1300
|
+
return rb_id2sym(rb_intern("value_cannot_insert"));
|
1301
|
+
|
1302
|
+
case couchbase::protocol::status::subdoc_doc_not_json:
|
1303
|
+
return rb_id2sym(rb_intern("doc_not_json"));
|
1304
|
+
|
1305
|
+
case couchbase::protocol::status::subdoc_num_range_error:
|
1306
|
+
return rb_id2sym(rb_intern("num_range"));
|
1307
|
+
|
1308
|
+
case couchbase::protocol::status::subdoc_delta_invalid:
|
1309
|
+
return rb_id2sym(rb_intern("delta_invalid"));
|
1310
|
+
|
1311
|
+
case couchbase::protocol::status::subdoc_path_exists:
|
1312
|
+
return rb_id2sym(rb_intern("path_exists"));
|
1313
|
+
|
1314
|
+
case couchbase::protocol::status::subdoc_value_too_deep:
|
1315
|
+
return rb_id2sym(rb_intern("value_too_deep"));
|
1316
|
+
|
1317
|
+
case couchbase::protocol::status::subdoc_invalid_combo:
|
1318
|
+
return rb_id2sym(rb_intern("invalid_combo"));
|
1319
|
+
|
1320
|
+
case couchbase::protocol::status::subdoc_xattr_invalid_flag_combo:
|
1321
|
+
return rb_id2sym(rb_intern("xattr_invalid_flag_combo"));
|
1322
|
+
|
1323
|
+
case couchbase::protocol::status::subdoc_xattr_invalid_key_combo:
|
1324
|
+
return rb_id2sym(rb_intern("xattr_invalid_key_combo"));
|
1325
|
+
|
1326
|
+
case couchbase::protocol::status::subdoc_xattr_unknown_macro:
|
1327
|
+
return rb_id2sym(rb_intern("xattr_unknown_macro"));
|
1328
|
+
|
1329
|
+
case couchbase::protocol::status::subdoc_xattr_unknown_vattr:
|
1330
|
+
return rb_id2sym(rb_intern("xattr_unknown_vattr"));
|
1331
|
+
|
1332
|
+
case couchbase::protocol::status::subdoc_xattr_cannot_modify_vattr:
|
1333
|
+
return rb_id2sym(rb_intern("xattr_cannot_modify_vattr"));
|
1334
|
+
|
1335
|
+
default:
|
1336
|
+
return rb_id2sym(rb_intern("unknown"));
|
1337
|
+
}
|
1338
|
+
}
|
1339
|
+
|
1340
|
+
static VALUE
|
1341
|
+
cb_Backend_document_lookup_in(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE access_deleted, VALUE specs)
|
1342
|
+
{
|
1343
|
+
cb_backend_data* backend = nullptr;
|
1344
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1345
|
+
|
1346
|
+
if (!backend->cluster) {
|
1347
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1348
|
+
}
|
1349
|
+
|
1350
|
+
Check_Type(bucket, T_STRING);
|
1351
|
+
Check_Type(collection, T_STRING);
|
1352
|
+
Check_Type(id, T_STRING);
|
1353
|
+
Check_Type(specs, T_ARRAY);
|
1354
|
+
if (RARRAY_LEN(specs) <= 0) {
|
1355
|
+
rb_raise(rb_eArgError, "Array with specs cannot be empty");
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
couchbase::document_id doc_id;
|
1359
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
1360
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
1361
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
1362
|
+
|
1363
|
+
couchbase::operations::lookup_in_request req{ doc_id };
|
1364
|
+
req.access_deleted = RTEST(access_deleted);
|
1365
|
+
auto entries_size = static_cast<size_t>(RARRAY_LEN(specs));
|
1366
|
+
req.specs.entries.reserve(entries_size);
|
1367
|
+
for (size_t i = 0; i < entries_size; ++i) {
|
1368
|
+
VALUE entry = rb_ary_entry(specs, static_cast<long>(i));
|
1369
|
+
Check_Type(entry, T_HASH);
|
1370
|
+
VALUE operation = rb_hash_aref(entry, rb_id2sym(rb_intern("opcode")));
|
1371
|
+
Check_Type(operation, T_SYMBOL);
|
1372
|
+
ID operation_id = rb_sym2id(operation);
|
852
1373
|
couchbase::protocol::subdoc_opcode opcode;
|
853
|
-
if (operation_id == rb_intern("
|
854
|
-
opcode = couchbase::protocol::subdoc_opcode::
|
855
|
-
} else if (operation_id == rb_intern("
|
856
|
-
opcode = couchbase::protocol::subdoc_opcode::
|
857
|
-
} else if (operation_id == rb_intern("
|
858
|
-
opcode = couchbase::protocol::subdoc_opcode::
|
859
|
-
} else if (operation_id == rb_intern("replace")) {
|
860
|
-
opcode = couchbase::protocol::subdoc_opcode::replace;
|
861
|
-
} else if (operation_id == rb_intern("array_push_last")) {
|
862
|
-
opcode = couchbase::protocol::subdoc_opcode::array_push_last;
|
863
|
-
} else if (operation_id == rb_intern("array_push_first")) {
|
864
|
-
opcode = couchbase::protocol::subdoc_opcode::array_push_first;
|
865
|
-
} else if (operation_id == rb_intern("array_insert")) {
|
866
|
-
opcode = couchbase::protocol::subdoc_opcode::array_insert;
|
867
|
-
} else if (operation_id == rb_intern("array_add_unique")) {
|
868
|
-
opcode = couchbase::protocol::subdoc_opcode::array_add_unique;
|
869
|
-
} else if (operation_id == rb_intern("counter")) {
|
870
|
-
opcode = couchbase::protocol::subdoc_opcode::counter;
|
1374
|
+
if (operation_id == rb_intern("get") || operation_id == rb_intern("get_doc")) {
|
1375
|
+
opcode = couchbase::protocol::subdoc_opcode::get;
|
1376
|
+
} else if (operation_id == rb_intern("exists")) {
|
1377
|
+
opcode = couchbase::protocol::subdoc_opcode::exists;
|
1378
|
+
} else if (operation_id == rb_intern("count")) {
|
1379
|
+
opcode = couchbase::protocol::subdoc_opcode::get_count;
|
871
1380
|
} else {
|
872
|
-
rb_raise(rb_eArgError, "Unsupported operation for subdocument
|
1381
|
+
rb_raise(rb_eArgError, "Unsupported operation for subdocument lookup");
|
873
1382
|
}
|
874
1383
|
bool xattr = RTEST(rb_hash_aref(entry, rb_id2sym(rb_intern("xattr"))));
|
875
|
-
bool create_parents = RTEST(rb_hash_aref(entry, rb_id2sym(rb_intern("create_parents"))));
|
876
|
-
bool expand_macros = RTEST(rb_hash_aref(entry, rb_id2sym(rb_intern("expand_macros"))));
|
877
1384
|
VALUE path = rb_hash_aref(entry, rb_id2sym(rb_intern("path")));
|
878
1385
|
Check_Type(path, T_STRING);
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
1386
|
+
req.specs.add_spec(opcode, xattr, std::string(RSTRING_PTR(path), static_cast<size_t>(RSTRING_LEN(path))));
|
1387
|
+
}
|
1388
|
+
|
1389
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::lookup_in_response>>();
|
1390
|
+
auto f = barrier->get_future();
|
1391
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::lookup_in_response resp) mutable { barrier->set_value(resp); });
|
1392
|
+
auto resp = f.get();
|
1393
|
+
if (resp.ec) {
|
1394
|
+
cb_raise_error_code(resp.ec, fmt::format("unable fetch {}", doc_id));
|
1395
|
+
}
|
1396
|
+
|
1397
|
+
VALUE res = rb_hash_new();
|
1398
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("cas")), ULL2NUM(resp.cas));
|
1399
|
+
VALUE fields = rb_ary_new_capa(static_cast<long>(resp.fields.size()));
|
1400
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("fields")), fields);
|
1401
|
+
for (size_t i = 0; i < resp.fields.size(); ++i) {
|
1402
|
+
VALUE entry = rb_hash_new();
|
1403
|
+
rb_hash_aset(entry, rb_id2sym(rb_intern("exists")), resp.fields[i].exists ? Qtrue : Qfalse);
|
1404
|
+
rb_hash_aset(
|
1405
|
+
entry, rb_id2sym(rb_intern("path")), rb_str_new(resp.fields[i].path.data(), static_cast<long>(resp.fields[i].path.size())));
|
1406
|
+
rb_hash_aset(
|
1407
|
+
entry, rb_id2sym(rb_intern("value")), rb_str_new(resp.fields[i].value.data(), static_cast<long>(resp.fields[i].value.size())));
|
1408
|
+
rb_hash_aset(entry, rb_id2sym(rb_intern("status")), cb__map_subdoc_status(resp.fields[i].status));
|
1409
|
+
if (resp.fields[i].opcode == couchbase::protocol::subdoc_opcode::get && resp.fields[i].path.empty()) {
|
1410
|
+
rb_hash_aset(entry, rb_id2sym(rb_intern("type")), rb_id2sym(rb_intern("get_doc")));
|
1411
|
+
} else {
|
1412
|
+
rb_hash_aset(entry, rb_id2sym(rb_intern("type")), cb__map_subdoc_opcode(resp.fields[i].opcode));
|
1413
|
+
}
|
1414
|
+
rb_ary_store(fields, static_cast<long>(i), entry);
|
1415
|
+
}
|
1416
|
+
return res;
|
1417
|
+
}
|
1418
|
+
|
1419
|
+
static VALUE
|
1420
|
+
cb_Backend_document_mutate_in(VALUE self, VALUE bucket, VALUE collection, VALUE id, VALUE access_deleted, VALUE specs, VALUE options)
|
1421
|
+
{
|
1422
|
+
cb_backend_data* backend = nullptr;
|
1423
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1424
|
+
|
1425
|
+
if (!backend->cluster) {
|
1426
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1427
|
+
}
|
1428
|
+
|
1429
|
+
Check_Type(bucket, T_STRING);
|
1430
|
+
Check_Type(collection, T_STRING);
|
1431
|
+
Check_Type(id, T_STRING);
|
1432
|
+
Check_Type(specs, T_ARRAY);
|
1433
|
+
if (RARRAY_LEN(specs) <= 0) {
|
1434
|
+
rb_raise(rb_eArgError, "Array with specs cannot be empty");
|
1435
|
+
}
|
1436
|
+
|
1437
|
+
couchbase::document_id doc_id;
|
1438
|
+
doc_id.bucket.assign(RSTRING_PTR(bucket), static_cast<size_t>(RSTRING_LEN(bucket)));
|
1439
|
+
doc_id.collection.assign(RSTRING_PTR(collection), static_cast<size_t>(RSTRING_LEN(collection)));
|
1440
|
+
doc_id.key.assign(RSTRING_PTR(id), static_cast<size_t>(RSTRING_LEN(id)));
|
1441
|
+
|
1442
|
+
couchbase::operations::mutate_in_request req{ doc_id };
|
1443
|
+
if (!NIL_P(options)) {
|
1444
|
+
Check_Type(options, T_HASH);
|
1445
|
+
VALUE durability_level = rb_hash_aref(options, rb_id2sym(rb_intern("durability_level")));
|
1446
|
+
if (!NIL_P(durability_level)) {
|
1447
|
+
Check_Type(durability_level, T_SYMBOL);
|
1448
|
+
ID level = rb_sym2id(durability_level);
|
1449
|
+
if (level == rb_intern("none")) {
|
1450
|
+
req.durability_level = couchbase::protocol::durability_level::none;
|
1451
|
+
} else if (level == rb_intern("majority_and_persist_to_active")) {
|
1452
|
+
req.durability_level = couchbase::protocol::durability_level::majority_and_persist_to_active;
|
1453
|
+
} else if (level == rb_intern("persist_to_majority")) {
|
1454
|
+
req.durability_level = couchbase::protocol::durability_level::persist_to_majority;
|
1455
|
+
} else {
|
1456
|
+
rb_raise(rb_eArgError, "Unknown durability level");
|
1457
|
+
}
|
1458
|
+
VALUE durability_timeout = rb_hash_aref(options, rb_id2sym(rb_intern("durability_timeout")));
|
1459
|
+
if (!NIL_P(durability_timeout)) {
|
1460
|
+
Check_Type(durability_timeout, T_FIXNUM);
|
1461
|
+
req.durability_timeout = FIX2UINT(durability_timeout);
|
1462
|
+
}
|
1463
|
+
}
|
1464
|
+
}
|
1465
|
+
req.access_deleted = RTEST(access_deleted);
|
1466
|
+
auto entries_size = static_cast<size_t>(RARRAY_LEN(specs));
|
1467
|
+
req.specs.entries.reserve(entries_size);
|
1468
|
+
for (size_t i = 0; i < entries_size; ++i) {
|
1469
|
+
VALUE entry = rb_ary_entry(specs, static_cast<long>(i));
|
1470
|
+
Check_Type(entry, T_HASH);
|
1471
|
+
VALUE operation = rb_hash_aref(entry, rb_id2sym(rb_intern("opcode")));
|
1472
|
+
Check_Type(operation, T_SYMBOL);
|
1473
|
+
ID operation_id = rb_sym2id(operation);
|
1474
|
+
couchbase::protocol::subdoc_opcode opcode;
|
1475
|
+
if (operation_id == rb_intern("dict_add")) {
|
1476
|
+
opcode = couchbase::protocol::subdoc_opcode::dict_add;
|
1477
|
+
} else if (operation_id == rb_intern("dict_upsert")) {
|
1478
|
+
opcode = couchbase::protocol::subdoc_opcode::dict_upsert;
|
1479
|
+
} else if (operation_id == rb_intern("remove")) {
|
1480
|
+
opcode = couchbase::protocol::subdoc_opcode::remove;
|
1481
|
+
} else if (operation_id == rb_intern("replace")) {
|
1482
|
+
opcode = couchbase::protocol::subdoc_opcode::replace;
|
1483
|
+
} else if (operation_id == rb_intern("array_push_last")) {
|
1484
|
+
opcode = couchbase::protocol::subdoc_opcode::array_push_last;
|
1485
|
+
} else if (operation_id == rb_intern("array_push_first")) {
|
1486
|
+
opcode = couchbase::protocol::subdoc_opcode::array_push_first;
|
1487
|
+
} else if (operation_id == rb_intern("array_insert")) {
|
1488
|
+
opcode = couchbase::protocol::subdoc_opcode::array_insert;
|
1489
|
+
} else if (operation_id == rb_intern("array_add_unique")) {
|
1490
|
+
opcode = couchbase::protocol::subdoc_opcode::array_add_unique;
|
1491
|
+
} else if (operation_id == rb_intern("counter")) {
|
1492
|
+
opcode = couchbase::protocol::subdoc_opcode::counter;
|
1493
|
+
} else {
|
1494
|
+
rb_raise(rb_eArgError, "Unsupported operation for subdocument mutation: %+" PRIsVALUE, operation);
|
1495
|
+
}
|
1496
|
+
bool xattr = RTEST(rb_hash_aref(entry, rb_id2sym(rb_intern("xattr"))));
|
1497
|
+
bool create_parents = RTEST(rb_hash_aref(entry, rb_id2sym(rb_intern("create_parents"))));
|
1498
|
+
bool expand_macros = RTEST(rb_hash_aref(entry, rb_id2sym(rb_intern("expand_macros"))));
|
1499
|
+
VALUE path = rb_hash_aref(entry, rb_id2sym(rb_intern("path")));
|
1500
|
+
Check_Type(path, T_STRING);
|
1501
|
+
VALUE param = rb_hash_aref(entry, rb_id2sym(rb_intern("param")));
|
1502
|
+
if (NIL_P(param)) {
|
1503
|
+
req.specs.add_spec(opcode, xattr, std::string(RSTRING_PTR(path), static_cast<size_t>(RSTRING_LEN(path))));
|
1504
|
+
} else if (opcode == couchbase::protocol::subdoc_opcode::counter) {
|
1505
|
+
Check_Type(param, T_FIXNUM);
|
1506
|
+
req.specs.add_spec(opcode,
|
1507
|
+
xattr,
|
1508
|
+
create_parents,
|
1509
|
+
expand_macros,
|
1510
|
+
std::string(RSTRING_PTR(path), static_cast<size_t>(RSTRING_LEN(path))),
|
1511
|
+
FIX2LONG(param));
|
1512
|
+
} else {
|
1513
|
+
Check_Type(param, T_STRING);
|
1514
|
+
req.specs.add_spec(opcode,
|
1515
|
+
xattr,
|
1516
|
+
create_parents,
|
1517
|
+
expand_macros,
|
1518
|
+
std::string(RSTRING_PTR(path), static_cast<size_t>(RSTRING_LEN(path))),
|
1519
|
+
std::string(RSTRING_PTR(param), static_cast<size_t>(RSTRING_LEN(param))));
|
1520
|
+
}
|
1521
|
+
}
|
1522
|
+
|
1523
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::mutate_in_response>>();
|
1524
|
+
auto f = barrier->get_future();
|
1525
|
+
backend->cluster->execute(req, [barrier](couchbase::operations::mutate_in_response resp) mutable { barrier->set_value(resp); });
|
1526
|
+
auto resp = f.get();
|
1527
|
+
if (resp.ec) {
|
1528
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to mutate {}", doc_id));
|
1529
|
+
}
|
1530
|
+
|
1531
|
+
VALUE res = cb__extract_mutation_result(resp);
|
1532
|
+
if (resp.first_error_index) {
|
1533
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("first_error_index")), ULONG2NUM(resp.first_error_index.value()));
|
1534
|
+
}
|
1535
|
+
VALUE fields = rb_ary_new_capa(static_cast<long>(resp.fields.size()));
|
1536
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("fields")), fields);
|
1537
|
+
for (size_t i = 0; i < resp.fields.size(); ++i) {
|
1538
|
+
VALUE entry = rb_hash_new();
|
1539
|
+
rb_hash_aset(
|
1540
|
+
entry, rb_id2sym(rb_intern("path")), rb_str_new(resp.fields[i].path.data(), static_cast<long>(resp.fields[i].path.size())));
|
1541
|
+
if (resp.fields[i].opcode == couchbase::protocol::subdoc_opcode::counter) {
|
1542
|
+
rb_hash_aset(entry, rb_id2sym(rb_intern("value")), LONG2NUM(std::stoll(resp.fields[i].value)));
|
1543
|
+
} else {
|
1544
|
+
rb_hash_aset(entry,
|
1545
|
+
rb_id2sym(rb_intern("value")),
|
1546
|
+
rb_str_new(resp.fields[i].value.data(), static_cast<long>(resp.fields[i].value.size())));
|
1547
|
+
}
|
1548
|
+
rb_hash_aset(entry, rb_id2sym(rb_intern("status")), cb__map_subdoc_status(resp.fields[i].status));
|
1549
|
+
rb_hash_aset(entry, rb_id2sym(rb_intern("type")), cb__map_subdoc_opcode(resp.fields[i].opcode));
|
1550
|
+
rb_ary_store(fields, static_cast<long>(i), entry);
|
1551
|
+
}
|
1552
|
+
return res;
|
1553
|
+
}
|
1554
|
+
|
1555
|
+
static int
|
1556
|
+
cb__for_each_named_param(VALUE key, VALUE value, VALUE arg)
|
1557
|
+
{
|
1558
|
+
auto* preq = reinterpret_cast<couchbase::operations::query_request*>(arg);
|
1559
|
+
Check_Type(key, T_STRING);
|
1560
|
+
Check_Type(value, T_STRING);
|
1561
|
+
preq->named_parameters.emplace(
|
1562
|
+
std::string_view(RSTRING_PTR(key), static_cast<std::size_t>(RSTRING_LEN(key))),
|
1563
|
+
tao::json::from_string(std::string_view(RSTRING_PTR(value), static_cast<std::size_t>(RSTRING_LEN(value)))));
|
1564
|
+
return ST_CONTINUE;
|
1565
|
+
}
|
1566
|
+
|
1567
|
+
static VALUE
|
1568
|
+
cb_Backend_document_query(VALUE self, VALUE statement, VALUE options)
|
1569
|
+
{
|
1570
|
+
cb_backend_data* backend = nullptr;
|
1571
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1572
|
+
|
1573
|
+
if (!backend->cluster) {
|
1574
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1575
|
+
}
|
1576
|
+
|
1577
|
+
Check_Type(statement, T_STRING);
|
1578
|
+
Check_Type(options, T_HASH);
|
1579
|
+
|
1580
|
+
couchbase::operations::query_request req;
|
1581
|
+
req.statement.assign(RSTRING_PTR(statement), static_cast<size_t>(RSTRING_LEN(statement)));
|
1582
|
+
VALUE client_context_id = rb_hash_aref(options, rb_id2sym(rb_intern("client_context_id")));
|
1583
|
+
if (!NIL_P(client_context_id)) {
|
1584
|
+
Check_Type(client_context_id, T_STRING);
|
1585
|
+
req.client_context_id.assign(RSTRING_PTR(client_context_id), static_cast<size_t>(RSTRING_LEN(client_context_id)));
|
1586
|
+
}
|
1587
|
+
VALUE timeout = rb_hash_aref(options, rb_id2sym(rb_intern("timeout")));
|
1588
|
+
if (!NIL_P(timeout)) {
|
1589
|
+
switch (TYPE(timeout)) {
|
1590
|
+
case T_FIXNUM:
|
1591
|
+
case T_BIGNUM:
|
1592
|
+
break;
|
1593
|
+
default:
|
1594
|
+
rb_raise(rb_eArgError, "timeout must be an Integer");
|
1595
|
+
}
|
1596
|
+
req.timeout = NUM2ULL(timeout);
|
1597
|
+
}
|
1598
|
+
VALUE adhoc = rb_hash_aref(options, rb_id2sym(rb_intern("adhoc")));
|
1599
|
+
if (!NIL_P(adhoc)) {
|
1600
|
+
req.adhoc = RTEST(adhoc);
|
1601
|
+
}
|
1602
|
+
VALUE metrics = rb_hash_aref(options, rb_id2sym(rb_intern("metrics")));
|
1603
|
+
if (!NIL_P(metrics)) {
|
1604
|
+
req.metrics = RTEST(metrics);
|
1605
|
+
}
|
1606
|
+
VALUE readonly = rb_hash_aref(options, rb_id2sym(rb_intern("readonly")));
|
1607
|
+
if (!NIL_P(readonly)) {
|
1608
|
+
req.readonly = RTEST(readonly);
|
1609
|
+
}
|
1610
|
+
VALUE scan_cap = rb_hash_aref(options, rb_id2sym(rb_intern("scan_cap")));
|
1611
|
+
if (!NIL_P(scan_cap)) {
|
1612
|
+
req.scan_cap = NUM2ULONG(scan_cap);
|
1613
|
+
}
|
1614
|
+
VALUE scan_wait = rb_hash_aref(options, rb_id2sym(rb_intern("scan_wait")));
|
1615
|
+
if (!NIL_P(scan_wait)) {
|
1616
|
+
req.scan_wait = NUM2ULONG(scan_wait);
|
1617
|
+
}
|
1618
|
+
VALUE max_parallelism = rb_hash_aref(options, rb_id2sym(rb_intern("max_parallelism")));
|
1619
|
+
if (!NIL_P(max_parallelism)) {
|
1620
|
+
req.max_parallelism = NUM2ULONG(max_parallelism);
|
1621
|
+
}
|
1622
|
+
VALUE pipeline_cap = rb_hash_aref(options, rb_id2sym(rb_intern("pipeline_cap")));
|
1623
|
+
if (!NIL_P(pipeline_cap)) {
|
1624
|
+
req.pipeline_cap = NUM2ULONG(pipeline_cap);
|
1625
|
+
}
|
1626
|
+
VALUE pipeline_batch = rb_hash_aref(options, rb_id2sym(rb_intern("pipeline_batch")));
|
1627
|
+
if (!NIL_P(pipeline_batch)) {
|
1628
|
+
req.pipeline_batch = NUM2ULONG(pipeline_batch);
|
1629
|
+
}
|
1630
|
+
VALUE profile = rb_hash_aref(options, rb_id2sym(rb_intern("profile")));
|
1631
|
+
if (!NIL_P(profile)) {
|
1632
|
+
Check_Type(profile, T_SYMBOL);
|
1633
|
+
ID mode = rb_sym2id(profile);
|
1634
|
+
if (mode == rb_intern("phases")) {
|
1635
|
+
req.profile = couchbase::operations::query_request::profile_mode::phases;
|
1636
|
+
} else if (mode == rb_intern("timings")) {
|
1637
|
+
req.profile = couchbase::operations::query_request::profile_mode::timings;
|
1638
|
+
} else if (mode == rb_intern("off")) {
|
1639
|
+
req.profile = couchbase::operations::query_request::profile_mode::off;
|
1640
|
+
}
|
1641
|
+
}
|
1642
|
+
VALUE positional_params = rb_hash_aref(options, rb_id2sym(rb_intern("positional_parameters")));
|
1643
|
+
if (!NIL_P(positional_params)) {
|
1644
|
+
Check_Type(positional_params, T_ARRAY);
|
1645
|
+
auto entries_num = static_cast<size_t>(RARRAY_LEN(positional_params));
|
1646
|
+
req.positional_parameters.reserve(entries_num);
|
1647
|
+
for (size_t i = 0; i < entries_num; ++i) {
|
1648
|
+
VALUE entry = rb_ary_entry(positional_params, static_cast<long>(i));
|
1649
|
+
Check_Type(entry, T_STRING);
|
1650
|
+
req.positional_parameters.emplace_back(
|
1651
|
+
tao::json::from_string(std::string_view(RSTRING_PTR(entry), static_cast<std::size_t>(RSTRING_LEN(entry)))));
|
1652
|
+
}
|
1653
|
+
}
|
1654
|
+
VALUE named_params = rb_hash_aref(options, rb_id2sym(rb_intern("named_parameters")));
|
1655
|
+
if (!NIL_P(named_params)) {
|
1656
|
+
Check_Type(named_params, T_HASH);
|
1657
|
+
rb_hash_foreach(named_params, INT_FUNC(cb__for_each_named_param), reinterpret_cast<VALUE>(&req));
|
1658
|
+
}
|
1659
|
+
VALUE scan_consistency = rb_hash_aref(options, rb_id2sym(rb_intern("scan_consistency")));
|
1660
|
+
if (!NIL_P(scan_consistency)) {
|
1661
|
+
Check_Type(scan_consistency, T_SYMBOL);
|
1662
|
+
ID type = rb_sym2id(scan_consistency);
|
1663
|
+
if (type == rb_intern("not_bounded")) {
|
1664
|
+
req.scan_consistency = couchbase::operations::query_request::scan_consistency_type::not_bounded;
|
1665
|
+
} else if (type == rb_intern("request_plus")) {
|
1666
|
+
req.scan_consistency = couchbase::operations::query_request::scan_consistency_type::request_plus;
|
1667
|
+
}
|
1668
|
+
}
|
1669
|
+
VALUE mutation_state = rb_hash_aref(options, rb_id2sym(rb_intern("mutation_state")));
|
1670
|
+
if (!NIL_P(mutation_state)) {
|
1671
|
+
Check_Type(mutation_state, T_ARRAY);
|
1672
|
+
auto state_size = static_cast<size_t>(RARRAY_LEN(mutation_state));
|
1673
|
+
req.mutation_state.reserve(state_size);
|
1674
|
+
for (size_t i = 0; i < state_size; ++i) {
|
1675
|
+
VALUE token = rb_ary_entry(mutation_state, static_cast<long>(i));
|
1676
|
+
Check_Type(token, T_HASH);
|
1677
|
+
VALUE bucket_name = rb_hash_aref(token, rb_id2sym(rb_intern("bucket_name")));
|
1678
|
+
Check_Type(bucket_name, T_STRING);
|
1679
|
+
VALUE partition_id = rb_hash_aref(token, rb_id2sym(rb_intern("partition_id")));
|
1680
|
+
Check_Type(partition_id, T_FIXNUM);
|
1681
|
+
VALUE partition_uuid = rb_hash_aref(token, rb_id2sym(rb_intern("partition_uuid")));
|
1682
|
+
switch (TYPE(partition_uuid)) {
|
1683
|
+
case T_FIXNUM:
|
1684
|
+
case T_BIGNUM:
|
1685
|
+
break;
|
1686
|
+
default:
|
1687
|
+
rb_raise(rb_eArgError, "partition_uuid must be an Integer");
|
1688
|
+
}
|
1689
|
+
VALUE sequence_number = rb_hash_aref(token, rb_id2sym(rb_intern("sequence_number")));
|
1690
|
+
switch (TYPE(sequence_number)) {
|
1691
|
+
case T_FIXNUM:
|
1692
|
+
case T_BIGNUM:
|
1693
|
+
break;
|
1694
|
+
default:
|
1695
|
+
rb_raise(rb_eArgError, "sequence_number must be an Integer");
|
1696
|
+
}
|
1697
|
+
req.mutation_state.emplace_back(
|
1698
|
+
couchbase::mutation_token{ NUM2ULL(partition_uuid),
|
1699
|
+
NUM2ULL(sequence_number),
|
1700
|
+
gsl::narrow_cast<std::uint16_t>(NUM2UINT(partition_id)),
|
1701
|
+
std::string(RSTRING_PTR(bucket_name), static_cast<std::size_t>(RSTRING_LEN(bucket_name))) });
|
1702
|
+
}
|
1703
|
+
}
|
1704
|
+
|
1705
|
+
VALUE raw_params = rb_hash_aref(options, rb_id2sym(rb_intern("raw_parameters")));
|
1706
|
+
if (!NIL_P(raw_params)) {
|
1707
|
+
Check_Type(raw_params, T_HASH);
|
1708
|
+
rb_hash_foreach(raw_params, INT_FUNC(cb__for_each_named_param), reinterpret_cast<VALUE>(&req));
|
1709
|
+
}
|
1710
|
+
|
1711
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::query_response>>();
|
1712
|
+
auto f = barrier->get_future();
|
1713
|
+
backend->cluster->execute_http(req, [barrier](couchbase::operations::query_response resp) mutable { barrier->set_value(resp); });
|
1714
|
+
auto resp = f.get();
|
1715
|
+
if (resp.ec) {
|
1716
|
+
if (resp.payload.meta_data.errors && !resp.payload.meta_data.errors->empty()) {
|
1717
|
+
const auto& first_error = resp.payload.meta_data.errors->front();
|
1718
|
+
cb_raise_error_code(resp.ec,
|
1719
|
+
fmt::format("unable to query: \"{}{}\" ({}: {})",
|
1720
|
+
req.statement.substr(0, 50),
|
1721
|
+
req.statement.size() > 50 ? "..." : "",
|
1722
|
+
first_error.code,
|
1723
|
+
first_error.message));
|
1724
|
+
} else {
|
1725
|
+
cb_raise_error_code(
|
1726
|
+
resp.ec, fmt::format("unable to query: \"{}{}\"", req.statement.substr(0, 50), req.statement.size() > 50 ? "..." : ""));
|
1727
|
+
}
|
1728
|
+
}
|
1729
|
+
VALUE res = rb_hash_new();
|
1730
|
+
VALUE rows = rb_ary_new_capa(static_cast<long>(resp.payload.rows.size()));
|
1731
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("rows")), rows);
|
1732
|
+
for (auto& row : resp.payload.rows) {
|
1733
|
+
rb_ary_push(rows, rb_str_new(row.data(), static_cast<long>(row.size())));
|
1734
|
+
}
|
1735
|
+
VALUE meta = rb_hash_new();
|
1736
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("meta")), meta);
|
1737
|
+
rb_hash_aset(meta,
|
1738
|
+
rb_id2sym(rb_intern("status")),
|
1739
|
+
rb_id2sym(rb_intern2(resp.payload.meta_data.status.data(), static_cast<long>(resp.payload.meta_data.status.size()))));
|
1740
|
+
rb_hash_aset(meta,
|
1741
|
+
rb_id2sym(rb_intern("request_id")),
|
1742
|
+
rb_str_new(resp.payload.meta_data.request_id.data(), static_cast<long>(resp.payload.meta_data.request_id.size())));
|
1743
|
+
rb_hash_aset(
|
1744
|
+
meta,
|
1745
|
+
rb_id2sym(rb_intern("client_context_id")),
|
1746
|
+
rb_str_new(resp.payload.meta_data.client_context_id.data(), static_cast<long>(resp.payload.meta_data.client_context_id.size())));
|
1747
|
+
if (resp.payload.meta_data.signature) {
|
1748
|
+
rb_hash_aset(meta,
|
1749
|
+
rb_id2sym(rb_intern("signature")),
|
1750
|
+
rb_str_new(resp.payload.meta_data.signature->data(), static_cast<long>(resp.payload.meta_data.signature->size())));
|
1751
|
+
}
|
1752
|
+
if (resp.payload.meta_data.profile) {
|
1753
|
+
rb_hash_aset(meta,
|
1754
|
+
rb_id2sym(rb_intern("profile")),
|
1755
|
+
rb_str_new(resp.payload.meta_data.profile->data(), static_cast<long>(resp.payload.meta_data.profile->size())));
|
1756
|
+
}
|
1757
|
+
metrics = rb_hash_new();
|
1758
|
+
rb_hash_aset(meta, rb_id2sym(rb_intern("metrics")), metrics);
|
1759
|
+
rb_hash_aset(metrics,
|
1760
|
+
rb_id2sym(rb_intern("elapsed_time")),
|
1761
|
+
rb_str_new(resp.payload.meta_data.metrics.elapsed_time.data(),
|
1762
|
+
static_cast<long>(resp.payload.meta_data.metrics.elapsed_time.size())));
|
1763
|
+
rb_hash_aset(metrics,
|
1764
|
+
rb_id2sym(rb_intern("execution_time")),
|
1765
|
+
rb_str_new(resp.payload.meta_data.metrics.execution_time.data(),
|
1766
|
+
static_cast<long>(resp.payload.meta_data.metrics.execution_time.size())));
|
1767
|
+
rb_hash_aset(metrics, rb_id2sym(rb_intern("result_count")), ULL2NUM(resp.payload.meta_data.metrics.result_count));
|
1768
|
+
rb_hash_aset(metrics, rb_id2sym(rb_intern("result_size")), ULL2NUM(resp.payload.meta_data.metrics.result_count));
|
1769
|
+
if (resp.payload.meta_data.metrics.sort_count) {
|
1770
|
+
rb_hash_aset(metrics, rb_id2sym(rb_intern("sort_count")), ULL2NUM(*resp.payload.meta_data.metrics.sort_count));
|
1771
|
+
}
|
1772
|
+
if (resp.payload.meta_data.metrics.mutation_count) {
|
1773
|
+
rb_hash_aset(metrics, rb_id2sym(rb_intern("mutation_count")), ULL2NUM(*resp.payload.meta_data.metrics.mutation_count));
|
1774
|
+
}
|
1775
|
+
if (resp.payload.meta_data.metrics.error_count) {
|
1776
|
+
rb_hash_aset(metrics, rb_id2sym(rb_intern("error_count")), ULL2NUM(*resp.payload.meta_data.metrics.error_count));
|
1777
|
+
}
|
1778
|
+
if (resp.payload.meta_data.metrics.warning_count) {
|
1779
|
+
rb_hash_aset(metrics, rb_id2sym(rb_intern("warning_count")), ULL2NUM(*resp.payload.meta_data.metrics.warning_count));
|
1780
|
+
}
|
1781
|
+
|
1782
|
+
return res;
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
static void
|
1786
|
+
cb__generate_bucket_settings(VALUE bucket, couchbase::operations::bucket_settings& entry, bool is_create)
|
1787
|
+
{
|
1788
|
+
{
|
1789
|
+
VALUE bucket_type = rb_hash_aref(bucket, rb_id2sym(rb_intern("bucket_type")));
|
1790
|
+
Check_Type(bucket_type, T_SYMBOL);
|
1791
|
+
if (bucket_type == rb_id2sym(rb_intern("couchbase")) || bucket_type == rb_id2sym(rb_intern("membase"))) {
|
1792
|
+
entry.bucket_type = couchbase::operations::bucket_settings::bucket_type::couchbase;
|
1793
|
+
} else if (bucket_type == rb_id2sym(rb_intern("memcached"))) {
|
1794
|
+
entry.bucket_type = couchbase::operations::bucket_settings::bucket_type::memcached;
|
1795
|
+
} else if (bucket_type == rb_id2sym(rb_intern("ephemeral"))) {
|
1796
|
+
entry.bucket_type = couchbase::operations::bucket_settings::bucket_type::ephemeral;
|
1797
|
+
} else {
|
1798
|
+
rb_raise(rb_eArgError, "unknown bucket type");
|
1799
|
+
}
|
1800
|
+
}
|
1801
|
+
{
|
1802
|
+
VALUE name = rb_hash_aref(bucket, rb_id2sym(rb_intern("name")));
|
1803
|
+
Check_Type(name, T_STRING);
|
1804
|
+
entry.name.assign(RSTRING_PTR(name), static_cast<size_t>(RSTRING_LEN(name)));
|
1805
|
+
}
|
1806
|
+
{
|
1807
|
+
VALUE quota = rb_hash_aref(bucket, rb_id2sym(rb_intern("ram_quota_mb")));
|
1808
|
+
Check_Type(quota, T_FIXNUM);
|
1809
|
+
entry.ram_quota_mb = FIX2ULONG(quota);
|
1810
|
+
}
|
1811
|
+
{
|
1812
|
+
VALUE expiry = rb_hash_aref(bucket, rb_id2sym(rb_intern("max_expiry")));
|
1813
|
+
if (!NIL_P(expiry)) {
|
1814
|
+
Check_Type(expiry, T_FIXNUM);
|
1815
|
+
entry.max_expiry = FIX2UINT(expiry);
|
1816
|
+
}
|
1817
|
+
}
|
1818
|
+
{
|
1819
|
+
VALUE num_replicas = rb_hash_aref(bucket, rb_id2sym(rb_intern("num_replicas")));
|
1820
|
+
if (!NIL_P(num_replicas)) {
|
1821
|
+
Check_Type(num_replicas, T_FIXNUM);
|
1822
|
+
entry.num_replicas = FIX2UINT(num_replicas);
|
1823
|
+
}
|
1824
|
+
}
|
1825
|
+
{
|
1826
|
+
VALUE replica_indexes = rb_hash_aref(bucket, rb_id2sym(rb_intern("replica_indexes")));
|
1827
|
+
if (!NIL_P(replica_indexes)) {
|
1828
|
+
entry.replica_indexes = RTEST(replica_indexes);
|
1829
|
+
}
|
1830
|
+
}
|
1831
|
+
{
|
1832
|
+
VALUE flush_enabled = rb_hash_aref(bucket, rb_id2sym(rb_intern("flush_enabled")));
|
1833
|
+
if (!NIL_P(flush_enabled)) {
|
1834
|
+
entry.flush_enabled = RTEST(flush_enabled);
|
1835
|
+
}
|
1836
|
+
}
|
1837
|
+
{
|
1838
|
+
VALUE compression_mode = rb_hash_aref(bucket, rb_id2sym(rb_intern("compression_mode")));
|
1839
|
+
if (!NIL_P(compression_mode)) {
|
1840
|
+
Check_Type(compression_mode, T_SYMBOL);
|
1841
|
+
if (compression_mode == rb_id2sym(rb_intern("active"))) {
|
1842
|
+
entry.compression_mode = couchbase::operations::bucket_settings::compression_mode::active;
|
1843
|
+
} else if (compression_mode == rb_id2sym(rb_intern("passive"))) {
|
1844
|
+
entry.compression_mode = couchbase::operations::bucket_settings::compression_mode::passive;
|
1845
|
+
} else if (compression_mode == rb_id2sym(rb_intern("off"))) {
|
1846
|
+
entry.compression_mode = couchbase::operations::bucket_settings::compression_mode::off;
|
1847
|
+
} else {
|
1848
|
+
rb_raise(rb_eArgError, "unknown compression mode");
|
1849
|
+
}
|
1850
|
+
}
|
1851
|
+
}
|
1852
|
+
{
|
1853
|
+
VALUE ejection_policy = rb_hash_aref(bucket, rb_id2sym(rb_intern("ejection_policy")));
|
1854
|
+
if (!NIL_P(ejection_policy)) {
|
1855
|
+
Check_Type(ejection_policy, T_SYMBOL);
|
1856
|
+
if (ejection_policy == rb_id2sym(rb_intern("full"))) {
|
1857
|
+
entry.ejection_policy = couchbase::operations::bucket_settings::ejection_policy::full;
|
1858
|
+
} else if (ejection_policy == rb_id2sym(rb_intern("value_only"))) {
|
1859
|
+
entry.ejection_policy = couchbase::operations::bucket_settings::ejection_policy::value_only;
|
1860
|
+
} else {
|
1861
|
+
rb_raise(rb_eArgError, "unknown ejection policy");
|
1862
|
+
}
|
1863
|
+
}
|
1864
|
+
}
|
1865
|
+
if (is_create) {
|
1866
|
+
VALUE conflict_resolution_type = rb_hash_aref(bucket, rb_id2sym(rb_intern("conflict_resolution_type")));
|
1867
|
+
if (!NIL_P(conflict_resolution_type)) {
|
1868
|
+
Check_Type(conflict_resolution_type, T_SYMBOL);
|
1869
|
+
if (conflict_resolution_type == rb_id2sym(rb_intern("timestamp"))) {
|
1870
|
+
entry.conflict_resolution_type = couchbase::operations::bucket_settings::conflict_resolution_type::timestamp;
|
1871
|
+
} else if (conflict_resolution_type == rb_id2sym(rb_intern("sequence_number"))) {
|
1872
|
+
entry.conflict_resolution_type = couchbase::operations::bucket_settings::conflict_resolution_type::sequence_number;
|
1873
|
+
} else {
|
1874
|
+
rb_raise(rb_eArgError, "unknown conflict resolution type");
|
1875
|
+
}
|
1876
|
+
}
|
1877
|
+
}
|
1878
|
+
}
|
1879
|
+
|
1880
|
+
static VALUE
|
1881
|
+
cb_Backend_bucket_create(VALUE self, VALUE bucket_settings)
|
1882
|
+
{
|
1883
|
+
cb_backend_data* backend = nullptr;
|
1884
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1885
|
+
|
1886
|
+
if (!backend->cluster) {
|
1887
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1888
|
+
}
|
1889
|
+
|
1890
|
+
Check_Type(bucket_settings, T_HASH);
|
1891
|
+
couchbase::operations::bucket_create_request req{};
|
1892
|
+
cb__generate_bucket_settings(bucket_settings, req.bucket, true);
|
1893
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::bucket_create_response>>();
|
1894
|
+
auto f = barrier->get_future();
|
1895
|
+
backend->cluster->execute_http(req,
|
1896
|
+
[barrier](couchbase::operations::bucket_create_response resp) mutable { barrier->set_value(resp); });
|
1897
|
+
auto resp = f.get();
|
1898
|
+
if (resp.ec) {
|
1899
|
+
cb_raise_error_code(resp.ec,
|
1900
|
+
fmt::format("unable to create bucket \"{}\" on the cluster ({})", req.bucket.name, resp.error_message));
|
1901
|
+
}
|
1902
|
+
|
1903
|
+
return Qtrue;
|
1904
|
+
}
|
1905
|
+
|
1906
|
+
static VALUE
|
1907
|
+
cb_Backend_bucket_update(VALUE self, VALUE bucket_settings)
|
1908
|
+
{
|
1909
|
+
cb_backend_data* backend = nullptr;
|
1910
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1911
|
+
|
1912
|
+
if (!backend->cluster) {
|
1913
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1914
|
+
}
|
1915
|
+
|
1916
|
+
Check_Type(bucket_settings, T_HASH);
|
1917
|
+
couchbase::operations::bucket_update_request req{};
|
1918
|
+
cb__generate_bucket_settings(bucket_settings, req.bucket, false);
|
1919
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::bucket_update_response>>();
|
1920
|
+
auto f = barrier->get_future();
|
1921
|
+
backend->cluster->execute_http(req,
|
1922
|
+
[barrier](couchbase::operations::bucket_update_response resp) mutable { barrier->set_value(resp); });
|
1923
|
+
auto resp = f.get();
|
1924
|
+
if (resp.ec) {
|
1925
|
+
cb_raise_error_code(resp.ec,
|
1926
|
+
fmt::format("unable to update bucket \"{}\" on the cluster ({})", req.bucket.name, resp.error_message));
|
1927
|
+
}
|
1928
|
+
|
1929
|
+
return Qtrue;
|
1930
|
+
}
|
1931
|
+
|
1932
|
+
static VALUE
|
1933
|
+
cb_Backend_bucket_drop(VALUE self, VALUE bucket_name)
|
1934
|
+
{
|
1935
|
+
cb_backend_data* backend = nullptr;
|
1936
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1937
|
+
|
1938
|
+
if (!backend->cluster) {
|
1939
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1940
|
+
}
|
1941
|
+
|
1942
|
+
Check_Type(bucket_name, T_STRING);
|
1943
|
+
|
1944
|
+
couchbase::operations::bucket_drop_request req{};
|
1945
|
+
req.name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
1946
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::bucket_drop_response>>();
|
1947
|
+
auto f = barrier->get_future();
|
1948
|
+
backend->cluster->execute_http(req, [barrier](couchbase::operations::bucket_drop_response resp) mutable { barrier->set_value(resp); });
|
1949
|
+
auto resp = f.get();
|
1950
|
+
if (resp.ec) {
|
1951
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to remove bucket \"{}\" on the cluster", req.name));
|
1952
|
+
}
|
1953
|
+
|
1954
|
+
return Qtrue;
|
1955
|
+
}
|
1956
|
+
|
1957
|
+
static VALUE
|
1958
|
+
cb_Backend_bucket_flush(VALUE self, VALUE bucket_name)
|
1959
|
+
{
|
1960
|
+
cb_backend_data* backend = nullptr;
|
1961
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
1962
|
+
|
1963
|
+
if (!backend->cluster) {
|
1964
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1965
|
+
}
|
1966
|
+
|
1967
|
+
Check_Type(bucket_name, T_STRING);
|
1968
|
+
|
1969
|
+
couchbase::operations::bucket_flush_request req{};
|
1970
|
+
req.name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
1971
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::bucket_flush_response>>();
|
1972
|
+
auto f = barrier->get_future();
|
1973
|
+
backend->cluster->execute_http(req, [barrier](couchbase::operations::bucket_flush_response resp) mutable { barrier->set_value(resp); });
|
1974
|
+
auto resp = f.get();
|
1975
|
+
if (resp.ec) {
|
1976
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to remove bucket \"{}\" on the cluster", req.name));
|
1977
|
+
}
|
1978
|
+
|
1979
|
+
return Qtrue;
|
1980
|
+
}
|
1981
|
+
|
1982
|
+
static void
|
1983
|
+
cb__extract_bucket_settings(const couchbase::operations::bucket_settings& entry, VALUE bucket)
|
1984
|
+
{
|
1985
|
+
switch (entry.bucket_type) {
|
1986
|
+
case couchbase::operations::bucket_settings::bucket_type::couchbase:
|
1987
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("bucket_type")), rb_id2sym(rb_intern("couchbase")));
|
1988
|
+
break;
|
1989
|
+
case couchbase::operations::bucket_settings::bucket_type::memcached:
|
1990
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("bucket_type")), rb_id2sym(rb_intern("memcached")));
|
1991
|
+
break;
|
1992
|
+
case couchbase::operations::bucket_settings::bucket_type::ephemeral:
|
1993
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("bucket_type")), rb_id2sym(rb_intern("ephemeral")));
|
1994
|
+
break;
|
1995
|
+
case couchbase::operations::bucket_settings::bucket_type::unknown:
|
1996
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("bucket_type")), Qnil);
|
1997
|
+
break;
|
1998
|
+
}
|
1999
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("name")), rb_str_new(entry.name.data(), static_cast<long>(entry.name.size())));
|
2000
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("uuid")), rb_str_new(entry.uuid.data(), static_cast<long>(entry.uuid.size())));
|
2001
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("ram_quota_mb")), ULL2NUM(entry.ram_quota_mb));
|
2002
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("max_expiry")), ULONG2NUM(entry.max_expiry));
|
2003
|
+
switch (entry.compression_mode) {
|
2004
|
+
case couchbase::operations::bucket_settings::compression_mode::off:
|
2005
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("compression_mode")), rb_id2sym(rb_intern("off")));
|
2006
|
+
break;
|
2007
|
+
case couchbase::operations::bucket_settings::compression_mode::active:
|
2008
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("compression_mode")), rb_id2sym(rb_intern("active")));
|
2009
|
+
break;
|
2010
|
+
case couchbase::operations::bucket_settings::compression_mode::passive:
|
2011
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("compression_mode")), rb_id2sym(rb_intern("passive")));
|
2012
|
+
break;
|
2013
|
+
case couchbase::operations::bucket_settings::compression_mode::unknown:
|
2014
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("compression_mode")), Qnil);
|
2015
|
+
break;
|
2016
|
+
}
|
2017
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("num_replicas")), ULONG2NUM(entry.num_replicas));
|
2018
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("replica_indexes")), entry.replica_indexes ? Qtrue : Qfalse);
|
2019
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("flush_enabled")), entry.flush_enabled ? Qtrue : Qfalse);
|
2020
|
+
switch (entry.ejection_policy) {
|
2021
|
+
case couchbase::operations::bucket_settings::ejection_policy::full:
|
2022
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("ejection_policy")), rb_id2sym(rb_intern("full")));
|
2023
|
+
break;
|
2024
|
+
case couchbase::operations::bucket_settings::ejection_policy::value_only:
|
2025
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("ejection_policy")), rb_id2sym(rb_intern("value_only")));
|
2026
|
+
break;
|
2027
|
+
case couchbase::operations::bucket_settings::ejection_policy::unknown:
|
2028
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("ejection_policy")), Qnil);
|
2029
|
+
break;
|
2030
|
+
}
|
2031
|
+
switch (entry.conflict_resolution_type) {
|
2032
|
+
case couchbase::operations::bucket_settings::conflict_resolution_type::timestamp:
|
2033
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("conflict_resolution_type")), rb_id2sym(rb_intern("timestamp")));
|
2034
|
+
break;
|
2035
|
+
case couchbase::operations::bucket_settings::conflict_resolution_type::sequence_number:
|
2036
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("conflict_resolution_type")), rb_id2sym(rb_intern("sequence_number")));
|
2037
|
+
break;
|
2038
|
+
case couchbase::operations::bucket_settings::conflict_resolution_type::unknown:
|
2039
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("conflict_resolution_type")), Qnil);
|
2040
|
+
break;
|
2041
|
+
}
|
2042
|
+
VALUE capabilities = rb_ary_new_capa(static_cast<long>(entry.capabilities.size()));
|
2043
|
+
for (const auto& capa : entry.capabilities) {
|
2044
|
+
rb_ary_push(capabilities, rb_str_new(capa.data(), static_cast<long>(capa.size())));
|
2045
|
+
}
|
2046
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("capabilities")), capabilities);
|
2047
|
+
VALUE nodes = rb_ary_new_capa(static_cast<long>(entry.nodes.size()));
|
2048
|
+
for (const auto& n : entry.nodes) {
|
2049
|
+
VALUE node = rb_hash_new();
|
2050
|
+
rb_hash_aset(node, rb_id2sym(rb_intern("status")), rb_str_new(n.status.data(), static_cast<long>(n.status.size())));
|
2051
|
+
rb_hash_aset(node, rb_id2sym(rb_intern("hostname")), rb_str_new(n.hostname.data(), static_cast<long>(n.hostname.size())));
|
2052
|
+
rb_hash_aset(node, rb_id2sym(rb_intern("version")), rb_str_new(n.version.data(), static_cast<long>(n.version.size())));
|
2053
|
+
rb_ary_push(nodes, node);
|
2054
|
+
}
|
2055
|
+
rb_hash_aset(bucket, rb_id2sym(rb_intern("nodes")), nodes);
|
2056
|
+
}
|
2057
|
+
|
2058
|
+
static VALUE
|
2059
|
+
cb_Backend_bucket_get_all(VALUE self)
|
2060
|
+
{
|
2061
|
+
cb_backend_data* backend = nullptr;
|
2062
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2063
|
+
|
2064
|
+
if (!backend->cluster) {
|
2065
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2066
|
+
}
|
2067
|
+
|
2068
|
+
couchbase::operations::bucket_get_all_request req{};
|
2069
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::bucket_get_all_response>>();
|
2070
|
+
auto f = barrier->get_future();
|
2071
|
+
backend->cluster->execute_http(req,
|
2072
|
+
[barrier](couchbase::operations::bucket_get_all_response resp) mutable { barrier->set_value(resp); });
|
2073
|
+
auto resp = f.get();
|
2074
|
+
if (resp.ec) {
|
2075
|
+
cb_raise_error_code(resp.ec, "unable to get list of the buckets of the cluster");
|
2076
|
+
}
|
2077
|
+
|
2078
|
+
VALUE res = rb_ary_new_capa(static_cast<long>(resp.buckets.size()));
|
2079
|
+
for (const auto& entry : resp.buckets) {
|
2080
|
+
VALUE bucket = rb_hash_new();
|
2081
|
+
cb__extract_bucket_settings(entry, bucket);
|
2082
|
+
rb_ary_push(res, bucket);
|
2083
|
+
}
|
2084
|
+
|
2085
|
+
return res;
|
2086
|
+
}
|
2087
|
+
|
2088
|
+
static VALUE
|
2089
|
+
cb_Backend_bucket_get(VALUE self, VALUE bucket_name)
|
2090
|
+
{
|
2091
|
+
cb_backend_data* backend = nullptr;
|
2092
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2093
|
+
|
2094
|
+
if (!backend->cluster) {
|
2095
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2096
|
+
}
|
2097
|
+
|
2098
|
+
Check_Type(bucket_name, T_STRING);
|
2099
|
+
|
2100
|
+
couchbase::operations::bucket_get_request req{};
|
2101
|
+
req.name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2102
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::bucket_get_response>>();
|
2103
|
+
auto f = barrier->get_future();
|
2104
|
+
backend->cluster->execute_http(req, [barrier](couchbase::operations::bucket_get_response resp) mutable { barrier->set_value(resp); });
|
2105
|
+
auto resp = f.get();
|
2106
|
+
if (resp.ec) {
|
2107
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to locate bucket \"{}\" on the cluster", req.name));
|
2108
|
+
}
|
2109
|
+
|
2110
|
+
VALUE res = rb_hash_new();
|
2111
|
+
cb__extract_bucket_settings(resp.bucket, res);
|
2112
|
+
|
2113
|
+
return res;
|
2114
|
+
}
|
2115
|
+
|
2116
|
+
static VALUE
|
2117
|
+
cb_Backend_cluster_enable_developer_preview(VALUE self)
|
2118
|
+
{
|
2119
|
+
cb_backend_data* backend = nullptr;
|
2120
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2121
|
+
|
2122
|
+
if (!backend->cluster) {
|
2123
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2124
|
+
}
|
2125
|
+
|
2126
|
+
couchbase::operations::cluster_developer_preview_enable_request req{};
|
2127
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::cluster_developer_preview_enable_response>>();
|
2128
|
+
auto f = barrier->get_future();
|
2129
|
+
backend->cluster->execute_http(
|
2130
|
+
req, [barrier](couchbase::operations::cluster_developer_preview_enable_response resp) mutable { barrier->set_value(resp); });
|
2131
|
+
auto resp = f.get();
|
2132
|
+
if (resp.ec) {
|
2133
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to enable developer preview for this cluster"));
|
2134
|
+
}
|
2135
|
+
spdlog::critical("Developer preview cannot be disabled once it is enabled. If you enter developer preview mode you will not be able to "
|
2136
|
+
"upgrade. DO NOT USE IN PRODUCTION.");
|
2137
|
+
return Qtrue;
|
2138
|
+
}
|
2139
|
+
|
2140
|
+
static VALUE
|
2141
|
+
cb_Backend_scope_get_all(VALUE self, VALUE bucket_name)
|
2142
|
+
{
|
2143
|
+
cb_backend_data* backend = nullptr;
|
2144
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2145
|
+
|
2146
|
+
if (!backend->cluster) {
|
2147
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2148
|
+
}
|
2149
|
+
|
2150
|
+
Check_Type(bucket_name, T_STRING);
|
2151
|
+
|
2152
|
+
couchbase::operations::scope_get_all_request req{};
|
2153
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2154
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::scope_get_all_response>>();
|
2155
|
+
auto f = barrier->get_future();
|
2156
|
+
backend->cluster->execute_http(req,
|
2157
|
+
[barrier](couchbase::operations::scope_get_all_response resp) mutable { barrier->set_value(resp); });
|
2158
|
+
auto resp = f.get();
|
2159
|
+
if (resp.ec) {
|
2160
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to get list of the scopes of the bucket \"{}\"", req.bucket_name));
|
2161
|
+
}
|
2162
|
+
|
2163
|
+
VALUE res = rb_hash_new();
|
2164
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("uid")), ULL2NUM(resp.manifest.uid));
|
2165
|
+
VALUE scopes = rb_ary_new_capa(static_cast<long>(resp.manifest.scopes.size()));
|
2166
|
+
for (const auto& s : resp.manifest.scopes) {
|
2167
|
+
VALUE scope = rb_hash_new();
|
2168
|
+
rb_hash_aset(scope, rb_id2sym(rb_intern("uid")), ULL2NUM(s.uid));
|
2169
|
+
rb_hash_aset(scope, rb_id2sym(rb_intern("name")), rb_str_new(s.name.data(), static_cast<long>(s.name.size())));
|
2170
|
+
VALUE collections = rb_ary_new_capa(static_cast<long>(s.collections.size()));
|
2171
|
+
for (const auto& c : s.collections) {
|
2172
|
+
VALUE collection = rb_hash_new();
|
2173
|
+
rb_hash_aset(collection, rb_id2sym(rb_intern("uid")), ULL2NUM(c.uid));
|
2174
|
+
rb_hash_aset(collection, rb_id2sym(rb_intern("name")), rb_str_new(c.name.data(), static_cast<long>(c.name.size())));
|
2175
|
+
rb_ary_push(collections, collection);
|
2176
|
+
}
|
2177
|
+
rb_hash_aset(scope, rb_id2sym(rb_intern("collections")), collections);
|
2178
|
+
rb_ary_push(scopes, scope);
|
2179
|
+
}
|
2180
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("scopes")), scopes);
|
2181
|
+
|
2182
|
+
return res;
|
2183
|
+
}
|
2184
|
+
|
2185
|
+
static VALUE
|
2186
|
+
cb_Backend_scope_create(VALUE self, VALUE bucket_name, VALUE scope_name)
|
2187
|
+
{
|
2188
|
+
cb_backend_data* backend = nullptr;
|
2189
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2190
|
+
|
2191
|
+
if (!backend->cluster) {
|
2192
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2193
|
+
}
|
2194
|
+
|
2195
|
+
Check_Type(bucket_name, T_STRING);
|
2196
|
+
Check_Type(scope_name, T_STRING);
|
2197
|
+
|
2198
|
+
couchbase::operations::scope_create_request req{};
|
2199
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2200
|
+
req.scope_name.assign(RSTRING_PTR(scope_name), static_cast<size_t>(RSTRING_LEN(scope_name)));
|
2201
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::scope_create_response>>();
|
2202
|
+
auto f = barrier->get_future();
|
2203
|
+
backend->cluster->execute_http(req, [barrier](couchbase::operations::scope_create_response resp) mutable { barrier->set_value(resp); });
|
2204
|
+
auto resp = f.get();
|
2205
|
+
if (resp.ec) {
|
2206
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to create the scope on the bucket \"{}\"", req.bucket_name));
|
2207
|
+
}
|
2208
|
+
return ULL2NUM(resp.uid);
|
2209
|
+
}
|
2210
|
+
|
2211
|
+
static VALUE
|
2212
|
+
cb_Backend_scope_drop(VALUE self, VALUE bucket_name, VALUE scope_name)
|
2213
|
+
{
|
2214
|
+
cb_backend_data* backend = nullptr;
|
2215
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2216
|
+
|
2217
|
+
if (!backend->cluster) {
|
2218
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2219
|
+
}
|
2220
|
+
|
2221
|
+
Check_Type(bucket_name, T_STRING);
|
2222
|
+
Check_Type(scope_name, T_STRING);
|
2223
|
+
|
2224
|
+
couchbase::operations::scope_drop_request req{};
|
2225
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2226
|
+
req.scope_name.assign(RSTRING_PTR(scope_name), static_cast<size_t>(RSTRING_LEN(scope_name)));
|
2227
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::scope_drop_response>>();
|
2228
|
+
auto f = barrier->get_future();
|
2229
|
+
backend->cluster->execute_http(req, [barrier](couchbase::operations::scope_drop_response resp) mutable { barrier->set_value(resp); });
|
2230
|
+
auto resp = f.get();
|
2231
|
+
if (resp.ec) {
|
2232
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to drop the scope \"{}\" on the bucket \"{}\"", req.scope_name, req.bucket_name));
|
2233
|
+
}
|
2234
|
+
return ULL2NUM(resp.uid);
|
2235
|
+
}
|
2236
|
+
|
2237
|
+
static VALUE
|
2238
|
+
cb_Backend_collection_create(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE collection_name, VALUE max_expiry)
|
2239
|
+
{
|
2240
|
+
cb_backend_data* backend = nullptr;
|
2241
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2242
|
+
|
2243
|
+
if (!backend->cluster) {
|
2244
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
899
2245
|
}
|
900
2246
|
|
901
|
-
|
2247
|
+
Check_Type(bucket_name, T_STRING);
|
2248
|
+
Check_Type(scope_name, T_STRING);
|
2249
|
+
Check_Type(collection_name, T_STRING);
|
2250
|
+
|
2251
|
+
couchbase::operations::collection_create_request req{};
|
2252
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2253
|
+
req.scope_name.assign(RSTRING_PTR(scope_name), static_cast<size_t>(RSTRING_LEN(scope_name)));
|
2254
|
+
req.collection_name.assign(RSTRING_PTR(collection_name), static_cast<size_t>(RSTRING_LEN(collection_name)));
|
2255
|
+
|
2256
|
+
if (!NIL_P(max_expiry)) {
|
2257
|
+
Check_Type(max_expiry, T_FIXNUM);
|
2258
|
+
req.max_expiry = FIX2UINT(max_expiry);
|
2259
|
+
}
|
2260
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::collection_create_response>>();
|
902
2261
|
auto f = barrier->get_future();
|
903
|
-
backend->cluster->
|
2262
|
+
backend->cluster->execute_http(req,
|
2263
|
+
[barrier](couchbase::operations::collection_create_response resp) mutable { barrier->set_value(resp); });
|
904
2264
|
auto resp = f.get();
|
905
2265
|
if (resp.ec) {
|
906
|
-
cb_raise_error_code(resp.ec, fmt::format("unable to
|
2266
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to create the collection on the bucket \"{}\"", req.bucket_name));
|
907
2267
|
}
|
2268
|
+
return ULL2NUM(resp.uid);
|
2269
|
+
}
|
908
2270
|
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
2271
|
+
static VALUE
|
2272
|
+
cb_Backend_collection_drop(VALUE self, VALUE bucket_name, VALUE scope_name, VALUE collection_name)
|
2273
|
+
{
|
2274
|
+
cb_backend_data* backend = nullptr;
|
2275
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2276
|
+
|
2277
|
+
if (!backend->cluster) {
|
2278
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
913
2279
|
}
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
2280
|
+
|
2281
|
+
Check_Type(bucket_name, T_STRING);
|
2282
|
+
Check_Type(scope_name, T_STRING);
|
2283
|
+
Check_Type(collection_name, T_STRING);
|
2284
|
+
|
2285
|
+
couchbase::operations::collection_drop_request req{};
|
2286
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2287
|
+
req.scope_name.assign(RSTRING_PTR(scope_name), static_cast<size_t>(RSTRING_LEN(scope_name)));
|
2288
|
+
req.collection_name.assign(RSTRING_PTR(collection_name), static_cast<size_t>(RSTRING_LEN(collection_name)));
|
2289
|
+
|
2290
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::collection_drop_response>>();
|
2291
|
+
auto f = barrier->get_future();
|
2292
|
+
backend->cluster->execute_http(req,
|
2293
|
+
[barrier](couchbase::operations::collection_drop_response resp) mutable { barrier->set_value(resp); });
|
2294
|
+
auto resp = f.get();
|
2295
|
+
if (resp.ec) {
|
2296
|
+
cb_raise_error_code(
|
2297
|
+
resp.ec,
|
2298
|
+
fmt::format(
|
2299
|
+
R"(unable to drop the collection "{}.{}" on the bucket "{}")", req.scope_name, req.collection_name, req.bucket_name));
|
2300
|
+
}
|
2301
|
+
return ULL2NUM(resp.uid);
|
2302
|
+
}
|
2303
|
+
|
2304
|
+
static VALUE
|
2305
|
+
cb_Backend_query_index_get_all(VALUE self, VALUE bucket_name)
|
2306
|
+
{
|
2307
|
+
cb_backend_data* backend = nullptr;
|
2308
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2309
|
+
|
2310
|
+
if (!backend->cluster) {
|
2311
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2312
|
+
}
|
2313
|
+
|
2314
|
+
Check_Type(bucket_name, T_STRING);
|
2315
|
+
|
2316
|
+
couchbase::operations::query_index_get_all_request req{};
|
2317
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2318
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::query_index_get_all_response>>();
|
2319
|
+
auto f = barrier->get_future();
|
2320
|
+
backend->cluster->execute_http(
|
2321
|
+
req, [barrier](couchbase::operations::query_index_get_all_response resp) mutable { barrier->set_value(resp); });
|
2322
|
+
auto resp = f.get();
|
2323
|
+
if (resp.ec) {
|
2324
|
+
cb_raise_error_code(resp.ec, fmt::format("unable to get list of the indexes of the bucket \"{}\"", req.bucket_name));
|
2325
|
+
}
|
2326
|
+
|
2327
|
+
VALUE res = rb_hash_new();
|
2328
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_str_new(resp.status.data(), static_cast<long>(resp.status.size())));
|
2329
|
+
VALUE indexes = rb_ary_new_capa(static_cast<long>(resp.indexes.size()));
|
2330
|
+
for (const auto& idx : resp.indexes) {
|
2331
|
+
VALUE index = rb_hash_new();
|
2332
|
+
rb_hash_aset(index, rb_id2sym(rb_intern("id")), rb_str_new(idx.id.data(), static_cast<long>(idx.id.size())));
|
2333
|
+
rb_hash_aset(index, rb_id2sym(rb_intern("state")), rb_str_new(idx.state.data(), static_cast<long>(idx.state.size())));
|
2334
|
+
rb_hash_aset(index, rb_id2sym(rb_intern("name")), rb_str_new(idx.name.data(), static_cast<long>(idx.name.size())));
|
918
2335
|
rb_hash_aset(
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
2336
|
+
index, rb_id2sym(rb_intern("datastore_id")), rb_str_new(idx.datastore_id.data(), static_cast<long>(idx.datastore_id.size())));
|
2337
|
+
rb_hash_aset(
|
2338
|
+
index, rb_id2sym(rb_intern("keyspace_id")), rb_str_new(idx.keyspace_id.data(), static_cast<long>(idx.keyspace_id.size())));
|
2339
|
+
rb_hash_aset(
|
2340
|
+
index, rb_id2sym(rb_intern("namespace_id")), rb_str_new(idx.namespace_id.data(), static_cast<long>(idx.namespace_id.size())));
|
2341
|
+
rb_hash_aset(index, rb_id2sym(rb_intern("type")), rb_str_new(idx.type.data(), static_cast<long>(idx.type.size())));
|
2342
|
+
rb_hash_aset(index, rb_id2sym(rb_intern("is_primary")), idx.is_primary ? Qtrue : Qfalse);
|
2343
|
+
VALUE index_key = rb_ary_new_capa(static_cast<long>(idx.index_key.size()));
|
2344
|
+
for (const auto& key : idx.index_key) {
|
2345
|
+
rb_ary_push(index_key, rb_str_new(key.data(), static_cast<long>(key.size())));
|
926
2346
|
}
|
927
|
-
rb_hash_aset(
|
928
|
-
|
929
|
-
|
2347
|
+
rb_hash_aset(index, rb_id2sym(rb_intern("index_key")), index_key);
|
2348
|
+
if (idx.condition) {
|
2349
|
+
rb_hash_aset(
|
2350
|
+
index, rb_id2sym(rb_intern("condition")), rb_str_new(idx.condition->data(), static_cast<long>(idx.condition->size())));
|
2351
|
+
}
|
2352
|
+
rb_ary_push(indexes, index);
|
930
2353
|
}
|
2354
|
+
|
2355
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("indexes")), indexes);
|
2356
|
+
|
931
2357
|
return res;
|
932
2358
|
}
|
933
2359
|
|
934
|
-
static
|
935
|
-
|
2360
|
+
static VALUE
|
2361
|
+
cb_Backend_query_index_create(VALUE self, VALUE bucket_name, VALUE index_name, VALUE fields, VALUE options)
|
936
2362
|
{
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
2363
|
+
cb_backend_data* backend = nullptr;
|
2364
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2365
|
+
|
2366
|
+
if (!backend->cluster) {
|
2367
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
2368
|
+
}
|
2369
|
+
|
2370
|
+
Check_Type(bucket_name, T_STRING);
|
2371
|
+
Check_Type(index_name, T_STRING);
|
2372
|
+
Check_Type(fields, T_ARRAY);
|
2373
|
+
|
2374
|
+
couchbase::operations::query_index_create_request req{};
|
2375
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2376
|
+
req.index_name.assign(RSTRING_PTR(index_name), static_cast<size_t>(RSTRING_LEN(index_name)));
|
2377
|
+
auto fields_num = static_cast<size_t>(RARRAY_LEN(fields));
|
2378
|
+
req.fields.reserve(fields_num);
|
2379
|
+
for (size_t i = 0; i < fields_num; ++i) {
|
2380
|
+
VALUE entry = rb_ary_entry(fields, static_cast<long>(i));
|
2381
|
+
Check_Type(entry, T_STRING);
|
2382
|
+
req.fields.emplace_back(RSTRING_PTR(entry), static_cast<std::size_t>(RSTRING_LEN(entry)));
|
2383
|
+
}
|
2384
|
+
if (!NIL_P(options)) {
|
2385
|
+
Check_Type(options, T_HASH);
|
2386
|
+
VALUE ignore_if_exists = rb_hash_aref(options, rb_id2sym(rb_intern("ignore_if_exists")));
|
2387
|
+
if (ignore_if_exists == Qtrue) {
|
2388
|
+
req.ignore_if_exists = true;
|
2389
|
+
} else if (ignore_if_exists == Qfalse) {
|
2390
|
+
req.ignore_if_exists = false;
|
2391
|
+
} /* else use backend default */
|
2392
|
+
VALUE deferred = rb_hash_aref(options, rb_id2sym(rb_intern("deferred")));
|
2393
|
+
if (deferred == Qtrue) {
|
2394
|
+
req.deferred = true;
|
2395
|
+
} else if (deferred == Qfalse) {
|
2396
|
+
req.deferred = false;
|
2397
|
+
} /* else use backend default */
|
2398
|
+
VALUE num_replicas = rb_hash_aref(options, rb_id2sym(rb_intern("num_replicas")));
|
2399
|
+
if (!NIL_P(num_replicas)) {
|
2400
|
+
req.num_replicas = NUM2UINT(num_replicas);
|
2401
|
+
} /* else use backend default */
|
2402
|
+
VALUE condition = rb_hash_aref(options, rb_id2sym(rb_intern("condition")));
|
2403
|
+
if (!NIL_P(condition)) {
|
2404
|
+
req.condition.emplace(std::string(RSTRING_PTR(condition), static_cast<std::size_t>(RSTRING_LEN(condition))));
|
2405
|
+
} /* else use backend default */
|
2406
|
+
}
|
2407
|
+
|
2408
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::query_index_create_response>>();
|
2409
|
+
auto f = barrier->get_future();
|
2410
|
+
backend->cluster->execute_http(
|
2411
|
+
req, [barrier](couchbase::operations::query_index_create_response resp) mutable { barrier->set_value(resp); });
|
2412
|
+
auto resp = f.get();
|
2413
|
+
if (resp.ec) {
|
2414
|
+
if (!resp.errors.empty()) {
|
2415
|
+
const auto& first_error = resp.errors.front();
|
2416
|
+
cb_raise_error_code(resp.ec,
|
2417
|
+
fmt::format(R"(unable to create index "{}" on the bucket "{}" ({}: {}))",
|
2418
|
+
req.index_name,
|
2419
|
+
req.bucket_name,
|
2420
|
+
first_error.code,
|
2421
|
+
first_error.message));
|
2422
|
+
} else {
|
2423
|
+
cb_raise_error_code(resp.ec, fmt::format(R"(unable to create index "{}" on the bucket "{}")", req.index_name, req.bucket_name));
|
2424
|
+
}
|
2425
|
+
}
|
2426
|
+
VALUE res = rb_hash_new();
|
2427
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_str_new(resp.status.data(), static_cast<long>(resp.status.size())));
|
2428
|
+
if (!resp.errors.empty()) {
|
2429
|
+
VALUE errors = rb_ary_new_capa(static_cast<long>(resp.errors.size()));
|
2430
|
+
for (const auto& err : resp.errors) {
|
2431
|
+
VALUE error = rb_hash_new();
|
2432
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("code")), ULL2NUM(err.code));
|
2433
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("message")), rb_str_new(err.message.data(), static_cast<long>(err.message.size())));
|
2434
|
+
rb_ary_push(errors, error);
|
2435
|
+
}
|
2436
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("errors")), errors);
|
2437
|
+
}
|
2438
|
+
return res;
|
944
2439
|
}
|
945
2440
|
|
946
2441
|
static VALUE
|
947
|
-
|
2442
|
+
cb_Backend_query_index_drop(VALUE self, VALUE bucket_name, VALUE index_name, VALUE options)
|
948
2443
|
{
|
949
2444
|
cb_backend_data* backend = nullptr;
|
950
2445
|
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
@@ -953,114 +2448,247 @@ cb_Backend_query(VALUE self, VALUE statement, VALUE options)
|
|
953
2448
|
rb_raise(rb_eArgError, "Cluster has been closed already");
|
954
2449
|
}
|
955
2450
|
|
956
|
-
Check_Type(
|
957
|
-
Check_Type(
|
2451
|
+
Check_Type(bucket_name, T_STRING);
|
2452
|
+
Check_Type(index_name, T_STRING);
|
2453
|
+
|
2454
|
+
couchbase::operations::query_index_drop_request req{};
|
2455
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2456
|
+
req.index_name.assign(RSTRING_PTR(index_name), static_cast<size_t>(RSTRING_LEN(index_name)));
|
2457
|
+
if (!NIL_P(options)) {
|
2458
|
+
Check_Type(options, T_HASH);
|
2459
|
+
VALUE ignore_if_does_not_exist = rb_hash_aref(options, rb_id2sym(rb_intern("ignore_if_does_not_exist")));
|
2460
|
+
if (ignore_if_does_not_exist == Qtrue) {
|
2461
|
+
req.ignore_if_does_not_exist = true;
|
2462
|
+
} else if (ignore_if_does_not_exist == Qfalse) {
|
2463
|
+
req.ignore_if_does_not_exist = false;
|
2464
|
+
} /* else use backend default */
|
2465
|
+
}
|
958
2466
|
|
959
|
-
couchbase::operations::
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
2467
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::query_index_drop_response>>();
|
2468
|
+
auto f = barrier->get_future();
|
2469
|
+
backend->cluster->execute_http(req,
|
2470
|
+
[barrier](couchbase::operations::query_index_drop_response resp) mutable { barrier->set_value(resp); });
|
2471
|
+
auto resp = f.get();
|
2472
|
+
if (resp.ec) {
|
2473
|
+
if (!resp.errors.empty()) {
|
2474
|
+
const auto& first_error = resp.errors.front();
|
2475
|
+
cb_raise_error_code(resp.ec,
|
2476
|
+
fmt::format(R"(unable to drop index "{}" on the bucket "{}" ({}: {}))",
|
2477
|
+
req.index_name,
|
2478
|
+
req.bucket_name,
|
2479
|
+
first_error.code,
|
2480
|
+
first_error.message));
|
2481
|
+
} else {
|
2482
|
+
cb_raise_error_code(resp.ec, fmt::format(R"(unable to drop index "{}" on the bucket "{}")", req.index_name, req.bucket_name));
|
2483
|
+
}
|
964
2484
|
}
|
965
|
-
VALUE
|
966
|
-
|
967
|
-
|
2485
|
+
VALUE res = rb_hash_new();
|
2486
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_str_new(resp.status.data(), static_cast<long>(resp.status.size())));
|
2487
|
+
if (!resp.errors.empty()) {
|
2488
|
+
VALUE errors = rb_ary_new_capa(static_cast<long>(resp.errors.size()));
|
2489
|
+
for (const auto& err : resp.errors) {
|
2490
|
+
VALUE error = rb_hash_new();
|
2491
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("code")), ULL2NUM(err.code));
|
2492
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("message")), rb_str_new(err.message.data(), static_cast<long>(err.message.size())));
|
2493
|
+
rb_ary_push(errors, error);
|
2494
|
+
}
|
2495
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("errors")), errors);
|
968
2496
|
}
|
969
|
-
|
970
|
-
|
971
|
-
|
2497
|
+
return res;
|
2498
|
+
}
|
2499
|
+
|
2500
|
+
static VALUE
|
2501
|
+
cb_Backend_query_index_create_primary(VALUE self, VALUE bucket_name, VALUE options)
|
2502
|
+
{
|
2503
|
+
cb_backend_data* backend = nullptr;
|
2504
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2505
|
+
|
2506
|
+
if (!backend->cluster) {
|
2507
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
972
2508
|
}
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
2509
|
+
|
2510
|
+
Check_Type(bucket_name, T_STRING);
|
2511
|
+
if (!NIL_P(options)) {
|
2512
|
+
Check_Type(options, T_HASH);
|
2513
|
+
}
|
2514
|
+
|
2515
|
+
couchbase::operations::query_index_create_request req{};
|
2516
|
+
req.is_primary = true;
|
2517
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2518
|
+
if (!NIL_P(options)) {
|
2519
|
+
Check_Type(options, T_HASH);
|
2520
|
+
VALUE ignore_if_exists = rb_hash_aref(options, rb_id2sym(rb_intern("ignore_if_exists")));
|
2521
|
+
if (ignore_if_exists == Qtrue) {
|
2522
|
+
req.ignore_if_exists = true;
|
2523
|
+
} else if (ignore_if_exists == Qfalse) {
|
2524
|
+
req.ignore_if_exists = false;
|
2525
|
+
} /* else use backend default */
|
2526
|
+
VALUE deferred = rb_hash_aref(options, rb_id2sym(rb_intern("deferred")));
|
2527
|
+
if (deferred == Qtrue) {
|
2528
|
+
req.deferred = true;
|
2529
|
+
} else if (deferred == Qfalse) {
|
2530
|
+
req.deferred = false;
|
2531
|
+
} /* else use backend default */
|
2532
|
+
VALUE num_replicas = rb_hash_aref(options, rb_id2sym(rb_intern("num_replicas")));
|
2533
|
+
if (!NIL_P(num_replicas)) {
|
2534
|
+
req.num_replicas = NUM2UINT(num_replicas);
|
2535
|
+
} /* else use backend default */
|
2536
|
+
VALUE index_name = rb_hash_aref(options, rb_id2sym(rb_intern("index_name")));
|
2537
|
+
if (!NIL_P(index_name)) {
|
2538
|
+
req.index_name.assign(RSTRING_PTR(index_name), static_cast<size_t>(RSTRING_LEN(index_name)));
|
2539
|
+
} /* else use backend default */
|
2540
|
+
}
|
2541
|
+
|
2542
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::query_index_create_response>>();
|
2543
|
+
auto f = barrier->get_future();
|
2544
|
+
backend->cluster->execute_http(
|
2545
|
+
req, [barrier](couchbase::operations::query_index_create_response resp) mutable { barrier->set_value(resp); });
|
2546
|
+
auto resp = f.get();
|
2547
|
+
if (resp.ec) {
|
2548
|
+
if (!resp.errors.empty()) {
|
2549
|
+
const auto& first_error = resp.errors.front();
|
2550
|
+
cb_raise_error_code(
|
2551
|
+
resp.ec,
|
2552
|
+
fmt::format(
|
2553
|
+
R"(unable to create primary index on the bucket "{}" ({}: {}))", req.bucket_name, first_error.code, first_error.message));
|
2554
|
+
} else {
|
2555
|
+
cb_raise_error_code(resp.ec,
|
2556
|
+
fmt::format(R"(unable to create primary index on the bucket "{}")", req.index_name, req.bucket_name));
|
983
2557
|
}
|
984
2558
|
}
|
985
|
-
VALUE
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
tao::json::from_string(std::string_view(RSTRING_PTR(entry), static_cast<std::size_t>(RSTRING_LEN(entry)))));
|
2559
|
+
VALUE res = rb_hash_new();
|
2560
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_str_new(resp.status.data(), static_cast<long>(resp.status.size())));
|
2561
|
+
if (!resp.errors.empty()) {
|
2562
|
+
VALUE errors = rb_ary_new_capa(static_cast<long>(resp.errors.size()));
|
2563
|
+
for (const auto& err : resp.errors) {
|
2564
|
+
VALUE error = rb_hash_new();
|
2565
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("code")), ULL2NUM(err.code));
|
2566
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("message")), rb_str_new(err.message.data(), static_cast<long>(err.message.size())));
|
2567
|
+
rb_ary_push(errors, error);
|
995
2568
|
}
|
2569
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("errors")), errors);
|
996
2570
|
}
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
2571
|
+
return res;
|
2572
|
+
}
|
2573
|
+
|
2574
|
+
static VALUE
|
2575
|
+
cb_Backend_query_index_drop_primary(VALUE self, VALUE bucket_name, VALUE options)
|
2576
|
+
{
|
2577
|
+
cb_backend_data* backend = nullptr;
|
2578
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2579
|
+
|
2580
|
+
if (!backend->cluster) {
|
2581
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1001
2582
|
}
|
1002
2583
|
|
1003
|
-
|
2584
|
+
Check_Type(bucket_name, T_STRING);
|
2585
|
+
|
2586
|
+
couchbase::operations::query_index_drop_request req{};
|
2587
|
+
req.is_primary = true;
|
2588
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2589
|
+
if (!NIL_P(options)) {
|
2590
|
+
Check_Type(options, T_HASH);
|
2591
|
+
VALUE ignore_if_does_not_exist = rb_hash_aref(options, rb_id2sym(rb_intern("ignore_if_does_not_exist")));
|
2592
|
+
if (ignore_if_does_not_exist == Qtrue) {
|
2593
|
+
req.ignore_if_does_not_exist = true;
|
2594
|
+
} else if (ignore_if_does_not_exist == Qfalse) {
|
2595
|
+
req.ignore_if_does_not_exist = false;
|
2596
|
+
} /* else use backend default */
|
2597
|
+
VALUE index_name = rb_hash_aref(options, rb_id2sym(rb_intern("index_name")));
|
2598
|
+
if (!NIL_P(index_name)) {
|
2599
|
+
Check_Type(options, T_STRING);
|
2600
|
+
req.is_primary = false;
|
2601
|
+
req.bucket_name.assign(RSTRING_PTR(index_name), static_cast<size_t>(RSTRING_LEN(index_name)));
|
2602
|
+
}
|
2603
|
+
}
|
2604
|
+
|
2605
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::query_index_drop_response>>();
|
1004
2606
|
auto f = barrier->get_future();
|
1005
|
-
backend->cluster->
|
2607
|
+
backend->cluster->execute_http(req,
|
2608
|
+
[barrier](couchbase::operations::query_index_drop_response resp) mutable { barrier->set_value(resp); });
|
1006
2609
|
auto resp = f.get();
|
1007
2610
|
if (resp.ec) {
|
1008
|
-
|
2611
|
+
if (!resp.errors.empty()) {
|
2612
|
+
const auto& first_error = resp.errors.front();
|
2613
|
+
cb_raise_error_code(
|
2614
|
+
resp.ec,
|
2615
|
+
fmt::format(
|
2616
|
+
R"(unable to drop primary index on the bucket "{}" ({}: {}))", req.bucket_name, first_error.code, first_error.message));
|
2617
|
+
} else {
|
2618
|
+
cb_raise_error_code(resp.ec, fmt::format(R"(unable to drop primary index on the bucket "{}")", req.bucket_name));
|
2619
|
+
}
|
1009
2620
|
}
|
1010
2621
|
VALUE res = rb_hash_new();
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
rb_hash_aset(meta,
|
1022
|
-
rb_id2sym(rb_intern("request_id")),
|
1023
|
-
rb_str_new(resp.payload.meta_data.request_id.data(), static_cast<long>(resp.payload.meta_data.request_id.size())));
|
1024
|
-
rb_hash_aset(
|
1025
|
-
meta,
|
1026
|
-
rb_id2sym(rb_intern("client_context_id")),
|
1027
|
-
rb_str_new(resp.payload.meta_data.client_context_id.data(), static_cast<long>(resp.payload.meta_data.client_context_id.size())));
|
1028
|
-
if (resp.payload.meta_data.signature) {
|
1029
|
-
rb_hash_aset(meta,
|
1030
|
-
rb_id2sym(rb_intern("signature")),
|
1031
|
-
rb_str_new(resp.payload.meta_data.signature->data(), static_cast<long>(resp.payload.meta_data.signature->size())));
|
2622
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("status")), rb_str_new(resp.status.data(), static_cast<long>(resp.status.size())));
|
2623
|
+
if (!resp.errors.empty()) {
|
2624
|
+
VALUE errors = rb_ary_new_capa(static_cast<long>(resp.errors.size()));
|
2625
|
+
for (const auto& err : resp.errors) {
|
2626
|
+
VALUE error = rb_hash_new();
|
2627
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("code")), ULL2NUM(err.code));
|
2628
|
+
rb_hash_aset(error, rb_id2sym(rb_intern("message")), rb_str_new(err.message.data(), static_cast<long>(err.message.size())));
|
2629
|
+
rb_ary_push(errors, error);
|
2630
|
+
}
|
2631
|
+
rb_hash_aset(res, rb_id2sym(rb_intern("errors")), errors);
|
1032
2632
|
}
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
2633
|
+
return res;
|
2634
|
+
}
|
2635
|
+
|
2636
|
+
static VALUE
|
2637
|
+
cb_Backend_query_index_build_deferred(VALUE self, VALUE bucket_name, VALUE options)
|
2638
|
+
{
|
2639
|
+
cb_backend_data* backend = nullptr;
|
2640
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2641
|
+
|
2642
|
+
if (!backend->cluster) {
|
2643
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1037
2644
|
}
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
rb_str_new(resp.payload.meta_data.metrics.elapsed_time.data(),
|
1043
|
-
static_cast<long>(resp.payload.meta_data.metrics.elapsed_time.size())));
|
1044
|
-
rb_hash_aset(metrics,
|
1045
|
-
rb_id2sym(rb_intern("execution_time")),
|
1046
|
-
rb_str_new(resp.payload.meta_data.metrics.execution_time.data(),
|
1047
|
-
static_cast<long>(resp.payload.meta_data.metrics.execution_time.size())));
|
1048
|
-
rb_hash_aset(metrics, rb_id2sym(rb_intern("result_count")), ULL2NUM(resp.payload.meta_data.metrics.result_count));
|
1049
|
-
rb_hash_aset(metrics, rb_id2sym(rb_intern("result_size")), ULL2NUM(resp.payload.meta_data.metrics.result_count));
|
1050
|
-
if (resp.payload.meta_data.metrics.sort_count) {
|
1051
|
-
rb_hash_aset(metrics, rb_id2sym(rb_intern("sort_count")), ULL2NUM(*resp.payload.meta_data.metrics.sort_count));
|
2645
|
+
|
2646
|
+
Check_Type(bucket_name, T_STRING);
|
2647
|
+
if (!NIL_P(options)) {
|
2648
|
+
Check_Type(options, T_HASH);
|
1052
2649
|
}
|
1053
|
-
|
1054
|
-
|
2650
|
+
|
2651
|
+
couchbase::operations::query_index_build_deferred_request req{};
|
2652
|
+
req.bucket_name.assign(RSTRING_PTR(bucket_name), static_cast<size_t>(RSTRING_LEN(bucket_name)));
|
2653
|
+
auto barrier = std::make_shared<std::promise<couchbase::operations::query_index_build_deferred_response>>();
|
2654
|
+
auto f = barrier->get_future();
|
2655
|
+
backend->cluster->execute_http(
|
2656
|
+
req, [barrier](couchbase::operations::query_index_build_deferred_response resp) mutable { barrier->set_value(resp); });
|
2657
|
+
auto resp = f.get();
|
2658
|
+
if (resp.ec) {
|
2659
|
+
if (!resp.errors.empty()) {
|
2660
|
+
const auto& first_error = resp.errors.front();
|
2661
|
+
cb_raise_error_code(
|
2662
|
+
resp.ec,
|
2663
|
+
fmt::format(
|
2664
|
+
R"(unable to drop primary index on the bucket "{}" ({}: {}))", req.bucket_name, first_error.code, first_error.message));
|
2665
|
+
|
2666
|
+
} else {
|
2667
|
+
cb_raise_error_code(resp.ec,
|
2668
|
+
fmt::format("unable to trigger build for deferred indexes for the bucket \"{}\"", req.bucket_name));
|
2669
|
+
}
|
1055
2670
|
}
|
1056
|
-
|
1057
|
-
|
2671
|
+
return Qtrue;
|
2672
|
+
}
|
2673
|
+
|
2674
|
+
static VALUE
|
2675
|
+
cb_Backend_query_index_watch(VALUE self, VALUE bucket_name, VALUE index_names, VALUE timeout, VALUE options)
|
2676
|
+
{
|
2677
|
+
cb_backend_data* backend = nullptr;
|
2678
|
+
TypedData_Get_Struct(self, cb_backend_data, &cb_backend_type, backend);
|
2679
|
+
|
2680
|
+
if (!backend->cluster) {
|
2681
|
+
rb_raise(rb_eArgError, "Cluster has been closed already");
|
1058
2682
|
}
|
1059
|
-
|
1060
|
-
|
2683
|
+
|
2684
|
+
Check_Type(bucket_name, T_STRING);
|
2685
|
+
Check_Type(index_names, T_ARRAY);
|
2686
|
+
Check_Type(timeout, T_FIXNUM);
|
2687
|
+
if (!NIL_P(options)) {
|
2688
|
+
Check_Type(options, T_HASH);
|
1061
2689
|
}
|
1062
2690
|
|
1063
|
-
return
|
2691
|
+
return Qtrue;
|
1064
2692
|
}
|
1065
2693
|
|
1066
2694
|
static void
|
@@ -1071,12 +2699,45 @@ init_backend(VALUE mCouchbase)
|
|
1071
2699
|
rb_define_method(cBackend, "open", VALUE_FUNC(cb_Backend_open), 3);
|
1072
2700
|
rb_define_method(cBackend, "close", VALUE_FUNC(cb_Backend_close), 0);
|
1073
2701
|
rb_define_method(cBackend, "open_bucket", VALUE_FUNC(cb_Backend_open_bucket), 1);
|
1074
|
-
|
1075
|
-
rb_define_method(cBackend, "
|
1076
|
-
rb_define_method(cBackend, "
|
1077
|
-
rb_define_method(cBackend, "
|
1078
|
-
rb_define_method(cBackend, "
|
1079
|
-
rb_define_method(cBackend, "
|
2702
|
+
|
2703
|
+
rb_define_method(cBackend, "document_get", VALUE_FUNC(cb_Backend_document_get), 3);
|
2704
|
+
rb_define_method(cBackend, "document_get_and_lock", VALUE_FUNC(cb_Backend_document_get_and_lock), 4);
|
2705
|
+
rb_define_method(cBackend, "document_get_and_touch", VALUE_FUNC(cb_Backend_document_get_and_touch), 4);
|
2706
|
+
rb_define_method(cBackend, "document_insert", VALUE_FUNC(cb_Backend_document_insert), 6);
|
2707
|
+
rb_define_method(cBackend, "document_replace", VALUE_FUNC(cb_Backend_document_replace), 6);
|
2708
|
+
rb_define_method(cBackend, "document_upsert", VALUE_FUNC(cb_Backend_document_upsert), 6);
|
2709
|
+
rb_define_method(cBackend, "document_remove", VALUE_FUNC(cb_Backend_document_remove), 4);
|
2710
|
+
rb_define_method(cBackend, "document_lookup_in", VALUE_FUNC(cb_Backend_document_lookup_in), 5);
|
2711
|
+
rb_define_method(cBackend, "document_mutate_in", VALUE_FUNC(cb_Backend_document_mutate_in), 6);
|
2712
|
+
rb_define_method(cBackend, "document_query", VALUE_FUNC(cb_Backend_document_query), 2);
|
2713
|
+
rb_define_method(cBackend, "document_touch", VALUE_FUNC(cb_Backend_document_touch), 4);
|
2714
|
+
rb_define_method(cBackend, "document_exists", VALUE_FUNC(cb_Backend_document_exists), 3);
|
2715
|
+
rb_define_method(cBackend, "document_unlock", VALUE_FUNC(cb_Backend_document_unlock), 4);
|
2716
|
+
rb_define_method(cBackend, "document_increment", VALUE_FUNC(cb_Backend_document_increment), 4);
|
2717
|
+
rb_define_method(cBackend, "document_decrement", VALUE_FUNC(cb_Backend_document_decrement), 4);
|
2718
|
+
|
2719
|
+
rb_define_method(cBackend, "bucket_create", VALUE_FUNC(cb_Backend_bucket_create), 1);
|
2720
|
+
rb_define_method(cBackend, "bucket_update", VALUE_FUNC(cb_Backend_bucket_update), 1);
|
2721
|
+
rb_define_method(cBackend, "bucket_drop", VALUE_FUNC(cb_Backend_bucket_drop), 1);
|
2722
|
+
rb_define_method(cBackend, "bucket_flush", VALUE_FUNC(cb_Backend_bucket_flush), 1);
|
2723
|
+
rb_define_method(cBackend, "bucket_get_all", VALUE_FUNC(cb_Backend_bucket_get_all), 0);
|
2724
|
+
rb_define_method(cBackend, "bucket_get", VALUE_FUNC(cb_Backend_bucket_get), 1);
|
2725
|
+
|
2726
|
+
rb_define_method(cBackend, "cluster_enable_developer_preview!", VALUE_FUNC(cb_Backend_cluster_enable_developer_preview), 0);
|
2727
|
+
|
2728
|
+
rb_define_method(cBackend, "scope_get_all", VALUE_FUNC(cb_Backend_scope_get_all), 1);
|
2729
|
+
rb_define_method(cBackend, "scope_create", VALUE_FUNC(cb_Backend_scope_create), 2);
|
2730
|
+
rb_define_method(cBackend, "scope_drop", VALUE_FUNC(cb_Backend_scope_drop), 2);
|
2731
|
+
rb_define_method(cBackend, "collection_create", VALUE_FUNC(cb_Backend_collection_create), 4);
|
2732
|
+
rb_define_method(cBackend, "collection_drop", VALUE_FUNC(cb_Backend_collection_drop), 3);
|
2733
|
+
|
2734
|
+
rb_define_method(cBackend, "query_index_get_all", VALUE_FUNC(cb_Backend_query_index_get_all), 1);
|
2735
|
+
rb_define_method(cBackend, "query_index_create", VALUE_FUNC(cb_Backend_query_index_create), 4);
|
2736
|
+
rb_define_method(cBackend, "query_index_create_primary", VALUE_FUNC(cb_Backend_query_index_create_primary), 2);
|
2737
|
+
rb_define_method(cBackend, "query_index_drop", VALUE_FUNC(cb_Backend_query_index_drop), 3);
|
2738
|
+
rb_define_method(cBackend, "query_index_drop_primary", VALUE_FUNC(cb_Backend_query_index_drop_primary), 2);
|
2739
|
+
rb_define_method(cBackend, "query_index_build_deferred", VALUE_FUNC(cb_Backend_query_index_build_deferred), 2);
|
2740
|
+
rb_define_method(cBackend, "query_index_watch", VALUE_FUNC(cb_Backend_query_index_watch), 4);
|
1080
2741
|
}
|
1081
2742
|
|
1082
2743
|
extern "C" {
|