couchbase 4.2.1 → 4.2.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 (162) hide show
  1. package/CMakeLists.txt +1 -0
  2. package/deps/couchbase-cxx-client/.gitmodules +3 -0
  3. package/deps/couchbase-cxx-client/.idea/misc.xml +1 -0
  4. package/deps/couchbase-cxx-client/.idea/vcs.xml +1 -0
  5. package/deps/couchbase-cxx-client/CMakeLists.txt +11 -1
  6. package/deps/couchbase-cxx-client/README.md +3 -3
  7. package/deps/couchbase-cxx-client/cmake/CompilerWarnings.cmake +4 -1
  8. package/deps/couchbase-cxx-client/cmake/VersionInfo.cmake +13 -1
  9. package/deps/couchbase-cxx-client/cmake/build_version.hxx.in +1 -0
  10. package/deps/couchbase-cxx-client/core/cluster.hxx +15 -5
  11. package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +17 -6
  12. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +1 -1
  13. package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +93 -0
  14. package/deps/couchbase-cxx-client/core/impl/configuration_profiles_registry.cxx +11 -0
  15. package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +119 -0
  16. package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +108 -0
  17. package/deps/couchbase-cxx-client/core/impl/get.cxx +1 -1
  18. package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +76 -0
  19. package/deps/couchbase-cxx-client/core/impl/query.cxx +5 -7
  20. package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +168 -0
  21. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +15 -1
  22. package/deps/couchbase-cxx-client/core/logger/configuration.hxx +3 -0
  23. package/deps/couchbase-cxx-client/core/logger/level.hxx +21 -0
  24. package/deps/couchbase-cxx-client/core/logger/logger.hxx +4 -6
  25. package/deps/couchbase-cxx-client/core/meta/CMakeLists.txt +4 -2
  26. package/deps/couchbase-cxx-client/core/meta/features.hxx +31 -0
  27. package/deps/couchbase-cxx-client/core/meta/version.cxx +67 -5
  28. package/deps/couchbase-cxx-client/core/meta/version.hxx +12 -1
  29. package/deps/couchbase-cxx-client/core/metrics/CMakeLists.txt +4 -1
  30. package/deps/couchbase-cxx-client/core/metrics/logging_meter.cxx +46 -5
  31. package/deps/couchbase-cxx-client/core/metrics/logging_meter.hxx +10 -26
  32. package/deps/couchbase-cxx-client/core/operations/document_get_projected.cxx +3 -2
  33. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +10 -12
  34. package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -3
  35. package/deps/couchbase-cxx-client/core/operations/management/query_index_build.cxx +8 -14
  36. package/deps/couchbase-cxx-client/core/operations/management/query_index_build.hxx +2 -1
  37. package/deps/couchbase-cxx-client/core/operations/management/query_index_build_deferred.hxx +15 -8
  38. package/deps/couchbase-cxx-client/core/operations/management/query_index_create.cxx +7 -14
  39. package/deps/couchbase-cxx-client/core/operations/management/query_index_create.hxx +2 -0
  40. package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.cxx +11 -16
  41. package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.hxx +2 -0
  42. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.cxx +8 -12
  43. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.hxx +4 -3
  44. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.cxx +21 -12
  45. package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.hxx +3 -2
  46. package/deps/couchbase-cxx-client/core/origin.hxx +1 -1
  47. package/deps/couchbase-cxx-client/core/platform/uuid.cc +1 -2
  48. package/deps/couchbase-cxx-client/core/protocol/cmd_hello.hxx +5 -1
  49. package/deps/couchbase-cxx-client/core/query_context.hxx +79 -0
  50. package/deps/couchbase-cxx-client/core/tracing/CMakeLists.txt +3 -1
  51. package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.cxx +19 -4
  52. package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.hxx +2 -2
  53. package/deps/couchbase-cxx-client/core/transactions/async_attempt_context.hxx +10 -4
  54. package/deps/couchbase-cxx-client/core/transactions/atr_cleanup_entry.cxx +52 -63
  55. package/deps/couchbase-cxx-client/core/transactions/attempt_context.hxx +8 -3
  56. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +163 -126
  57. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.hxx +24 -37
  58. package/deps/couchbase-cxx-client/core/transactions/forward_compat.hxx +4 -4
  59. package/deps/couchbase-cxx-client/core/transactions/internal/atr_cleanup_entry.hxx +51 -13
  60. package/deps/couchbase-cxx-client/core/transactions/internal/client_record.hxx +26 -1
  61. package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.hxx +21 -0
  62. package/deps/couchbase-cxx-client/core/transactions/internal/logging.hxx +40 -18
  63. package/deps/couchbase-cxx-client/core/transactions/internal/transaction_context.hxx +5 -0
  64. package/deps/couchbase-cxx-client/core/transactions/result.hxx +26 -0
  65. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +48 -47
  66. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +6 -6
  67. package/deps/couchbase-cxx-client/core/transactions/transaction_context.cxx +33 -19
  68. package/deps/couchbase-cxx-client/core/transactions/transaction_get_result.hxx +18 -2
  69. package/deps/couchbase-cxx-client/core/transactions/transaction_links.hxx +25 -2
  70. package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +4 -4
  71. package/deps/couchbase-cxx-client/core/transactions/transactions_cleanup.cxx +49 -56
  72. package/deps/couchbase-cxx-client/core/transactions/waitable_op_list.hxx +7 -7
  73. package/deps/couchbase-cxx-client/core/transactions.hxx +0 -12
  74. package/deps/couchbase-cxx-client/core/utils/binary.hxx +1 -1
  75. package/deps/couchbase-cxx-client/core/utils/keyspace.hxx +55 -0
  76. package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +12 -45
  77. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +1 -1
  78. package/deps/couchbase-cxx-client/couchbase/cluster_options.hxx +6 -7
  79. package/deps/couchbase-cxx-client/couchbase/collection.hxx +8 -0
  80. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +218 -0
  81. package/deps/couchbase-cxx-client/couchbase/configuration_profiles_registry.hxx +3 -0
  82. package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +166 -0
  83. package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +172 -0
  84. package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +129 -0
  85. package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +116 -0
  86. package/deps/couchbase-cxx-client/couchbase/fmt/cas.hxx +1 -1
  87. package/deps/couchbase-cxx-client/couchbase/fmt/query_scan_consistency.hxx +46 -0
  88. package/deps/couchbase-cxx-client/couchbase/fmt/query_status.hxx +70 -0
  89. package/deps/couchbase-cxx-client/couchbase/fmt/tls_verify_mode.hxx +46 -0
  90. package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +100 -0
  91. package/deps/couchbase-cxx-client/{core → couchbase}/management/query_index.hxx +2 -2
  92. package/deps/couchbase-cxx-client/couchbase/metrics/meter.hxx +16 -0
  93. package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +178 -6
  94. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +1 -18
  95. package/deps/couchbase-cxx-client/couchbase/scope.hxx +5 -2
  96. package/deps/couchbase-cxx-client/couchbase/tracing/request_tracer.hxx +16 -0
  97. package/deps/couchbase-cxx-client/couchbase/transactions/async_attempt_context.hxx +11 -4
  98. package/deps/couchbase-cxx-client/couchbase/transactions/attempt_context.hxx +5 -3
  99. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_keyspace.hxx +16 -0
  100. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_query_options.hxx +0 -6
  101. package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +115 -0
  102. package/deps/couchbase-cxx-client/examples/minimal.cxx +3 -1
  103. package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +72 -0
  104. package/deps/couchbase-cxx-client/test/test_integration_management.cxx +727 -310
  105. package/deps/couchbase-cxx-client/test/test_integration_query.cxx +4 -8
  106. package/deps/couchbase-cxx-client/test/test_integration_transcoders.cxx +14 -0
  107. package/deps/couchbase-cxx-client/test/test_transaction_transaction_public_blocking_api.cxx +34 -19
  108. package/deps/couchbase-cxx-client/test/test_unit_transaction_logging.cxx +66 -22
  109. package/deps/couchbase-cxx-client/test/test_unit_utils.cxx +51 -0
  110. package/deps/couchbase-cxx-client/test/tools/tool_kv_loader.cxx +2 -2
  111. package/deps/couchbase-cxx-client/test/utils/integration_test_guard.cxx +2 -0
  112. package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +4 -4
  113. package/deps/couchbase-cxx-client/third_party/docopt/.travis.yml +103 -0
  114. package/deps/couchbase-cxx-client/third_party/docopt/CMakeLists.txt +129 -0
  115. package/deps/couchbase-cxx-client/third_party/docopt/LICENSE-Boost-1.0 +23 -0
  116. package/deps/couchbase-cxx-client/third_party/docopt/LICENSE-MIT +23 -0
  117. package/deps/couchbase-cxx-client/third_party/docopt/README.rst +479 -0
  118. package/deps/couchbase-cxx-client/third_party/docopt/docopt-config.cmake +1 -0
  119. package/deps/couchbase-cxx-client/third_party/docopt/docopt.cpp +687 -0
  120. package/deps/couchbase-cxx-client/third_party/docopt/docopt.h +98 -0
  121. package/deps/couchbase-cxx-client/third_party/docopt/docopt.pc.in +9 -0
  122. package/deps/couchbase-cxx-client/third_party/docopt/docopt_private.h +676 -0
  123. package/deps/couchbase-cxx-client/third_party/docopt/docopt_util.h +122 -0
  124. package/deps/couchbase-cxx-client/third_party/docopt/docopt_value.h +341 -0
  125. package/deps/couchbase-cxx-client/third_party/docopt/examples/naval_fate.cpp +36 -0
  126. package/deps/couchbase-cxx-client/third_party/docopt/main.cpp +16 -0
  127. package/deps/couchbase-cxx-client/third_party/docopt/run_testcase.cpp +40 -0
  128. package/deps/couchbase-cxx-client/third_party/docopt/run_tests.py +72 -0
  129. package/deps/couchbase-cxx-client/third_party/docopt/testcases.docopt +957 -0
  130. package/deps/couchbase-cxx-client/tools/CMakeLists.txt +14 -0
  131. package/deps/couchbase-cxx-client/tools/cbc.cxx +65 -0
  132. package/deps/couchbase-cxx-client/tools/command.hxx +31 -0
  133. package/deps/couchbase-cxx-client/tools/command_registry.cxx +43 -0
  134. package/deps/couchbase-cxx-client/tools/command_registry.hxx +39 -0
  135. package/deps/couchbase-cxx-client/tools/get.cxx +267 -0
  136. package/deps/couchbase-cxx-client/tools/get.hxx +26 -0
  137. package/deps/couchbase-cxx-client/tools/query.cxx +441 -0
  138. package/deps/couchbase-cxx-client/tools/query.hxx +26 -0
  139. package/deps/couchbase-cxx-client/tools/utils.cxx +418 -0
  140. package/deps/couchbase-cxx-client/tools/utils.hxx +150 -0
  141. package/deps/couchbase-cxx-client/tools/version.cxx +82 -0
  142. package/deps/couchbase-cxx-client/tools/version.hxx +26 -0
  143. package/dist/authenticators.d.ts +2 -2
  144. package/dist/authenticators.js +1 -2
  145. package/dist/binding.d.ts +32 -16
  146. package/dist/cluster.js +14 -7
  147. package/dist/collection.d.ts +6 -0
  148. package/dist/collection.js +8 -0
  149. package/dist/queryexecutor.js +1 -1
  150. package/dist/queryindexmanager.d.ts +100 -4
  151. package/dist/queryindexmanager.js +344 -118
  152. package/dist/transactions.js +0 -2
  153. package/package.json +1 -1
  154. package/src/connection.cpp +2 -0
  155. package/src/connection.hpp +1 -0
  156. package/src/connection_autogen.cpp +16 -0
  157. package/src/jstocbpp_autogen.hpp +93 -23
  158. package/src/jstocbpp_basic.hpp +24 -0
  159. package/src/jstocbpp_transactions.hpp +0 -8
  160. package/tools/gen-bindings-js.js +1 -0
  161. package/tools/gen-bindings-json.py +4 -2
  162. package/deps/couchbase-cxx-client/core/transactions/logging.cxx +0 -107
