couchbase 4.2.5 → 4.2.6-dev

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 (120) hide show
  1. package/deps/couchbase-cxx-client/CMakeLists.txt +9 -1
  2. package/deps/couchbase-cxx-client/bin/api.rb +234 -0
  3. package/deps/couchbase-cxx-client/bin/create-search-index +18 -135
  4. package/deps/couchbase-cxx-client/bin/init-cluster +17 -139
  5. package/deps/couchbase-cxx-client/bin/load-sample-buckets +54 -0
  6. package/deps/couchbase-cxx-client/core/cluster.hxx +33 -12
  7. package/deps/couchbase-cxx-client/core/cluster_options.hxx +3 -0
  8. package/deps/couchbase-cxx-client/core/crud_component.cxx +51 -22
  9. package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +115 -50
  10. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +6 -0
  11. package/deps/couchbase-cxx-client/core/impl/create_bucket.cxx +155 -0
  12. package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +172 -59
  13. package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.cxx +2 -1
  14. package/deps/couchbase-cxx-client/core/impl/drop_bucket.cxx +66 -0
  15. package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +138 -59
  16. package/deps/couchbase-cxx-client/core/impl/flush_bucket.cxx +66 -0
  17. package/deps/couchbase-cxx-client/core/impl/get_all_buckets.cxx +163 -0
  18. package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +67 -37
  19. package/deps/couchbase-cxx-client/core/impl/get_bucket.cxx +153 -0
  20. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.cxx +113 -0
  21. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.hxx +60 -0
  22. package/deps/couchbase-cxx-client/core/impl/key_value_error_category.cxx +2 -4
  23. package/deps/couchbase-cxx-client/core/impl/manager_error_context.cxx +100 -0
  24. package/deps/couchbase-cxx-client/core/impl/query.cxx +1 -0
  25. package/deps/couchbase-cxx-client/core/impl/update_bucket.cxx +130 -0
  26. package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +53 -29
  27. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +71 -38
  28. package/deps/couchbase-cxx-client/core/io/dns_config.cxx +5 -4
  29. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +5 -6
  30. package/deps/couchbase-cxx-client/core/meta/features.hxx +6 -0
  31. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +11 -0
  32. package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -0
  33. package/deps/couchbase-cxx-client/core/origin.cxx +270 -0
  34. package/deps/couchbase-cxx-client/core/origin.hxx +2 -0
  35. package/deps/couchbase-cxx-client/core/protocol/status.cxx +2 -2
  36. package/deps/couchbase-cxx-client/core/range_scan_options.cxx +3 -27
  37. package/deps/couchbase-cxx-client/core/range_scan_options.hxx +13 -17
  38. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +367 -170
  39. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +13 -2
  40. package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +5 -3
  41. package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -19
  42. package/deps/couchbase-cxx-client/core/scan_result.cxx +19 -5
  43. package/deps/couchbase-cxx-client/core/scan_result.hxx +5 -2
  44. package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +2 -3
  45. package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +1 -0
  46. package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +2 -0
  47. package/deps/couchbase-cxx-client/core/topology/collections_manifest_fmt.hxx +1 -1
  48. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +5 -0
  49. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +2 -0
  50. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +4 -0
  51. package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +19 -2
  52. package/deps/couchbase-cxx-client/couchbase/bucket_manager.hxx +135 -0
  53. package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +0 -30
  54. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +14 -0
  55. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +7 -48
  56. package/deps/couchbase-cxx-client/couchbase/create_bucket_options.hxx +41 -0
  57. package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +0 -29
  58. package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +0 -33
  59. package/deps/couchbase-cxx-client/couchbase/drop_bucket_options.hxx +41 -0
  60. package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +0 -30
  61. package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +0 -31
  62. package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -2
  63. package/deps/couchbase-cxx-client/couchbase/flush_bucket_options.hxx +41 -0
  64. package/deps/couchbase-cxx-client/couchbase/get_all_buckets_options.hxx +44 -0
  65. package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +0 -30
  66. package/deps/couchbase-cxx-client/couchbase/get_bucket_options.hxx +43 -0
  67. package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +116 -0
  68. package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +29 -53
  69. package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +16 -83
  70. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +18 -0
  71. package/deps/couchbase-cxx-client/couchbase/security_options.hxx +15 -0
  72. package/deps/couchbase-cxx-client/couchbase/update_bucket_options.hxx +41 -0
  73. package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +0 -31
  74. package/deps/couchbase-cxx-client/docs/cbc-analytics.md +1 -0
  75. package/deps/couchbase-cxx-client/docs/cbc-get.md +1 -0
  76. package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +1 -0
  77. package/deps/couchbase-cxx-client/docs/cbc-query.md +1 -0
  78. package/deps/couchbase-cxx-client/docs/cbc.md +10 -0
  79. package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
  80. package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +6 -0
  81. package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +5 -0
  82. package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +137 -1
  83. package/deps/couchbase-cxx-client/test/test_integration_management.cxx +709 -266
  84. package/deps/couchbase-cxx-client/test/test_integration_query.cxx +19 -7
  85. package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +351 -112
  86. package/deps/couchbase-cxx-client/test/test_integration_search.cxx +10 -1
  87. package/deps/couchbase-cxx-client/test/test_transaction_public_async_api.cxx +13 -12
  88. package/deps/couchbase-cxx-client/test/test_transaction_public_blocking_api.cxx +27 -21
  89. package/deps/couchbase-cxx-client/test/test_unit_query.cxx +75 -0
  90. package/deps/couchbase-cxx-client/test/utils/server_version.hxx +5 -0
  91. package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +29 -10
  92. package/deps/couchbase-cxx-client/test/utils/wait_until.hxx +3 -1
  93. package/deps/couchbase-cxx-client/tools/utils.cxx +4 -1
  94. package/dist/binding.d.ts +21 -16
  95. package/dist/binding.js +1 -4
  96. package/dist/bindingutilities.d.ts +6 -1
  97. package/dist/bindingutilities.js +36 -1
  98. package/dist/collection.d.ts +65 -3
  99. package/dist/collection.js +107 -0
  100. package/dist/crudoptypes.d.ts +34 -0
  101. package/dist/crudoptypes.js +18 -1
  102. package/dist/queryexecutor.js +1 -0
  103. package/dist/querytypes.d.ts +7 -0
  104. package/dist/rangeScan.d.ts +107 -0
  105. package/dist/rangeScan.js +91 -0
  106. package/dist/streamablepromises.d.ts +6 -0
  107. package/dist/streamablepromises.js +25 -1
  108. package/package.json +12 -13
  109. package/src/addondata.hpp +1 -0
  110. package/src/binding.cpp +5 -2
  111. package/src/connection.cpp +108 -2
  112. package/src/connection.hpp +1 -0
  113. package/src/constants.cpp +2 -12
  114. package/src/jstocbpp_autogen.hpp +49 -22
  115. package/src/jstocbpp_basic.hpp +2 -8
  116. package/src/mutationtoken.cpp +13 -0
  117. package/src/scan_iterator.cpp +90 -0
  118. package/src/scan_iterator.hpp +30 -0
  119. package/tools/gen-bindings-json.py +9 -8
  120. package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +0 -93
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2020-2021 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
+ require "timeout"
18
+ require "set"
19
+
20
+ require_relative "api"
21
+
22
+ options = {
23
+ host: ENV.fetch("CB_HOST", ARGV[0] || "127.0.0.1"),
24
+ strict_encryption: ENV.fetch("CB_STRICT_ENCRYPTION", ARGV[1]).to_b,
25
+ username: ENV.fetch("CB_USERNAME", ARGV[2] || "Administrator"),
26
+ password: ENV.fetch("CB_PASSWORD", ARGV[3] || "password"),
27
+ verbose: ENV.fetch("CB_VERBOSE", true).to_b,
28
+ bucket: "travel-sample",
29
+ sample_buckets: Set.new,
30
+ }
31
+ options[:sample_buckets] << "beer-sample" if ENV.fetch("CB_BEER_SAMPLE", false).to_b
32
+ options[:sample_buckets] << "travel-sample" if ENV.fetch("CB_TRAVEL_SAMPLE", false).to_b
33
+ options[:sample_buckets] |= ARGV[4..-1]
34
+ return if options[:sample_buckets].empty?
35
+
36
+ p options: options
37
+
38
+ management_api =
39
+ begin
40
+ API.new(options.merge(port: options[:strict_encryption] ? 18091 : 8091))
41
+ rescue => ex
42
+ puts "#{ex}, sleep for 1 second and retry"
43
+ sleep(1)
44
+ retry
45
+ end
46
+
47
+ expected_counts = {
48
+ "travel-sample" => 30_000,
49
+ "beer-sample" => 7_000,
50
+ }
51
+
52
+ options[:sample_buckets].each do |bucket|
53
+ ensure_sample_bucket_loaded(management_api, expected_counts[bucket], options.merge(bucket: bucket))
54
+ end
@@ -79,6 +79,7 @@ class cluster : public std::enable_shared_from_this<cluster>
79
79
  }
