couchbase 3.0.1 → 3.0.2

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.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +73 -4
  3. data/ext/build_config.hxx.in +2 -0
  4. data/ext/build_version.hxx.in +11 -8
  5. data/ext/cmake/BuildTracing.cmake +1 -1
  6. data/ext/cmake/CompilerWarnings.cmake +5 -0
  7. data/ext/cmake/Testing.cmake +3 -6
  8. data/ext/couchbase/bucket.hxx +9 -1
  9. data/ext/couchbase/cbsasl/client.h +1 -1
  10. data/ext/couchbase/cluster.hxx +89 -6
  11. data/ext/couchbase/configuration.hxx +2 -0
  12. data/ext/couchbase/couchbase.cxx +1647 -507
  13. data/ext/couchbase/diagnostics.hxx +0 -3
  14. data/ext/couchbase/io/dns_client.hxx +2 -2
  15. data/ext/couchbase/io/http_command.hxx +6 -3
  16. data/ext/couchbase/io/http_session.hxx +14 -18
  17. data/ext/couchbase/io/http_session_manager.hxx +83 -2
  18. data/ext/couchbase/io/mcbp_command.hxx +4 -1
  19. data/ext/couchbase/io/mcbp_context.hxx +37 -0
  20. data/ext/couchbase/io/mcbp_session.hxx +91 -30
  21. data/ext/couchbase/operations.hxx +5 -0
  22. data/ext/couchbase/operations/analytics_dataset_create.hxx +3 -2
  23. data/ext/couchbase/operations/analytics_dataset_drop.hxx +3 -2
  24. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +3 -2
  25. data/ext/couchbase/operations/analytics_dataverse_create.hxx +3 -2
  26. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +3 -2
  27. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +3 -2
  28. data/ext/couchbase/operations/analytics_index_create.hxx +3 -2
  29. data/ext/couchbase/operations/analytics_index_drop.hxx +3 -2
  30. data/ext/couchbase/operations/analytics_index_get_all.hxx +5 -2
  31. data/ext/couchbase/operations/analytics_link_connect.hxx +3 -2
  32. data/ext/couchbase/operations/analytics_link_disconnect.hxx +3 -2
  33. data/ext/couchbase/operations/bucket_create.hxx +3 -2
  34. data/ext/couchbase/operations/bucket_drop.hxx +3 -2
  35. data/ext/couchbase/operations/bucket_flush.hxx +3 -2
  36. data/ext/couchbase/operations/bucket_get.hxx +3 -2
  37. data/ext/couchbase/operations/bucket_get_all.hxx +3 -2
  38. data/ext/couchbase/operations/bucket_update.hxx +3 -2
  39. data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +3 -2
  40. data/ext/couchbase/operations/collection_create.hxx +3 -2
  41. data/ext/couchbase/operations/collection_drop.hxx +3 -2
  42. data/ext/couchbase/operations/collections_manifest_get.hxx +3 -2
  43. data/ext/couchbase/operations/document_analytics.hxx +3 -2
  44. data/ext/couchbase/operations/document_append.hxx +77 -0
  45. data/ext/couchbase/operations/document_decrement.hxx +3 -2
  46. data/ext/couchbase/operations/document_exists.hxx +3 -2
  47. data/ext/couchbase/operations/document_get.hxx +3 -2
  48. data/ext/couchbase/operations/document_get_and_lock.hxx +3 -2
  49. data/ext/couchbase/operations/document_get_and_touch.hxx +3 -2
  50. data/ext/couchbase/operations/document_get_projected.hxx +3 -2
  51. data/ext/couchbase/operations/document_increment.hxx +3 -2
  52. data/ext/couchbase/operations/document_insert.hxx +3 -2
  53. data/ext/couchbase/operations/document_lookup_in.hxx +8 -2
  54. data/ext/couchbase/operations/document_mutate_in.hxx +13 -2
  55. data/ext/couchbase/operations/document_prepend.hxx +77 -0
  56. data/ext/couchbase/operations/document_query.hxx +3 -2
  57. data/ext/couchbase/operations/document_remove.hxx +5 -2
  58. data/ext/couchbase/operations/document_replace.hxx +3 -2
  59. data/ext/couchbase/operations/document_search.hxx +3 -2
  60. data/ext/couchbase/operations/document_touch.hxx +3 -2
  61. data/ext/couchbase/operations/document_unlock.hxx +3 -2
  62. data/ext/couchbase/operations/document_upsert.hxx +3 -2
  63. data/ext/couchbase/operations/document_view.hxx +3 -2
  64. data/ext/couchbase/operations/group_drop.hxx +3 -2
  65. data/ext/couchbase/operations/group_get.hxx +3 -2
  66. data/ext/couchbase/operations/group_get_all.hxx +3 -2
  67. data/ext/couchbase/operations/group_upsert.hxx +3 -2
  68. data/ext/couchbase/operations/http_noop.hxx +78 -0
  69. data/ext/couchbase/operations/mcbp_noop.hxx +61 -0
  70. data/ext/couchbase/operations/query_index_build_deferred.hxx +3 -2
  71. data/ext/couchbase/operations/query_index_create.hxx +3 -2
  72. data/ext/couchbase/operations/query_index_drop.hxx +3 -2
  73. data/ext/couchbase/operations/query_index_get_all.hxx +3 -2
  74. data/ext/couchbase/operations/role_get_all.hxx +3 -2
  75. data/ext/couchbase/operations/scope_create.hxx +3 -2
  76. data/ext/couchbase/operations/scope_drop.hxx +3 -2
  77. data/ext/couchbase/operations/scope_get_all.hxx +3 -2
  78. data/ext/couchbase/operations/search_get_stats.hxx +3 -2
  79. data/ext/couchbase/operations/search_index_analyze_document.hxx +3 -2
  80. data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -2
  81. data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +3 -2
  82. data/ext/couchbase/operations/search_index_control_query.hxx +3 -2
  83. data/ext/couchbase/operations/search_index_drop.hxx +3 -2
  84. data/ext/couchbase/operations/search_index_get.hxx +3 -2
  85. data/ext/couchbase/operations/search_index_get_all.hxx +3 -2
  86. data/ext/couchbase/operations/search_index_get_documents_count.hxx +3 -2
  87. data/ext/couchbase/operations/search_index_get_stats.hxx +3 -2
  88. data/ext/couchbase/operations/search_index_upsert.hxx +3 -2
  89. data/ext/couchbase/operations/user_drop.hxx +3 -2
  90. data/ext/couchbase/operations/user_get.hxx +3 -2
  91. data/ext/couchbase/operations/user_get_all.hxx +3 -2
  92. data/ext/couchbase/operations/user_upsert.hxx +3 -2
  93. data/ext/couchbase/operations/view_index_drop.hxx +3 -2
  94. data/ext/couchbase/operations/view_index_get.hxx +3 -2
  95. data/ext/couchbase/operations/view_index_get_all.hxx +3 -2
  96. data/ext/couchbase/operations/view_index_upsert.hxx +3 -2
  97. data/ext/couchbase/platform/terminate_handler.cc +5 -2
  98. data/ext/couchbase/protocol/client_opcode.hxx +368 -0
  99. data/ext/couchbase/protocol/cmd_append.hxx +145 -0
  100. data/ext/couchbase/protocol/cmd_hello.hxx +1 -0
  101. data/ext/couchbase/protocol/cmd_lookup_in.hxx +11 -3
  102. data/ext/couchbase/protocol/cmd_mutate_in.hxx +46 -4
  103. data/ext/couchbase/protocol/cmd_noop.hxx +82 -0
  104. data/ext/couchbase/protocol/cmd_prepend.hxx +145 -0
  105. data/ext/couchbase/protocol/durability_level.hxx +16 -0
  106. data/ext/couchbase/protocol/hello_feature.hxx +9 -0
  107. data/ext/couchbase/protocol/unsigned_leb128.h +2 -2
  108. data/ext/couchbase/service_type.hxx +1 -1
  109. data/ext/couchbase/version.hxx +18 -4
  110. data/ext/extconf.rb +9 -6
  111. data/ext/test/CMakeLists.txt +5 -0
  112. data/ext/test/test_helper.hxx +3 -3
  113. data/ext/test/test_helper_native.hxx +2 -5
  114. data/ext/test/test_native_binary_operations.cxx +186 -0
  115. data/ext/test/test_native_diagnostics.cxx +54 -3
  116. data/ext/test/test_ruby_trivial_crud.cxx +1 -1
  117. data/lib/couchbase.rb +1 -0
  118. data/lib/couchbase/analytics_options.rb +1 -71
  119. data/lib/couchbase/binary_collection.rb +60 -22
  120. data/lib/couchbase/binary_collection_options.rb +0 -76
  121. data/lib/couchbase/bucket.rb +40 -36
  122. data/lib/couchbase/cluster.rb +89 -156
  123. data/lib/couchbase/collection.rb +290 -72
  124. data/lib/couchbase/collection_options.rb +30 -243
  125. data/lib/couchbase/datastructures/couchbase_list.rb +5 -16
  126. data/lib/couchbase/datastructures/couchbase_map.rb +5 -16
  127. data/lib/couchbase/datastructures/couchbase_queue.rb +5 -16
  128. data/lib/couchbase/datastructures/couchbase_set.rb +5 -16
  129. data/lib/couchbase/diagnostics.rb +181 -0
  130. data/lib/couchbase/json_transcoder.rb +1 -1
  131. data/lib/couchbase/{common_options.rb → logger.rb} +24 -11
  132. data/lib/couchbase/management/query_index_manager.rb +1 -1
  133. data/lib/couchbase/management/user_manager.rb +3 -0
  134. data/lib/couchbase/options.rb +2094 -0
  135. data/lib/couchbase/query_options.rb +1 -144
  136. data/lib/couchbase/scope.rb +8 -25
  137. data/lib/couchbase/search_options.rb +0 -93
  138. data/lib/couchbase/version.rb +20 -1
  139. data/lib/couchbase/view_options.rb +1 -91
  140. metadata +19 -7