@@ -29,45 +29,29 @@ namespace couchbase::core::metrics
29
29
  {
30
30
  class logging_value_recorder;
31
31
 
32
- class logging_meter : public couchbase::metrics::meter
32
+ class logging_meter
33
+ : public couchbase::metrics::meter
34
+ , public std::enable_shared_from_this<logging_meter>
33
35
  {
34
36
  private:
35
37
  asio::steady_timer emit_report_;
36
38
  logging_meter_options options_;
37
39
  std::mutex recorders_mutex_{};
40
+ // service name -> operation name -> recorder
38
41
  std::map<std::string, std::map<std::string, std::shared_ptr<logging_value_recorder>>> recorders_{};
39
42
 
40
43
  void log_report() const;
41
44
 
42
- void rearm_reporter()
43
- {
44
- emit_report_.expires_after(options_.emit_interval);
45
- emit_report_.async_wait([this](std::error_code ec) {
46
- if (ec == asio::error::operation_aborted) {
47
- return;
48
- }
49
- log_report();
50
- rearm_reporter();
51
- });
52
- }
45
+ void rearm_reporter();
53
46
 
54
47
  public:
55
- logging_meter(asio::io_context& ctx, logging_meter_options options)
56
- : emit_report_(ctx)
57
- , options_(options)
58
- {
59
- }
48
+ logging_meter(asio::io_context& ctx, logging_meter_options options);
60
49
 
61
- ~logging_meter() override
62
- {
63
- emit_report_.cancel();
64
- log_report();
65
- }
50
+ ~logging_meter() override;
66
51
 
67
- void start()
68
- {
69
- rearm_reporter();
70
- }
52
+ void start() override;
53
+
54
+ void stop() override;
71
55
 
72
56
  std::shared_ptr<couchbase::metrics::value_recorder> get_value_recorder(const std::string& name,
73
57
  const std::map<std::string, std::string>& tags) override;
@@ -224,8 +224,9 @@ get_projected_request::make_response(key_value_error_context&& ctx, const encode
224
224
  return response;
225
225
  }
226
226
  subdoc_apply_projection(new_doc, projection, value_to_apply, preserve_array_indexes);
227
- } else {
228
- response.ctx.override_ec(errc::key_value::path_not_found);
227
+ } else if (field.status != key_value_status_code::subdoc_path_not_found) {
228
+ response.ctx.override_ec(
229
+ protocol::map_status_code(protocol::client_opcode::subdoc_multi_lookup, static_cast<std::uint16_t>(field.status)));
229
230
  return response;
230
231
  }
231
232
  }