80
80
 
81
81
  origin_ = std::move(origin);
82
+ CB_LOG_DEBUG(R"(open cluster, id: "{}", core version: "{}", {})", id_, couchbase::core::meta::sdk_semver(), origin_.to_json());
82
83
  // ignore the enable_tracing flag if a tracer was passed in
83
84
  if (nullptr != origin_.options().tracer) {
84
85
  tracer_ = origin_.options().tracer;
@@ -111,10 +112,7 @@ class cluster : public std::enable_shared_from_this<cluster>
111
112
  return self->dns_srv_tracker_->get_srv_nodes(
112
113
  [self, hostname = std::move(hostname), handler = std::forward<Handler>(handler)](origin::node_list nodes,
113
114
  std::error_code ec) mutable {
114
- if (ec) {
115
- return self->close([ec, handler = std::forward<Handler>(handler)]() mutable { handler(ec); });
116
- }
117
- if (!nodes.empty()) {
115
+ if (!ec && !nodes.empty()) {
118
116
  self->origin_.set_nodes(std::move(nodes));
119
117
  CB_LOG_INFO("replace list of bootstrap nodes with addresses from DNS SRV of \"{}\": [{}]",
120
118
  hostname,
@@ -339,8 +337,8 @@ class cluster : public std::enable_shared_from_this<cluster>
339
337
  void do_open(Handler&& handler)
340
338
  {
341
339
  // Warn users if they attempt to use Capella without TLS being enabled.
340
+ bool has_capella_host = false;
342
341
  {
343
- bool has_capella_host = false;
344
342
  bool has_non_capella_host = false;
345
343
  static std::string suffix = "cloud.couchbase.com";
346
344
  for (const auto& node : origin_.get_hostnames()) {
@@ -359,6 +357,7 @@ class cluster : public std::enable_shared_from_this<cluster>
359
357
 
360
358
  if (origin_.options().enable_tls /* TLS is enabled */
361
359
  && origin_.options().trust_certificate.empty() /* No CA certificate (or other SDK-specific trust source) is specified */
360
+ && origin_.options().trust_certificate_value.empty() /* and certificate value has not been specified */
362
361
  && origin_.options().tls_verify != tls_verify_mode::none /* The user did not disable all TLS verification */
363
362
  && has_non_capella_host /* The connection string has a hostname that does NOT end in ".cloud.couchbase.com" */) {
364
363
  CB_LOG_WARNING("[{}] When TLS is enabled, the cluster options must specify certificate(s) to trust or ensure that they are "
@@ -368,7 +367,17 @@ class cluster : public std::enable_shared_from_this<cluster>
368
367
  }
369
368
 
370
369
  if (origin_.options().enable_tls) {
371
- tls_.set_options(asio::ssl::context::default_workarounds | asio::ssl::context::no_sslv2 | asio::ssl::context::no_sslv3);
370
+ long tls_options = asio::ssl::context::default_workarounds | // various bug workarounds that should be rather harmless
371
+ asio::ssl::context::no_sslv2 | // published: 1995, deprecated: 2011
372
+ asio::ssl::context::no_sslv3; // published: 1996, deprecated: 2015
373
+ if (origin_.options().tls_disable_deprecated_protocols) {
374
+ tls_options |= asio::ssl::context::no_tlsv1 | // published: 1999, deprecated: 2021
375
+ asio::ssl::context::no_tlsv1_1; // published: 2006, deprecated: 2021
376
+ }
377
+ if (origin_.options().tls_disable_v1_2 || has_capella_host) {
378
+ tls_options |= asio::ssl::context::no_tlsv1_2; // published: 2008, still in use
379
+ }
380
+ tls_.set_options(tls_options);
372
381
  switch (origin_.options().tls_verify) {
373
382
  case tls_verify_mode::none:
374
383
  tls_.set_verify_mode(asio::ssl::verify_none);
@@ -378,7 +387,8 @@ class cluster : public std::enable_shared_from_this<cluster>
378
387
  tls_.set_verify_mode(asio::ssl::verify_peer);
379
388
  break;
380
389
  }
381
- if (origin_.options().trust_certificate.empty()) { // trust certificate is not explicitly specified
390
+ if (origin_.options().trust_certificate.empty() &&
391
+ origin_.options().trust_certificate_value.empty()) { // trust certificate is not explicitly specified
382
392
  CB_LOG_DEBUG(R"([{}]: use default CA for TLS verify)", id_);
383
393
  std::error_code ec{};
384
394
 
@@ -414,11 +424,22 @@ class cluster : public std::enable_shared_from_this<cluster>
414
424
  std::error_code ec{};
415
425
  // load only the explicit certificate
416
426
  // system and default capella certificates are not loaded
417
- CB_LOG_DEBUG(R"([{}]: use TLS verify file: "{}")", id_, origin_.options().trust_certificate);
418
- tls_.load_verify_file(origin_.options().trust_certificate, ec);
419
- if (ec) {
420
- CB_LOG_ERROR("[{}]: unable to load verify file \"{}\": {}", id_, origin_.options().trust_certificate, ec.message());
421
- return close([ec, handler = std::forward<Handler>(handler)]() mutable { return handler(ec); });
427
+ if (!origin_.options().trust_certificate_value.empty()) {
428
+ CB_LOG_DEBUG(R"([{}]: use TLS certificate passed through via options object)", id_);
429
+ tls_.add_certificate_authority(asio::const_buffer(origin_.options().trust_certificate_value.data(),
430
+ origin_.options().trust_certificate_value.size()),
431
+ ec);
432
+ if (ec) {
433
+ CB_LOG_WARNING("[{}]: unable to load CA passed via options object: {}", id_, ec.message());
434
+ }
435
+ }
436
+ if (!origin_.options().trust_certificate.empty()) {
437
+ CB_LOG_DEBUG(R"([{}]: use TLS verify file: "{}")", id_, origin_.options().trust_certificate);
438
+ tls_.load_verify_file(origin_.options().trust_certificate, ec);
439
+ if (ec) {
440
+ CB_LOG_ERROR("[{}]: unable to load verify file \"{}\": {}", id_, origin_.options().trust_certificate, ec.message());
441
+ return close([ec, handler = std::forward<Handler>(handler)]() mutable { return handler(ec); });
442
+ }
422
443
  }
423
444
  }
424
445
  #ifdef COUCHBASE_CXX_CLIENT_TLS_KEY_LOG_FILE
@@ -50,7 +50,10 @@ struct cluster_options {
50
50
  std::chrono::milliseconds management_timeout = timeout_defaults::management_timeout;
51
51
 
52
52
  bool enable_tls{ false };
53
+ bool tls_disable_deprecated_protocols{ true };
54
+ bool tls_disable_v1_2{ false };
53
55
  std::string trust_certificate{};
56
+ std::string trust_certificate_value{};
54
57
  bool enable_mutation_tokens{ true };
55
58
  bool enable_tcp_keep_alive{ true };
56
59
  io::ip_protocol use_ip_protocol{ io::ip_protocol::any };
@@ -1,6 +1,6 @@
1
1
  /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright 2020-2021 Couchbase, Inc.
3
+ * Copyright 2020-2023 Couchbase, Inc.
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
@@ -39,6 +39,8 @@
39
39
 
40
40
  #include <tl/expected.hpp>
41
41
 
42
+ #include <random>
43
+
42
44
  namespace couchbase::core
43
45
  {
44
46
  static std::pair<std::vector<std::byte>, std::error_code>
@@ -53,17 +55,40 @@ serialize_range_scan_create_options(const range_scan_create_options& options)
53
55
  body["collection"] = fmt::format("{:x}", options.collection_id);
54
56
  }
55
57
 
56
- if (std::holds_alternative<range_scan>(options.scan_type)) {
57
- const auto& range = std::get<range_scan>(options.scan_type);
58
+ if (std::holds_alternative<range_scan>(options.scan_type) || std::holds_alternative<prefix_scan>(options.scan_type)) {
59
+ const auto& range = (std::holds_alternative<range_scan>(options.scan_type))
60
+ ? std::get<range_scan>(options.scan_type)
61
+ : std::get<prefix_scan>(options.scan_type).to_range_scan();
62
+
63
+ const auto& from = range.from.value_or(scan_term{ "" });
64
+ const auto& to = range.to.value_or(scan_term{ "\xf4\x8f\xfb\xfb" });
65
+
58
66
  body["range"] = {
59
- { range.start_.exclusive ? "excl_start" : "start", base64::encode(range.start_.id) },
60
- { range.end_.exclusive ? "excl_end" : "end", base64::encode(range.end_.id) },
67
+ { from.exclusive ? "excl_start" : "start", base64::encode(from.term) },
68
+ { to.exclusive ? "excl_end" : "end", base64::encode(to.term) },
61
69
  };
62
70
  } else if (std::holds_alternative<sampling_scan>(options.scan_type)) {
63
71
  const auto& sampling = std::get<sampling_scan>(options.scan_type);
72
+
73
+ // The limit in sampling scan is required to be greater than 0
74
+ if (sampling.limit <= 0) {
75
+ return { {}, errc::common::invalid_argument };
76
+ }
77
+
78
+ std::uint64_t seed{};
79
+ if (sampling.seed.has_value()) {
80
+ seed = sampling.seed.value();
81
+ } else {
82
+ // Generate random uint64 as seed
83
+ std::random_device rd;
84
+ std::mt19937_64 gen(rd());
85
+ std::uniform_int_distribution<std::uint64_t> dis;
86
+ seed = dis(gen);
87
+ }
88
+
64
89
  body["sampling"] = {
65
90
  { "samples", sampling.limit },
66
- { "seed", sampling.seed.value_or(0) },
91
+ { "seed", seed },
67
92
  };
68
93
  } else {
69
94
  return { {}, errc::common::invalid_argument };
@@ -75,7 +100,7 @@ serialize_range_scan_create_options(const range_scan_create_options& options)
75
100
  { "vb_uuid", std::to_string(snapshot.vbucket_uuid) },
76
101
  { "seqno", snapshot.sequence_number },
77
102
  { "timeout_ms",
78
- (options.timeout == std::chrono::milliseconds::zero()) ? timeout_defaults::range_scan_timeout.count()
103
+ (options.timeout == std::chrono::milliseconds::zero()) ? timeout_defaults::key_value_scan_timeout.count()
79
104
  : options.timeout.count() },
80
105
  };
81
106
  if (snapshot.sequence_number_exists) {
@@ -98,7 +123,7 @@ parse_range_scan_keys(gsl::span<std::byte> data, range_scan_item_callback&& item
98
123
  if (remaining.size() < key_length) {
99
124
  return errc::network::protocol_error;
100
125
  }
101
- item_callback(range_scan_item{ { remaining.begin(), remaining.begin() + static_cast<std::ptrdiff_t>(key_length) } });
126
+ item_callback(range_scan_item{ { reinterpret_cast<const char*>(remaining.data()), key_length } });
102
127
  if (remaining.size() == key_length) {
103
128
  return {};
104
129
  }
@@ -130,13 +155,13 @@ parse_range_scan_documents(gsl::span<std::byte> data, range_scan_item_callback&&
130
155
  body.datatype = data[24];
131
156
  data = gsl::make_span(data.data() + header_offset, data.size() - header_offset);
132
157
 
133
- std::vector<std::byte> key{};
158
+ std::string key{};
134
159
  {
135
160
  auto [key_length, remaining] = utils::decode_unsigned_leb128<std::size_t>(data, core::utils::leb_128_no_throw{});
136
161
  if (remaining.size() < key_length) {
137
162
  return errc::network::protocol_error;
138
163
  }
139
- key = { remaining.begin(), remaining.begin() + static_cast<std::ptrdiff_t>(key_length) };
164
+ key = { reinterpret_cast<const char*>(remaining.data()), key_length };
140
165
  data = gsl::make_span(remaining.data() + key_length, remaining.size() - key_length);
141
166
  }
142
167
 
@@ -242,19 +267,10 @@ class crud_component_impl
242
267
  if (error) {
243
268
  return cb({}, error);
244
269
  }
245
- bool ids_only;
246
- switch (response->extras_.size()) {
247
- case 4:
248
- ids_only = mcbp::big_endian::read_uint32(response->extras_, 0) == 0;
249
- break;
250
-
251
- case 0:
252
- ids_only = options.ids_only; // support servers before MB-54267. TODO: remove after server GA
253
- break;
254
-
255
- default:
256
- return cb({}, errc::network::protocol_error);
270
+ if (response->extras_.size() != 4) {
271
+ return cb({}, errc::network::protocol_error);
257
272
  }
273
+ bool ids_only = mcbp::big_endian::read_uint32(response->extras_, 0) == 0;
258
274
 
259
275
  if (auto ec = parse_range_scan_data(response->value_, std::move(item_cb), ids_only); ec) {
260
276
  return cb({}, ec);
@@ -276,6 +292,19 @@ class crud_component_impl
276
292
 
277
293
  req->persistent_ = true;
278
294
  req->vbucket_ = vbucket_id;
295
+
296
+ if (options.timeout != std::chrono::milliseconds::zero()) {
297
+ auto timer = std::make_shared<asio::steady_timer>(io_);
298
+ timer->expires_after(options.timeout);
299
+ timer->async_wait([req](auto error) {
300
+ if (error == asio::error::operation_aborted) {
301
+ return;
302
+ }
303
+ req->cancel(couchbase::errc::common::unambiguous_timeout);
304
+ });
305
+ req->set_deadline(timer);
306
+ }
307
+
279
308
  mcbp::buffer_writer buf{ scan_uuid.size() + sizeof(std::uint32_t) * 3 };
280
309
  buf.write(scan_uuid);
281
310
  buf.write_uint32(options.batch_item_limit);
@@ -20,44 +20,116 @@
20
20
 
21
21
  #include "core/cluster.hxx"
22
22
  #include "core/operations/management/query_index_build.hxx"
23
- #include "core/operations/management/query_index_get_all_deferred.hxx"
24
- #include "core/utils/json.hxx"
23
+ #include "core/operations/management/query_index_build_deferred.hxx"
25
24
 
26
- namespace couchbase::core::impl
25
+ namespace couchbase
27
26
  {
28
27
  template<typename Response>
29
28
  static manager_error_context
30
29
  build_context(Response& resp)
31
30
  {
32
- return { resp.ctx.ec,
33
- resp.ctx.last_dispatched_to,
34
- resp.ctx.last_dispatched_from,
35
- resp.ctx.retry_attempts,
36
- std::move(resp.ctx.retry_reasons),
37
- std::move(resp.ctx.client_context_id),
38
- resp.ctx.http_status,
39
- std::move(resp.ctx.http_body),
40
- std::move(resp.ctx.path) };
31
+ return manager_error_context(internal_manager_error_context{ resp.ctx.ec,
32
+ resp.ctx.last_dispatched_to,
33
+ resp.ctx.last_dispatched_from,
34
+ resp.ctx.retry_attempts,
35
+ std::move(resp.ctx.retry_reasons),
36
+ std::move(resp.ctx.client_context_id),
37
+ resp.ctx.http_status,
38
+ std::move(resp.ctx.http_body),
39
+ std::move(resp.ctx.path) });
41
40
  }
41
+
42
+ static core::operations::management::query_index_build_request
43
+ build_build_index_request(std::string bucket_name,
44
+ core::operations::management::query_index_get_all_deferred_response list_resp,
45
+ const build_query_index_options::built& options)
46
+ {
47
+ core::operations::management::query_index_build_request request{
48
+ std::move(bucket_name), {}, {}, {}, std::move(list_resp.index_names), {}, options.timeout
49
+ };
50
+ return request;
51
+ }
52
+
53
+ static core::operations::management::query_index_get_all_deferred_request
54
+ build_get_all_request(std::string bucket_name, const build_query_index_options::built& options)
55
+ {
56
+ core::operations::management::query_index_get_all_deferred_request request{ std::move(bucket_name), {}, {}, {}, {}, options.timeout };
57
+ return request;
58
+ }
59
+
60
+ static core::operations::management::query_index_build_request
61
+ build_build_index_request(std::string bucket_name,
62
+ std::string scope_name,
63
+ std::string collection_name,
64
+ core::operations::management::query_index_get_all_deferred_response list_resp,
65
+ const build_query_index_options::built& options)
66
+ {
67
+ core::operations::management::query_index_build_request request{ "",
68
+ "",
69
+ std::move(collection_name),
70
+ core::query_context{ std::move(bucket_name), std::move(scope_name) },
71
+ std::move(list_resp.index_names),
72
+ {},
73
+ options.timeout };
74
+ return request;
75
+ }
76
+
77
+ static core::operations::management::query_index_get_all_deferred_request
78
+ build_get_all_request(std::string bucket_name,
79
+ std::string scope_name,
80
+ std::string collection_name,
81
+ const build_query_index_options::built& options)
82
+ {
83
+ core::operations::management::query_index_get_all_deferred_request request{
84
+ "", "", std::move(collection_name), core::query_context{ std::move(bucket_name), std::move(scope_name) }, {}, options.timeout
85
+ };
86
+ return request;
87
+ }
88
+
42
89
  void
43
- initiate_build_deferred_indexes(std::shared_ptr<couchbase::core::cluster> core,
44
- std::string bucket_name,
45
- build_query_index_options::built options,
46
- query_context query_ctx,
47
- std::string collection_name,
48
- build_deferred_query_indexes_handler&& handler)
90
+ query_index_manager::build_deferred_indexes(std::string bucket_name,
91
+ const couchbase::build_query_index_options& options,
92
+ couchbase::build_deferred_query_indexes_handler&& handler) const
93
+ {
94
+
95
+ auto get_all_request = build_get_all_request(bucket_name, options.build());
96
+ core_->execute(std::move(get_all_request),
97
+ [handler = std::move(handler), this, bucket_name, options](
98
+ core::operations::management::query_index_get_all_deferred_response resp1) mutable {
99
+ auto list_resp = std::move(resp1);
100
+ if (list_resp.ctx.ec) {
101
+ return handler(build_context(list_resp));
102
+ }
103
+ if (list_resp.index_names.empty()) {
104
+ return handler(build_context(list_resp));
105
+ }
106
+ auto build_request = build_build_index_request(std::move(bucket_name), list_resp, options.build());
107
+ core_->execute(
108
+ std::move(build_request),
109
+ [handler = std::move(handler)](core::operations::management::query_index_build_response resp2) mutable {
110
+ auto build_resp = std::move(resp2);
111
+ return handler(build_context(build_resp));
112
+ });
113
+ });
114
+ }
115
+
116
+ auto
117
+ query_index_manager::build_deferred_indexes(std::string bucket_name, const couchbase::build_query_index_options& options) const
118
+ -> std::future<manager_error_context>
49
119
  {
50
- core->execute(
51
- operations::management::query_index_get_all_deferred_request{
52
- bucket_name,
53
- "",
54
- collection_name,
55
- query_ctx,
56
- {},
57
- options.timeout,
58
- },
59
- [core, bucket_name, collection_name, options = std::move(options), query_ctx, handler = std::move(handler)](
60
- operations::management::query_index_get_all_deferred_response resp1) mutable {
120
+ auto barrier = std::make_shared<std::promise<manager_error_context>>();
121
+ build_deferred_indexes(std::move(bucket_name), options, [barrier](auto ctx) mutable { barrier->set_value(std::move(ctx)); });
122
+ return barrier->get_future();
123
+ }
124
+
125
+ void
126
+ collection_query_index_manager::build_deferred_indexes(const build_query_index_options& options,
127
+ build_deferred_query_indexes_handler&& handler) const
128
+ {
129
+ auto get_all_request = build_get_all_request(bucket_name_, scope_name_, collection_name_, options.build());
130
+ core_->execute(
131
+ std::move(get_all_request),
132
+ [handler = std::move(handler), this, options](core::operations::management::query_index_get_all_deferred_response resp1) mutable {
61
133
  auto list_resp = std::move(resp1);
62
134
  if (list_resp.ctx.ec) {
63
135
  return handler(build_context(list_resp));
@@ -65,28 +137,21 @@ initiate_build_deferred_indexes(std::shared_ptr<couchbase::core::cluster> core,
65
137
  if (list_resp.index_names.empty()) {
66
138
  return handler(build_context(list_resp));
67
139
  }
68
- core->execute(
69
- operations::management::query_index_build_request{
70
- std::move(bucket_name),
71
- "",
72
- collection_name,
73
- query_ctx,
74
- std::move(list_resp.index_names),
75
- {},
76
- options.timeout,
77
- },
78
- [handler = std::move(handler)](operations::management::query_index_build_response resp2) {
79
- auto build_resp = std::move(resp2);
80
- return handler(build_context(build_resp));
81
- });
140
+ auto build_request = build_build_index_request(bucket_name_, scope_name_, collection_name_, list_resp, options.build());
141
+ core_->execute(std::move(build_request),
142
+ [handler = std::move(handler)](core::operations::management::query_index_build_response resp2) mutable {
143
+ auto build_resp = std::move(resp2);
144
+ return handler(build_context(build_resp));
145
+ });
82
146
  });
83
147
  }
84
- void
85
- initiate_build_deferred_indexes(std::shared_ptr<couchbase::core::cluster> core,
86
- std::string bucket_name,
87
- build_query_index_options::built options,
88
- build_deferred_query_indexes_handler&& handler)
148
+
149
+ auto
150
+ collection_query_index_manager::build_deferred_indexes(const couchbase::build_query_index_options& options) const
151
+ -> std::future<manager_error_context>
89
152
  {
90
- return initiate_build_deferred_indexes(core, std::move(bucket_name), options, {}, "", std::move(handler));
153
+ auto barrier = std::make_shared<std::promise<manager_error_context>>();
154
+ build_deferred_indexes(options, [barrier](auto ctx) mutable { barrier->set_value(std::move(ctx)); });
155
+ return barrier->get_future();
91
156
  }
92
- } // namespace couchbase::core::impl
157
+ } // namespace couchbase
@@ -82,6 +82,9 @@ options_to_origin(const std::string& connection_string, const couchbase::cluster
82
82
  if (opts.security.trust_certificate.has_value()) {
83
83
  user_options.trust_certificate = opts.security.trust_certificate.value();
84
84
  }
85
+ if (opts.security.trust_certificate_value.has_value()) {
86
+ user_options.trust_certificate_value = opts.security.trust_certificate_value.value();
87
+ }
85
88
  switch (opts.security.tls_verify) {
86
89
  case couchbase::tls_verify_mode::none:
87
90
  user_options.tls_verify = core::tls_verify_mode::none;
@@ -91,6 +94,8 @@ options_to_origin(const std::string& connection_string, const couchbase::cluster
91
94
  break;
92
95
  }
93
96
  user_options.disable_mozilla_ca_certificates = opts.security.disable_mozilla_ca_certificates;
97
+ user_options.tls_disable_deprecated_protocols = opts.security.disable_deprecated_protocols;
98
+ user_options.tls_disable_v1_2 = opts.security.disable_tls_v1_2;
94
99
  }
95
100
 
96
101
  if (opts.dns.nameserver) {
@@ -103,6 +108,7 @@ options_to_origin(const std::string& connection_string, const couchbase::cluster
103
108
  user_options.enable_mutation_tokens = opts.behavior.enable_mutation_tokens;
104
109
  user_options.enable_unordered_execution = opts.behavior.enable_unordered_execution;
105
110
  user_options.user_agent_extra = opts.behavior.user_agent_extra;
111
+ user_options.network = opts.behavior.network;
106
112
 
107
113
  user_options.enable_tcp_keep_alive = opts.network.enable_tcp_keep_alive;
108
114
  user_options.tcp_keep_alive_interval = opts.network.tcp_keep_alive_interval;