@@ -22,9 +22,25 @@
22
22
  namespace couchbase::protocol
23
23
  {
24
24
  enum class durability_level : uint8_t {
25
+ /**
26
+ * no enhanced durability required for the mutation
27
+ */
25
28
  none = 0x00,
29
+
30
+ /**
31
+ * the mutation must be replicated to a majority of the Data Service nodes (that is, held in the memory allocated to the bucket)
32
+ */
26
33
  majority = 0x01,
34
+
35
+ /**
36
+ * The mutation must be replicated to a majority of the Data Service nodes. Additionally, it must be persisted (that is, written and
37
+ * synchronised to disk) on the node hosting the active partition (vBucket) for the data.
38
+ */
27
39
  majority_and_persist_to_active = 0x02,
40
+
41
+ /**
42
+ * The mutation must be persisted to a majority of the Data Service nodes. Accordingly, it will be written to disk on those nodes.
43
+ */
28
44
  persist_to_majority = 0x03,
29
45
  };
30
46
 
@@ -145,6 +145,11 @@ enum class hello_feature : uint16_t {
145
145
  * Does the server support the subdoc mutation flag create_as_deleted
146
146
  */
147
147
  subdoc_create_as_deleted = 0x17,
148
+
149
+ /**
150
+ * Does the server support using the virtual $document attributes in macro expansion ("${document.CAS}" etc)
151
+ */
152
+ subdoc_document_macro_support = 0x18,
148
153
  };
149
154
 
150
155
  constexpr inline bool
@@ -172,6 +177,7 @@ is_valid_hello_feature(uint16_t code)
172
177
  case hello_feature::tcp_delay:
173
178
  case hello_feature::tracing:
174
179
  case hello_feature::subdoc_create_as_deleted:
180
+ case hello_feature::subdoc_document_macro_support:
175
181
  return true;
176
182
  }