@@ -138,14 +138,8 @@ query_request::encode_to(query_request::encoded_request_type& encoded, http_cont
138
138
  body["scan_wait"] = fmt::format("{}ms", scan_wait.value().count());
139
139
  }
140
140
 
141
- if (scope_qualifier) {
142
- body["query_context"] = scope_qualifier;
143
- } else if (bucket_name) {
144
- if (scope_name) {
145
- body["query_context"] = fmt::format("default:`{}`.`{}`", *bucket_name, *scope_name);
146
- } else {
147
- body["query_context"] = fmt::format("default:`{}`", *bucket_name);
148
- }
141
+ if (query_context) {
142
+ body["query_context"] = query_context.value();
149
143
  }
150
144
  for (const auto& [name, value] : raw) {
151
145
  body[name] = utils::json::parse(value);
@@ -166,16 +160,20 @@ query_request::encode_to(query_request::encoded_request_type& encoded, http_cont
166
160
  if (!prep.is_string()) {
167
161
  prep = false;
168
162
  }
163
+ body.erase("statement");
164
+ body.erase("prepared");
169
165
  if (ctx_->options.show_queries) {
170
- CB_LOG_INFO("QUERY: client_context_id=\"{}\", prep={}, {}",
166
+ CB_LOG_INFO("QUERY: client_context_id=\"{}\", prep={}, {}, options={}",
171
167
  encoded.client_context_id,
172
168
  utils::json::generate(prep),
173
- utils::json::generate(stmt));
169
+ utils::json::generate(stmt),
170
+ utils::json::generate(body));
174
171
  } else {
175
- CB_LOG_DEBUG("QUERY: client_context_id=\"{}\", prep={}, {}",
172
+ CB_LOG_DEBUG("QUERY: client_context_id=\"{}\", prep={}, {}, options={}",
176
173
  encoded.client_context_id,
177
174
  utils::json::generate(prep),
178
- utils::json::generate(stmt));
175
+ utils::json::generate(stmt),
176
+ utils::json::generate(body));
179
177
  }
180
178
  if (row_callback) {
181
179
  encoded.streaming.emplace(couchbase::core::io::streaming_settings{
@@ -92,9 +92,7 @@ struct query_request {
92
92
  std::optional<std::uint64_t> pipeline_cap{};
93
93
  std::optional<query_scan_consistency> scan_consistency{};
94
94
  std::vector<mutation_token> mutation_state{};
95
- std::optional<std::string> bucket_name{};
96
- std::optional<std::string> scope_name{};
97
- std::optional<std::string> scope_qualifier{};
95
+ std::optional<std::string> query_context{};
98
96
  std::optional<std::string> client_context_id{};
99
97
  std::optional<std::chrono::milliseconds> timeout{};
100
98
 
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include "core/utils/join_strings.hxx"
21
21
  #include "core/utils/json.hxx"
22
+ #include "core/utils/keyspace.hxx"
22
23
  #include "error_utils.hxx"
23
24
 
24
25
  namespace couchbase::core::operations::management
@@ -44,23 +45,16 @@ quote_and_join_strings(const Range& values, const std::string& sep)
44
45
  std::error_code
45
46
  query_index_build_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
46
47
  {
47
- if ((scope_name.empty() && !collection_name.empty()) || (!scope_name.empty() && collection_name.empty()) || index_names.empty()) {
48
+ if (!utils::check_query_management_request(*this)) {
48
49
  return errc::common::invalid_argument;
49
50
  }
50
- std::string query_context = fmt::format("{}:`{}`", namespace_id, bucket_name);
51
- std::string statement;
52
- if (!scope_name.empty() && !collection_name.empty()) {
53
- statement = fmt::format(
54
- R"(BUILD INDEX ON `{}`.`{}`.`{}` ({}))", bucket_name, scope_name, collection_name, quote_and_join_strings(index_names, ","));
55
- query_context += ".`" + scope_name + "`";
56
- } else {
57
- statement = fmt::format(R"(BUILD INDEX ON {} ({}))", query_context, quote_and_join_strings(index_names, ","));
58
- query_context += fmt::format(".`{}`", couchbase::scope::default_name);
59
- }
51
+ auto keyspace = core::utils::build_keyspace(*this);
52
+ std::string statement = fmt::format(R"(BUILD INDEX ON {} ({}))", keyspace, quote_and_join_strings(index_names, ","));
60
53
  encoded.headers["content-type"] = "application/json";
61
- tao::json::value body{ { "statement", statement },
62
- { "client_context_id", encoded.client_context_id },
63
- { "query_context", query_context } };
54
+ tao::json::value body{ { "statement", statement }, { "client_context_id", encoded.client_context_id } };
55
+ if (query_ctx.has_value()) {
56
+ body["query_context"] = query_ctx.value();
57
+ }
64
58
  encoded.method = "POST";
65
59
  encoded.path = "/query/service";
66
60
  encoded.body = utils::json::generate(body);
@@ -21,6 +21,7 @@
21
21
  #include "core/io/http_context.hxx"
22
22
  #include "core/io/http_message.hxx"
23
23
  #include "core/platform/uuid.h"
24
+ #include "core/query_context.hxx"
24
25
  #include "core/timeout_defaults.hxx"
25
26
 
26
27
  namespace couchbase::core::operations::management
@@ -47,7 +48,7 @@ struct query_index_build_request {
47
48
  std::string bucket_name;
48
49
  std::string scope_name;
49
50
  std::string collection_name;
50
-
51
+ query_context query_ctx;
51
52
  std::vector<std::string> index_names;
52
53
 
53
54
  std::optional<std::string> client_context_id{};
@@ -18,10 +18,11 @@
18
18
  #pragma once
19
19
 
20
20
  #include "core/error_context/http.hxx"
21
- #include "core/management/query_index.hxx"
22
21
  #include "core/operations/management/query_index_build.hxx"
23
22
  #include "core/operations/management/query_index_get_all_deferred.hxx"
24
23
  #include "core/operations/operation_traits.hxx"
24
+ #include "core/query_context.hxx"
25
+ #include "couchbase/management/query_index.hxx"
25
26
 
26
27
  namespace couchbase::core::operations
27
28
  {
@@ -48,6 +49,7 @@ struct query_index_build_deferred_request {
48
49
  std::string bucket_name;
49
50
  std::optional<std::string> scope_name;
50
51
  std::optional<std::string> collection_name;
52
+ query_context query_ctx;
51
53
 
52
54
  std::optional<std::string> client_context_id{};
53
55
  std::optional<std::chrono::milliseconds> timeout{};
@@ -79,24 +81,29 @@ struct query_index_build_deferred_request {
79
81
  {
80
82
  core->execute(
81
83
  query_index_get_all_deferred_request{
82
- bucket_name, scope_name.value_or(""), collection_name.value_or(""), client_context_id, timeout },
84
+ bucket_name, scope_name.value_or(""), collection_name.value_or(""), query_ctx, client_context_id, timeout },
83
85
  [core,
84
86
  handler = std::move(handler),
85
87
  bucket_name = bucket_name,
86
88
  scope_name = scope_name.value_or(""),
87
89
  collection_name = collection_name.value_or(""),
90
+ query_ctx = query_ctx,
88
91
  client_context_id = client_context_id,
89
92
  timeout = timeout](query_index_get_all_deferred_response resp1) mutable {
90
93
  auto list_resp = std::move(resp1);
91
94
  if (list_resp.ctx.ec || list_resp.index_names.empty()) {
92
95
  return handler(convert_response(std::move(list_resp)));
93
96
  }
94
- core->execute(
95
- query_index_build_request{
96
- std::move(bucket_name), scope_name, collection_name, std::move(list_resp.index_names), client_context_id, timeout },
97
- [handler = std::move(handler)](query_index_build_response build_resp) mutable {
98
- return handler(convert_response(std::move(build_resp)));
99
- });
97
+ core->execute(query_index_build_request{ std::move(bucket_name),
98
+ scope_name,
99
+ collection_name,
100
+ query_ctx,
101
+ std::move(list_resp.index_names),
102
+ client_context_id,
103
+ timeout },
104
+ [handler = std::move(handler)](query_index_build_response build_resp) mutable {
105
+ return handler(convert_response(std::move(build_resp)));
106
+ });
100
107
  });
101
108
  }
102
109
  };
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include "core/utils/join_strings.hxx"
21
21
  #include "core/utils/json.hxx"
22
+ #include "core/utils/keyspace.hxx"
22
23
  #include "error_utils.hxx"
23
24
 
24
25
  namespace couchbase::core::operations::management
@@ -26,7 +27,7 @@ namespace couchbase::core::operations::management
26
27
  std::error_code
27
28
  query_index_create_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
28
29
  {
29
- if ((scope_name.empty() && !collection_name.empty()) || (!scope_name.empty() && collection_name.empty())) {
30
+ if (!core::utils::check_query_management_request(*this)) {
30
31
  return errc::common::invalid_argument;
31
32
  }
32
33
  encoded.headers["content-type"] = "application/json";
@@ -45,17 +46,7 @@ query_index_create_request::encode_to(encoded_request_type& encoded, http_contex
45
46
  if (with) {
46
47
  with_clause = fmt::format("WITH {}", utils::json::generate(with));
47
48
  }
48
- std::string keyspace = fmt::format("{}:`{}`", namespace_id, bucket_name);
49
- auto query_context = keyspace;
50
- if (!scope_name.empty()) {
51
- keyspace += ".`" + scope_name + "`";
52
- query_context += ".`" + scope_name + "`";
53
- } else {
54
- query_context += fmt::format(".`{}`", couchbase::scope::default_name);
55
- }
56
- if (!collection_name.empty()) {
57
- keyspace += ".`" + collection_name + "`";
58
- }
49
+ std::string keyspace = utils::build_keyspace(*this);
59
50
  tao::json::value body{ { "statement",
60
51
  is_primary ? fmt::format(R"(CREATE PRIMARY INDEX {} ON {} USING GSI {})",
61
52
  index_name.empty() ? "" : fmt::format("`{}`", index_name),
@@ -67,8 +58,10 @@ query_index_create_request::encode_to(encoded_request_type& encoded, http_contex
67
58
  utils::join_strings(fields, ", "),
68
59
  where_clause,
69
60
  with_clause) },
70
- { "client_context_id", encoded.client_context_id },
71
- { "query_context", query_context } };
61
+ { "client_context_id", encoded.client_context_id } };
62
+ if (query_ctx.has_value()) {
63
+ body["query_context"] = query_ctx.value();
64
+ }
72
65
  encoded.method = "POST";
73
66
  encoded.path = "/query/service";
74
67
  encoded.body = utils::json::generate(body);
@@ -21,6 +21,7 @@
21
21
  #include "core/io/http_context.hxx"
22
22
  #include "core/io/http_message.hxx"
23
23
  #include "core/platform/uuid.h"
24
+ #include "core/query_context.hxx"
24
25
  #include "core/timeout_defaults.hxx"
25
26
 
26
27
  namespace couchbase::core::operations::management
@@ -49,6 +50,7 @@ struct query_index_create_request {
49
50
  std::string collection_name;
50
51
  std::string index_name{};
51
52
  std::vector<std::string> fields;
53
+ query_context query_ctx;
52
54
  bool is_primary{ false };
53
55
  bool ignore_if_exists{ false };
54
56
  std::optional<std::string> condition{};
@@ -18,6 +18,7 @@
18
18
  #include "query_index_drop.hxx"
19
19
 
20
20
  #include "core/utils/json.hxx"
21
+ #include "core/utils/keyspace.hxx"
21
22
  #include "error_utils.hxx"
22
23
 
23
24
  namespace couchbase::core::operations::management
@@ -25,31 +26,25 @@ namespace couchbase::core::operations::management
25
26
  std::error_code
26
27
  query_index_drop_request::encode_to(encoded_request_type& encoded, http_context& /*context*/) const
27
28
  {
28
- if ((scope_name.empty() && !collection_name.empty()) || (!scope_name.empty() && collection_name.empty())) {
29
+ if (!utils::check_query_management_request(*this)) {
29
30
  return errc::common::invalid_argument;
30
31
  }
31
32
  encoded.headers["content-type"] = "application/json";
32
- std::string query_context = fmt::format("{}:`{}`", namespace_id, bucket_name);
33
- auto keyspace = query_context;
34
- if (!scope_name.empty()) {
35
- query_context += ".`" + scope_name + "`";
36
- keyspace += ".`" + scope_name + "`";
37
- } else {
38
- query_context += fmt::format(".`{}`", couchbase::scope::default_name);
39
- }
40
- if (!collection_name.empty()) {
41
- keyspace += ".`" + collection_name + "`";
42
- }
33
+ auto keyspace = utils::build_keyspace(*this);
43
34
  std::string drop_index_stmt;
44
35
  if (is_primary && index_name.empty()) {
45
36
  drop_index_stmt = fmt::format(R"(DROP PRIMARY INDEX ON {} USING GSI)", keyspace);
46
- } else {
37
+ } else if (bucket_name.empty() || (!collection_name.empty() && !scope_name.empty())) {
47
38
  drop_index_stmt = fmt::format(R"(DROP INDEX `{}` ON {} USING GSI)", index_name, keyspace);
39
+ } else {
40
+ // this works on 6.6 and earlier
41
+ drop_index_stmt = fmt::format(R"(DROP INDEX `{}`.`{}` USING GSI)", bucket_name, index_name);
48
42
  }
49
43
 
50
- tao::json::value body{ { "statement", drop_index_stmt },
51
- { "client_context_id", encoded.client_context_id },
52
- { "query_context", query_context } };
44
+ tao::json::value body{ { "statement", drop_index_stmt }, { "client_context_id", encoded.client_context_id } };
45
+ if (query_ctx.has_value()) {
46
+ body["query_context"] = query_ctx.value();
47
+ }
53
48
  encoded.method = "POST";
54
49
  encoded.path = "/query/service";
55
50
  encoded.body = utils::json::generate(body);
@@ -21,6 +21,7 @@
21
21
  #include "core/io/http_context.hxx"
22
22
  #include "core/io/http_message.hxx"
23
23
  #include "core/platform/uuid.h"
24
+ #include "core/query_context.hxx"
24
25
  #include "core/timeout_defaults.hxx"
25
26
 
26
27
  namespace couchbase::core::operations::management
@@ -48,6 +49,7 @@ struct query_index_drop_request {
48
49
  std::string scope_name;
49
50
  std::string collection_name;
50
51
  std::string index_name;
52
+ query_context query_ctx;
51
53
  bool is_primary{ false };
52
54
  bool ignore_if_does_not_exist{ false };
53
55
 
@@ -38,13 +38,6 @@ query_index_get_all_request::encode_to(encoded_request_type& encoded, couchbase:
38
38
  where = bucket_cond;
39
39
  }
40
40
 
41
- std::string query_context = fmt::format("{}:`{}`", namespace_id, bucket_name);
42
- if (!scope_name.empty()) {
43
- query_context += ".`" + scope_name + "`";
44
- } else {
45
- query_context += fmt::format(".`{}`", couchbase::scope::default_name);
46
- }
47
-
48
41
  if (collection_name == "_default" || collection_name.empty()) {
49
42
  std::string default_collection_cond = "(bucket_id IS MISSING AND keyspace_id = $bucket_name)";
50
43
  where = "(" + where + " OR " + default_collection_cond + ")";
@@ -59,10 +52,13 @@ query_index_get_all_request::encode_to(encoded_request_type& encoded, couchbase:
59
52
  encoded.headers["content-type"] = "application/json";
60
53
  tao::json::value body{ { "statement", statement },
61
54
  { "client_context_id", encoded.client_context_id },
62
- { "$bucket_name", bucket_name },
63
- { "$scope_name", scope_name },
64
- { "$collection_name", collection_name },
65
- { "query_context", query_context } };
55
+ { "$bucket_name", query_ctx.has_value() ? query_ctx.bucket_name() : bucket_name },
56
+ { "$scope_name", query_ctx.has_value() ? query_ctx.scope_name() : scope_name },
57
+ { "$collection_name", collection_name } };
58
+
59
+ if (query_ctx.has_value()) {
60
+ body["query_context"] = query_ctx.value();
61
+ }
66
62
  encoded.method = "POST";
67
63
  encoded.path = "/query/service";
68
64
  encoded.body = utils::json::generate(body);
@@ -90,7 +86,7 @@ query_index_get_all_request::make_response(couchbase::core::error_context::http&
90
86
  return response;
91
87
  }
92
88
  for (const auto& entry : payload.at("results").get_array()) {
93
- couchbase::core::management::query::index index;
89
+ couchbase::management::query::index index;
94
90
  index.type = entry.at("using").get_string();
95
91
  index.name = entry.at("name").get_string();
96
92
  index.state = entry.at("state").get_string();
@@ -20,16 +20,17 @@
20
20
  #include "core/error_context/http.hxx"
21
21
  #include "core/io/http_context.hxx"
22
22
  #include "core/io/http_message.hxx"
23
- #include "core/management/query_index.hxx"
24
23
  #include "core/platform/uuid.h"
24
+ #include "core/query_context.hxx"
25
25
  #include "core/timeout_defaults.hxx"
26
+ #include "couchbase/management/query_index.hxx"
26
27
 
27
28
  namespace couchbase::core::operations::management
28
29
  {
29
30
  struct query_index_get_all_response {
30
31
  error_context::http ctx;
31
32
  std::string status{};
32
- std::vector<couchbase::core::management::query::index> indexes{};
33
+ std::vector<couchbase::management::query::index> indexes{};
33
34
  };
34
35
 
35
36
  struct query_index_get_all_request {
@@ -44,7 +45,7 @@ struct query_index_get_all_request {
44
45
  std::string bucket_name;
45
46
  std::string scope_name;
46
47
  std::string collection_name;
47
-
48
+ query_context query_ctx;
48
49
  std::optional<std::string> client_context_id{};
49
50
  std::optional<std::chrono::milliseconds> timeout{};
50
51
 
@@ -25,18 +25,25 @@ namespace couchbase::core::operations::management
25
25
  std::error_code
26
26
  query_index_get_all_deferred_request::encode_to(encoded_request_type& encoded, couchbase::core::http_context& /* context */) const
27
27
  {
28
+
29
+ // essentially same as query_index_get_all_request::encode_to, except for the state condition. If you
30
+ // change this, you probably need to change that as well.
31
+ std::string bucket_cond = "bucket_id = $bucket_name";
32
+ std::string scope_cond = "(" + bucket_cond + " AND scope_id = $scope_name)";
33
+ std::string collection_cond = "(" + scope_cond + " AND keyspace_id = $collection_name)";
34
+
28
35
  std::string where;
29
- if (collection_name.empty()) {
30
- where = "(keyspace_id = $bucket_name AND bucket_id IS MISSING)";
36
+ if (!collection_name.empty()) {
37
+ where = collection_cond;
38
+ } else if (!scope_name.empty()) {
39
+ where = scope_cond;
31
40
  } else {
32
- where = "(bucket_id = $bucket_name AND scope_id = $scope_name AND keyspace_id = $collection_name)";
41
+ where = bucket_cond;
33
42
  }
34
43
 
35
- std::string query_context = fmt::format("{}:`{}`", namespace_id, bucket_name);
36
- if (!scope_name.empty()) {
37
- query_context += ".`" + scope_name + "`";
38
- } else {
39
- query_context += fmt::format(".`{}`", couchbase::scope::default_name);
44
+ if (collection_name == "_default" || collection_name.empty()) {
45
+ std::string default_collection_cond = "(bucket_id IS MISSING AND keyspace_id = $bucket_name)";
46
+ where = "(" + where + " OR " + default_collection_cond + ")";
40
47
  }
41
48
 
42
49
  std::string statement = "SELECT RAW name FROM system:indexes"
@@ -48,10 +55,12 @@ query_index_get_all_deferred_request::encode_to(encoded_request_type& encoded, c
48
55
  encoded.headers["content-type"] = "application/json";
49
56
  tao::json::value body{ { "statement", statement },
50
57
  { "client_context_id", encoded.client_context_id },
51
- { "$bucket_name", bucket_name },
52
- { "$scope_name", scope_name },
53
- { "$collection_name", collection_name },
54
- { "query_context", query_context } };
58
+ { "$bucket_name", query_ctx.has_value() ? query_ctx.bucket_name() : bucket_name },
59
+ { "$scope_name", query_ctx.has_value() ? query_ctx.scope_name() : scope_name },
60
+ { "$collection_name", collection_name } };
61
+ if (query_ctx.has_value()) {
62
+ body["query_context"] = query_ctx.value();
63
+ }
55
64
  encoded.method = "POST";
56
65
  encoded.path = "/query/service";
57
66
  encoded.body = utils::json::generate(body);
@@ -20,9 +20,10 @@
20
20
  #include "core/error_context/http.hxx"
21
21
  #include "core/io/http_context.hxx"
22
22
  #include "core/io/http_message.hxx"
23
- #include "core/management/query_index.hxx"
24
23
  #include "core/platform/uuid.h"
24
+ #include "core/query_context.hxx"
25
25
  #include "core/timeout_defaults.hxx"
26
+ #include "couchbase/management/query_index.hxx"
26
27
 
27
28
  namespace couchbase::core::operations::management
28
29
  {
@@ -44,7 +45,7 @@ struct query_index_get_all_deferred_request {
44
45
  std::string bucket_name;
45
46
  std::string scope_name;
46
47
  std::string collection_name;
47
-
48
+ query_context query_ctx;
48
49
  std::optional<std::string> client_context_id{};
49
50
  std::optional<std::chrono::milliseconds> timeout{};
50
51
 
@@ -31,7 +31,7 @@ struct cluster_credentials {
31
31
  std::string password{};
32
32
  std::string certificate_path{};
33
33
  std::string key_path{};
34
- std::vector<std::string> allowed_sasl_mechanisms{ "SCRAM-SHA512", "SCRAM-SHA256", "SCRAM-SHA1", "PLAIN" };
34
+ std::optional<std::vector<std::string>> allowed_sasl_mechanisms{};
35
35
 
36
36
  [[nodiscard]] bool uses_certificate() const
37
37
  {
@@ -21,12 +21,11 @@
21
21
 
22
22
  #include <iomanip>
23
23
  #include <random>
24
- #include <sstream>
25
24
 
26
25
  void
27
26
  couchbase::core::uuid::random(couchbase::core::uuid::uuid_t& uuid)
28
27
  {
29
- static thread_local std::minstd_rand gen{ std::random_device()() };
28
+ static thread_local std::mt19937_64 gen{ std::random_device()() };
30
29
  std::uniform_int_distribution<std::uint64_t> dis;
31
30
 
32
31
  // The uuid is 16 bytes, which is the same as two 64-bit integers
@@ -59,7 +59,6 @@ class hello_request_body
59
59
  std::vector<std::byte> key_;
60
60
  std::vector<hello_feature> features_{
61
61
  hello_feature::tcp_nodelay,
62
- hello_feature::mutation_seqno,
63
62
  hello_feature::xattr,
64
63
  hello_feature::xerror,
65
64
  hello_feature::select_bucket,
@@ -93,6 +92,11 @@ class hello_request_body
93
92
  features_.emplace_back(hello_feature::snappy);
94
93
  }
95
94
 
95
+ void enable_mutation_tokens()
96
+ {
97
+ features_.emplace_back(hello_feature::mutation_seqno);
98
+ }
99
+
96
100
  [[nodiscard]] const std::vector<hello_feature>& features() const
97
101
  {
98
102
  return features_;
@@ -0,0 +1,79 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-2023 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
+ #pragma once
18
+
19
+ #include <fmt/format.h>
20
+ #include <optional>
21
+ #include <string>
22
+
23
+ namespace couchbase::core
24
+ {
25
+
26
+ class query_context
27
+ {
28
+ public:
29
+ query_context() = default;
30
+ query_context(std::string namespace_id, std::string bucket_name, std::string scope_name)
31
+ : namespace_id_(namespace_id)
32
+ , bucket_name_(bucket_name)
33
+ , scope_name_(scope_name)
34
+ {
35
+ }
36
+
37
+ query_context(std::string bucket_name, std::string scope_name)
38
+ : bucket_name_(bucket_name)
39
+ , scope_name_(scope_name)
40
+ {
41
+ }
42
+
43
+ bool has_value() const
44
+ {
45
+ return bucket_name_.has_value() && scope_name_.has_value();
46
+ }
47
+
48
+ std::string value() const
49
+ {
50
+ if (has_value()) {
51
+ return fmt::format("{}:`{}`.`{}`", namespace_id_, bucket_name_.value(), scope_name_.value());
52
+ }
53
+ return {};
54
+ }
55
+ std::string bucket_name() const
56
+ {
57
+ if (has_value()) {
58
+ return bucket_name_.value();
59
+ }
60
+ return "";
61
+ }
62
+ std::string scope_name() const
63
+ {
64
+ if (has_value()) {
65
+ return scope_name_.value();
66
+ }
67
+ return "";
68
+ }
69
+ std::string namespace_id() const
70
+ {
71
+ return namespace_id_;
72
+ }
73
+
74
+ private:
75
+ std::string namespace_id_{ "default" };
76
+ std::optional<std::string> bucket_name_;
77
+ std::optional<std::string> scope_name_;
78
+ };
79
+ } // namespace couchbase::core
@@ -6,4 +6,6 @@ target_link_libraries(
6
6
  project_warnings
7
7
  fmt::fmt
8
8
  spdlog::spdlog)
9
- target_include_directories(couchbase_tracing PRIVATE ../..)
9
+ target_include_directories(couchbase_tracing PRIVATE
10
+ ${PROJECT_BINARY_DIR}/generated
11
+ ${PROJECT_SOURCE_DIR})