couchbase 4.2.1 → 4.2.2

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