177
183
  return false;
@@ -249,6 +255,9 @@ struct fmt::formatter<couchbase::protocol::hello_feature> : formatter<string_vie
249
255
  case couchbase::protocol::hello_feature::subdoc_create_as_deleted:
250
256
  name = "subdoc_create_as_deleted";
251
257
  break;
258
+ case couchbase::protocol::hello_feature::subdoc_document_macro_support:
259
+ name = "subdoc_document_macro_support";
260
+ break;
252
261
  }
253
262
  return formatter<string_view>::format(name, ctx);
254
263
  }
@@ -51,11 +51,11 @@ decode_unsigned_leb128(std::string_view buf, struct Leb128NoThrow)
51
51
  {
52
52
  T rv = static_cast<uint8_t>(buf[0]) & 0x7fULL;
53
53
  size_t end = 0;
54
- if ((buf[0] & 0x80) == 0x80ULL) {
54
+ if ((static_cast<uint8_t>(buf[0]) & 0x80ULL) == 0x80ULL) {
55
55
  T shift = 7;
56
56
  // shift in the remaining data
57
57
  for (end = 1; end < buf.size(); end++) {
58
- rv |= (buf[end] & 0x7fULL) << shift;
58
+ rv |= (static_cast<uint8_t>(buf[end]) & 0x7fULL) << shift;
59
59
  if ((static_cast<uint8_t>(buf[end]) & 0x80ULL) == 0) {
60
60
  break; // no more
61
61
  }
@@ -27,7 +27,7 @@ enum class service_type {
27
27
  views,
28
28
  management,
29
29
  };
30
- }
30
+ } // namespace couchbase
31
31
 
32
32
  template<>
33
33
  struct fmt::formatter<couchbase::service_type> : formatter<std::string_view> {
@@ -17,8 +17,22 @@
17
17
 
18
18
  #pragma once
19
19
 
20
- #define BACKEND_VERSION_MAJOR 1
21
- #define BACKEND_VERSION_MINOR 1
22
- #define BACKEND_VERSION_PATCH 0
23
-
24
20
  #include <build_version.hxx>
21
+
22
+ #include <string>
23
+
24
+ namespace couchbase
25
+ {
26
+ constexpr auto BACKEND_VERSION_MAJOR = 1;
27
+ constexpr auto BACKEND_VERSION_MINOR = 2;
28
+ constexpr auto BACKEND_VERSION_PATCH = 0;
29
+
30
+ inline const std::string&
31
+ sdk_id()
32
+ {
33
+ static const std::string identifier{ std::string("ruby/") + std::to_string(BACKEND_VERSION_MAJOR) + "/" +
34
+ std::to_string(BACKEND_VERSION_MINOR) + "/" + std::to_string(BACKEND_VERSION_PATCH) + "/" +
35
+ BACKEND_GIT_REVISION };
36
+ return identifier;
37
+ }
38
+ } // namespace couchbase
@@ -15,13 +15,14 @@
15
15
  require "mkmf"
16
16
  require "tempfile"
17
17
 
18
- require_relative "../lib/couchbase/version"
18
+ lib = File.expand_path("../lib", __dir__)
19
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
20
+ require "couchbase/version"
21
+
19
22
  SDK_VERSION = Couchbase::VERSION[:sdk]
20
23
 
21
24
  cmake = find_executable("cmake")
22
- if `#{cmake} --version`[/cmake version (\d+\.\d+)/, 1].to_f < 3.15
23
- cmake = find_executable("cmake3")
24
- end
25
+ cmake = find_executable("cmake3") if `#{cmake} --version`[/cmake version (\d+\.\d+)/, 1].to_f < 3.15
25
26
  abort "ERROR: CMake is required to build couchbase extension." unless cmake
26
27
  puts "-- #{`#{cmake} --version`.split("\n").first}"
27
28
 
@@ -64,7 +65,8 @@ FileUtils.mkdir_p(build_dir, verbose: true)
64
65
  Dir.chdir(build_dir) do
65
66
  puts "-- build #{build_type} extension #{SDK_VERSION} for ruby #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}-#{RUBY_PLATFORM}"
66
67
  sys(cmake, *cmake_flags, project_path)
67
- sys("make -j4 VERBOSE=1")
68
+ number_of_jobs = (ENV["CB_NUMBER_OF_JOBS"] || 4).to_s
69
+ sys(cmake, "--build", build_dir, "--parallel", number_of_jobs, "--verbose")
68
70
  end
69
71
  extension_name = "libcouchbase.#{RbConfig::CONFIG['SOEXT'] || RbConfig::CONFIG['DLEXT']}"
70
72
  extension_path = File.expand_path(File.join(build_dir, extension_name))
@@ -77,9 +79,10 @@ ext_directory = File.expand_path(__dir__)
77
79
  create_makefile("libcouchbase")
78
80
  if ENV["CB_REMOVE_EXT_DIRECTORY"]
79
81
  puts "-- CB_REMOVE_EXT_DIRECTORY is set, remove #{ext_directory}"
82
+ exceptions = %w[. .. extconf.rb]
80
83
  Dir
81
84
  .glob("#{ext_directory}/*", File::FNM_DOTMATCH)
82
- .reject { |path| %w[. .. extconf.rb].include?(File.basename(path)) || File.basename(path).start_with?(".gem") }
85
+ .reject { |path| exceptions.include?(File.basename(path)) || File.basename(path).start_with?(".gem") }
83
86
  .each do |entry|
84
87
  puts "-- remove #{entry}"
85
88
  FileUtils.rm_rf(entry, verbose: true)
@@ -0,0 +1,5 @@
1
+ ruby_test(trivial_crud)
2
+ ruby_test(trivial_query)
3
+ native_test(trivial_crud)
4
+ native_test(diagnostics)
5
+ native_test(binary_operations)
@@ -19,9 +19,9 @@
19
19
 
20
20
  #include <test_config.hxx>
21
21
 
22
- #include <string>
23
- #include <regex>
24
22
  #include <cstdlib>
23
+ #include <regex>
24
+ #include <string>
25
25
 
26
26
  #define CATCH_CONFIG_MAIN
27
27
  #include <catch2/catch.hpp>
@@ -36,7 +36,7 @@ struct test_server_version {
36
36
  static test_server_version parse(const std::string& str)
37
37
  {
38
38
  std::regex version_regex(R"((\d+).(\d+).(\d+(-(\d+))?)?)");
39
- std::smatch version_match;
39
+ std::smatch version_match{};
40
40
  test_server_version ver{};
41
41
  if (std::regex_match(str, version_match, version_regex) && version_match.ready()) {
42
42
  ver.major = std::stoul(version_match[1]);
@@ -19,12 +19,10 @@
19
19
 
20
20
  #include "test_helper.hxx"
21
21
 
22
- #include <build_config.hxx>
23
-
24
22
  #include <asio/version.hpp>
25
23
 
26
- #include <spdlog/spdlog.h>
27
24
  #include <spdlog/cfg/env.h>
25
+ #include <spdlog/spdlog.h>
28
26
 
29
27
  #include <http_parser.h>
30
28
 
@@ -50,8 +48,7 @@ native_init_logger()
50
48
  if (env_val.empty()) {
51
49
  spdlog::set_level(spdlog::level::warn);
52
50
  } else {
53
- auto levels = spdlog::cfg::helpers::extract_levels(env_val);
54
- spdlog::details::registry::instance().update_levels(std::move(levels));
51
+ spdlog::cfg::helpers::load_levels(env_val);
55
52
  }
56
53
 
57
54
  initialized = true;
@@ -0,0 +1,186 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "test_helper_native.hxx"
19
+
20
+ std::string
21
+ uniq_id(const std::string& prefix)
22
+ {
23
+ return fmt::format("{}_{}", prefix, std::chrono::steady_clock::now().time_since_epoch().count());
24
+ }
25
+
26
+ TEST_CASE("native: append", "[native]")
27
+ {
28
+ auto ctx = test_context::load_from_environment();
29
+ native_init_logger();
30
+
31
+ auto connstr = couchbase::utils::parse_connection_string(ctx.connection_string);
32
+ couchbase::cluster_credentials auth{};
33
+ auth.username = ctx.username;
34
+ auth.password = ctx.password;
35
+
36
+ asio::io_context io;
37
+
38
+ couchbase::cluster cluster(io);
39
+ auto io_thread = std::thread([&io]() { io.run(); });
40
+
41
+ {
42
+ auto barrier = std::make_shared<std::promise<std::error_code>>();
43
+ auto f = barrier->get_future();
44
+ cluster.open(couchbase::origin(auth, connstr), [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
45
+ auto rc = f.get();
46
+ INFO(rc.message());
47
+ REQUIRE_FALSE(rc);
48
+ }
49
+ {
50
+ auto barrier = std::make_shared<std::promise<std::error_code>>();
51
+ auto f = barrier->get_future();
52
+ cluster.open_bucket(ctx.bucket, [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
53
+ auto rc = f.get();
54
+ INFO(rc.message());
55
+ REQUIRE_FALSE(rc);
56
+ }
57
+ couchbase::document_id id{ ctx.bucket, "_default._default", uniq_id("foo") };
58
+ {
59
+ couchbase::operations::upsert_request req{ id, "world" };
60
+ auto barrier = std::make_shared<std::promise<couchbase::operations::upsert_response>>();
61
+ auto f = barrier->get_future();
62
+ cluster.execute(req, [barrier](couchbase::operations::upsert_response resp) mutable { barrier->set_value(resp); });
63
+ auto resp = f.get();
64
+ INFO(resp.ec.message());
65
+ REQUIRE_FALSE(resp.ec);
66
+ INFO("rc=" << resp.cas);
67
+ REQUIRE(resp.cas != 0);
68
+ INFO("seqno=" << resp.token.sequence_number);
69
+ REQUIRE(resp.token.sequence_number != 0);
70
+ }
71
+ {
72
+ couchbase::operations::append_request req{ id, "!" };
73
+ auto barrier = std::make_shared<std::promise<couchbase::operations::append_response>>();
74
+ auto f = barrier->get_future();
75
+ cluster.execute(req, [barrier](couchbase::operations::append_response resp) mutable { barrier->set_value(resp); });
76
+ auto resp = f.get();
77
+ INFO(resp.ec.message());
78
+ REQUIRE_FALSE(resp.ec);
79
+ INFO("rc=" << resp.cas);
80
+ REQUIRE(resp.cas != 0);
81
+ INFO("seqno=" << resp.token.sequence_number);
82
+ REQUIRE(resp.token.sequence_number != 0);
83
+ }
84
+ {
85
+ couchbase::operations::get_request req{ id };
86
+ auto barrier = std::make_shared<std::promise<couchbase::operations::get_response>>();
87
+ auto f = barrier->get_future();
88
+ cluster.execute(req, [barrier](couchbase::operations::get_response resp) mutable { barrier->set_value(resp); });
89
+ auto resp = f.get();
90
+ INFO(resp.ec.message());
91
+ REQUIRE_FALSE(resp.ec);
92
+ INFO("rc=" << resp.cas);
93
+ REQUIRE(resp.cas != 0);
94
+ INFO("value=" << resp.value);
95
+ REQUIRE(resp.value == "world!");
96
+ }
97
+ {
98
+ auto barrier = std::make_shared<std::promise<void>>();
99
+ auto f = barrier->get_future();
100
+ cluster.close([barrier]() { barrier->set_value(); });
101
+ f.get();
102
+ }
103
+
104
+ io_thread.join();
105
+ }
106
+
107
+ TEST_CASE("native: prepend", "[native]")
108
+ {
109
+ auto ctx = test_context::load_from_environment();
110
+ native_init_logger();
111
+
112
+ auto connstr = couchbase::utils::parse_connection_string(ctx.connection_string);
113
+ couchbase::cluster_credentials auth{};
114
+ auth.username = ctx.username;
115
+ auth.password = ctx.password;
116
+
117
+ asio::io_context io;
118
+
119
+ couchbase::cluster cluster(io);
120
+ auto io_thread = std::thread([&io]() { io.run(); });
121
+
122
+ {
123
+ auto barrier = std::make_shared<std::promise<std::error_code>>();
124
+ auto f = barrier->get_future();
125
+ cluster.open(couchbase::origin(auth, connstr), [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
126
+ auto rc = f.get();
127
+ INFO(rc.message());
128
+ REQUIRE_FALSE(rc);
129
+ }
130
+ {
131
+ auto barrier = std::make_shared<std::promise<std::error_code>>();
132
+ auto f = barrier->get_future();
133
+ cluster.open_bucket(ctx.bucket, [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
134
+ auto rc = f.get();
135
+ INFO(rc.message());
136
+ REQUIRE_FALSE(rc);
137
+ }
138
+ couchbase::document_id id{ ctx.bucket, "_default._default", uniq_id("foo") };
139
+ {
140
+ couchbase::operations::upsert_request req{ id, "world" };
141
+ auto barrier = std::make_shared<std::promise<couchbase::operations::upsert_response>>();
142
+ auto f = barrier->get_future();
143
+ cluster.execute(req, [barrier](couchbase::operations::upsert_response resp) mutable { barrier->set_value(resp); });
144
+ auto resp = f.get();
145
+ INFO(resp.ec.message());
146
+ REQUIRE_FALSE(resp.ec);
147
+ INFO("rc=" << resp.cas);
148
+ REQUIRE(resp.cas != 0);
149
+ INFO("seqno=" << resp.token.sequence_number);
150
+ REQUIRE(resp.token.sequence_number != 0);
151
+ }
152
+ {
153
+ couchbase::operations::prepend_request req{ id, "Hello, " };
154
+ auto barrier = std::make_shared<std::promise<couchbase::operations::prepend_response>>();
155
+ auto f = barrier->get_future();
156
+ cluster.execute(req, [barrier](couchbase::operations::prepend_response resp) mutable { barrier->set_value(resp); });
157
+ auto resp = f.get();
158
+ INFO(resp.ec.message());
159
+ REQUIRE_FALSE(resp.ec);
160
+ INFO("rc=" << resp.cas);
161
+ REQUIRE(resp.cas != 0);
162
+ INFO("seqno=" << resp.token.sequence_number);
163
+ REQUIRE(resp.token.sequence_number != 0);
164
+ }
165
+ {
166
+ couchbase::operations::get_request req{ id };
167
+ auto barrier = std::make_shared<std::promise<couchbase::operations::get_response>>();
168
+ auto f = barrier->get_future();
169
+ cluster.execute(req, [barrier](couchbase::operations::get_response resp) mutable { barrier->set_value(resp); });
170
+ auto resp = f.get();
171
+ INFO(resp.ec.message());
172
+ REQUIRE_FALSE(resp.ec);
173
+ INFO("rc=" << resp.cas);
174
+ REQUIRE(resp.cas != 0);
175
+ INFO("value=" << resp.value);
176
+ REQUIRE(resp.value == "Hello, world");
177
+ }
178
+ {
179
+ auto barrier = std::make_shared<std::promise<void>>();
180
+ auto f = barrier->get_future();
181
+ cluster.close([barrier]() { barrier->set_value(); });
182
+ f.get();
183
+ }
184
+
185
+ io_thread.join();
186
+ }
@@ -183,7 +183,6 @@ TEST_CASE("native: serializing ping report", "[native]")
183
183
  couchbase::diag::ping_result res{
184
184
  "0xdeadbeef",
185
185
  "ruby/1.0.0",
186
- 53,
187
186
  {
188
187
  {
189
188
  {
@@ -354,7 +353,7 @@ TEST_CASE("native: fetch diagnostics after N1QL query", "[native]")
354
353
  couchbase::operations::query_request req{ "SELECT 'hello, couchbase' AS greetings" };
355
354
  auto barrier = std::make_shared<std::promise<couchbase::operations::query_response>>();
356
355
  auto f = barrier->get_future();
357
- cluster.execute_http(req, [barrier](couchbase::operations::query_response resp) mutable { barrier->set_value(resp); });
356
+ cluster.execute_http(req, [barrier](couchbase::operations::query_response&& resp) mutable { barrier->set_value(resp); });
358
357
  auto resp = f.get();
359
358
  INFO(resp.ec.message());
360
359
  REQUIRE_FALSE(resp.ec);
@@ -366,7 +365,7 @@ TEST_CASE("native: fetch diagnostics after N1QL query", "[native]")
366
365
  {
367
366
  auto barrier = std::make_shared<std::promise<couchbase::diag::diagnostics_result>>();
368
367
  auto f = barrier->get_future();
369
- cluster.diagnostics("my_report_id", [barrier](couchbase::diag::diagnostics_result resp) mutable { barrier->set_value(resp); });
368
+ cluster.diagnostics("my_report_id", [barrier](couchbase::diag::diagnostics_result&& resp) mutable { barrier->set_value(resp); });
370
369
  auto res = f.get();
371
370
  REQUIRE(res.id == "my_report_id");
372
371
  REQUIRE(res.sdk.find("ruby/") == 0);
@@ -383,3 +382,55 @@ TEST_CASE("native: fetch diagnostics after N1QL query", "[native]")
383
382
 
384
383
  io_thread.join();
385
384
  }
385
+
386
+ TEST_CASE("native: ping", "[native]")
387
+ {
388
+ auto ctx = test_context::load_from_environment();
389
+ native_init_logger();
390
+
391
+ auto connstr = couchbase::utils::parse_connection_string(ctx.connection_string);
392
+ couchbase::cluster_credentials auth{};
393
+ auth.username = ctx.username;
394
+ auth.password = ctx.password;
395
+
396
+ asio::io_context io;
397
+
398
+ couchbase::cluster cluster(io);
399
+ auto io_thread = std::thread([&io]() { io.run(); });
400
+
401
+ {
402
+ auto barrier = std::make_shared<std::promise<std::error_code>>();
403
+ auto f = barrier->get_future();
404
+ cluster.open(couchbase::origin(auth, connstr), [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
405
+ auto rc = f.get();
406
+ INFO(rc.message());
407
+ REQUIRE_FALSE(rc);
408
+ }
409
+ {
410
+ auto barrier = std::make_shared<std::promise<std::error_code>>();
411
+ auto f = barrier->get_future();
412
+ cluster.open_bucket(ctx.bucket, [barrier](std::error_code ec) mutable { barrier->set_value(ec); });
413
+ auto rc = f.get();
414
+ INFO(rc.message());
415
+ REQUIRE_FALSE(rc);
416
+ }
417
+ {
418
+ auto barrier = std::make_shared<std::promise<couchbase::diag::ping_result>>();
419
+ auto f = barrier->get_future();
420
+ cluster.ping("my_report_id", {}, {}, [barrier](couchbase::diag::ping_result&& resp) mutable { barrier->set_value(resp); });
421
+ auto res = f.get();
422
+ REQUIRE(res.id == "my_report_id");
423
+ REQUIRE(res.sdk.find("ruby/") == 0);
424
+
425
+ auto report = tao::json::value(res);
426
+ spdlog::critical("XXX {}", tao::json::to_string(report));
427
+ }
428
+ {
429
+ auto barrier = std::make_shared<std::promise<void>>();
430
+ auto f = barrier->get_future();
431
+ cluster.close([barrier]() { barrier->set_value(); });
432
+ f.get();
433
+ }
434
+
435
+ io_thread.join();
436
+ }