couchbase 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }