couchbase 3.0.0.beta.1-universal-darwin-19 → 3.0.0-universal-darwin-19

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +227 -0
  3. data/.rubocop_todo.yml +47 -0
  4. data/CONTRIBUTING.md +110 -0
  5. data/Gemfile +4 -0
  6. data/README.md +3 -3
  7. data/Rakefile +1 -1
  8. data/couchbase.gemspec +40 -39
  9. data/examples/analytics.rb +123 -108
  10. data/examples/auth.rb +33 -0
  11. data/examples/crud.rb +16 -2
  12. data/examples/managing_analytics_indexes.rb +18 -4
  13. data/examples/managing_buckets.rb +17 -3
  14. data/examples/managing_collections.rb +22 -9
  15. data/examples/managing_query_indexes.rb +38 -18
  16. data/examples/managing_search_indexes.rb +21 -6
  17. data/examples/managing_view_indexes.rb +18 -4
  18. data/examples/query.rb +17 -3
  19. data/examples/query_with_consistency.rb +30 -20
  20. data/examples/search.rb +116 -101
  21. data/examples/search_with_consistency.rb +43 -30
  22. data/examples/subdocument.rb +42 -30
  23. data/examples/view.rb +19 -10
  24. data/ext/CMakeLists.txt +40 -2
  25. data/ext/build_version.hxx.in +1 -1
  26. data/ext/couchbase/bucket.hxx +190 -38
  27. data/ext/couchbase/cluster.hxx +22 -4
  28. data/ext/couchbase/configuration.hxx +14 -14
  29. data/ext/couchbase/couchbase.cxx +108 -12
  30. data/ext/couchbase/error_map.hxx +202 -2
  31. data/ext/couchbase/errors.hxx +8 -2
  32. data/ext/couchbase/io/dns_client.hxx +6 -6
  33. data/ext/couchbase/io/http_command.hxx +2 -2
  34. data/ext/couchbase/io/http_session.hxx +7 -11
  35. data/ext/couchbase/io/http_session_manager.hxx +3 -3
  36. data/ext/couchbase/io/mcbp_command.hxx +101 -44
  37. data/ext/couchbase/io/mcbp_session.hxx +144 -49
  38. data/ext/couchbase/io/retry_action.hxx +30 -0
  39. data/ext/couchbase/io/retry_context.hxx +39 -0
  40. data/ext/couchbase/io/retry_orchestrator.hxx +96 -0
  41. data/ext/couchbase/io/retry_reason.hxx +235 -0
  42. data/ext/couchbase/io/retry_strategy.hxx +156 -0
  43. data/ext/couchbase/operations/document_decrement.hxx +2 -0
  44. data/ext/couchbase/operations/document_exists.hxx +2 -0
  45. data/ext/couchbase/operations/document_get.hxx +2 -0
  46. data/ext/couchbase/operations/document_get_and_lock.hxx +2 -0
  47. data/ext/couchbase/operations/document_get_and_touch.hxx +2 -0
  48. data/ext/couchbase/operations/document_get_projected.hxx +2 -0
  49. data/ext/couchbase/operations/document_increment.hxx +2 -0
  50. data/ext/couchbase/operations/document_insert.hxx +2 -0
  51. data/ext/couchbase/operations/document_lookup_in.hxx +2 -0
  52. data/ext/couchbase/operations/document_mutate_in.hxx +3 -0
  53. data/ext/couchbase/operations/document_query.hxx +10 -0
  54. data/ext/couchbase/operations/document_remove.hxx +2 -0
  55. data/ext/couchbase/operations/document_replace.hxx +2 -0
  56. data/ext/couchbase/operations/document_search.hxx +8 -3
  57. data/ext/couchbase/operations/document_touch.hxx +2 -0
  58. data/ext/couchbase/operations/document_unlock.hxx +2 -0
  59. data/ext/couchbase/operations/document_upsert.hxx +2 -0
  60. data/ext/couchbase/operations/query_index_create.hxx +14 -4
  61. data/ext/couchbase/operations/query_index_drop.hxx +12 -2
  62. data/ext/couchbase/operations/query_index_get_all.hxx +11 -2
  63. data/ext/couchbase/origin.hxx +47 -17
  64. data/ext/couchbase/platform/backtrace.c +189 -0
  65. data/ext/couchbase/platform/backtrace.h +54 -0
  66. data/ext/couchbase/platform/terminate_handler.cc +122 -0
  67. data/ext/couchbase/platform/terminate_handler.h +36 -0
  68. data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +6 -1
  69. data/ext/couchbase/protocol/status.hxx +14 -4
  70. data/ext/couchbase/version.hxx +2 -2
  71. data/ext/extconf.rb +39 -36
  72. data/ext/test/main.cxx +64 -16
  73. data/lib/couchbase.rb +0 -1
  74. data/lib/couchbase/analytics_options.rb +2 -4
  75. data/lib/couchbase/authenticator.rb +14 -0
  76. data/lib/couchbase/binary_collection.rb +9 -9
  77. data/lib/couchbase/binary_collection_options.rb +8 -6
  78. data/lib/couchbase/bucket.rb +18 -18
  79. data/lib/couchbase/cluster.rb +121 -90
  80. data/lib/couchbase/collection.rb +36 -38
  81. data/lib/couchbase/collection_options.rb +31 -17
  82. data/lib/couchbase/common_options.rb +1 -1
  83. data/lib/couchbase/datastructures/couchbase_list.rb +16 -16
  84. data/lib/couchbase/datastructures/couchbase_map.rb +18 -18
  85. data/lib/couchbase/datastructures/couchbase_queue.rb +13 -13
  86. data/lib/couchbase/datastructures/couchbase_set.rb +8 -7
  87. data/lib/couchbase/errors.rb +10 -3
  88. data/lib/couchbase/json_transcoder.rb +2 -2
  89. data/lib/couchbase/libcouchbase.bundle +0 -0
  90. data/lib/couchbase/management/analytics_index_manager.rb +37 -37
  91. data/lib/couchbase/management/bucket_manager.rb +25 -25
  92. data/lib/couchbase/management/collection_manager.rb +3 -3
  93. data/lib/couchbase/management/query_index_manager.rb +59 -14
  94. data/lib/couchbase/management/search_index_manager.rb +15 -12
  95. data/lib/couchbase/management/user_manager.rb +1 -1
  96. data/lib/couchbase/management/view_index_manager.rb +11 -5
  97. data/lib/couchbase/mutation_state.rb +12 -0
  98. data/lib/couchbase/query_options.rb +23 -9
  99. data/lib/couchbase/scope.rb +61 -1
  100. data/lib/couchbase/search_options.rb +40 -27
  101. data/lib/couchbase/subdoc.rb +31 -28
  102. data/lib/couchbase/version.rb +2 -2
  103. data/lib/couchbase/view_options.rb +0 -1
  104. metadata +20 -7
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_decrement.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -45,6 +46,7 @@ struct decrement_request {
45
46
  protocol::durability_level durability_level{ protocol::durability_level::none };
46
47
  std::optional<std::uint16_t> durability_timeout{};
47
48
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
49
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
48
50
 
49
51
  void encode_to(encoded_request_type& encoded)
50
52
  {
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_exists.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -42,6 +43,7 @@ struct exists_request {
42
43
  std::uint16_t partition{};
43
44
  std::uint32_t opaque{};
44
45
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
46
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
45
47
 
46
48
  void encode_to(encoded_request_type& encoded)
47
49
  {
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_get.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -40,6 +41,7 @@ struct get_request {
40
41
  uint16_t partition{};
41
42
  uint32_t opaque{};
42
43
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
44
+ io::retry_context<io::retry_strategy::best_effort> retries{ true };
43
45
 
44
46
  void encode_to(encoded_request_type& encoded)
45
47
  {
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_get_and_lock.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -41,6 +42,7 @@ struct get_and_lock_request {
41
42
  uint32_t opaque{};
42
43
  uint32_t lock_time{};
43
44
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
45
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
44
46
 
45
47
  void encode_to(encoded_request_type& encoded)
46
48
  {
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_get_and_touch.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -41,6 +42,7 @@ struct get_and_touch_request {
41
42
  uint32_t opaque{};
42
43
  uint32_t expiry{};
43
44
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
45
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
44
46
 
45
47
  void encode_to(encoded_request_type& encoded)
46
48
  {
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_lookup_in.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -45,6 +46,7 @@ struct get_projected_request {
45
46
  std::vector<std::string> effective_projections{};
46
47
  bool preserve_array_indexes{ false };
47
48
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
49
+ io::retry_context<io::retry_strategy::best_effort> retries{ true };
48
50
 
49
51
  void encode_to(encoded_request_type& encoded)
50
52
  {
@@ -21,6 +21,7 @@
21
21
  #include <protocol/durability_level.hxx>
22
22
  #include <operations.hxx>
23
23
  #include <protocol/client_response.hxx>
24
+ #include <io/retry_context.hxx>
24
25
 
25
26
  namespace couchbase::operations
26
27
  {
@@ -47,6 +48,7 @@ struct increment_request {
47
48
  protocol::durability_level durability_level{ protocol::durability_level::none };
48
49
  std::optional<std::uint16_t> durability_timeout{};
49
50
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
51
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
50
52
 
51
53
  void encode_to(encoded_request_type& encoded)
52
54
  {
@@ -20,6 +20,7 @@
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_insert.hxx>
22
22
  #include <protocol/durability_level.hxx>
23
+ #include <io/retry_context.hxx>
23
24
 
24
25
  namespace couchbase::operations
25
26
  {
@@ -45,6 +46,7 @@ struct insert_request {
45
46
  protocol::durability_level durability_level{ protocol::durability_level::none };
46
47
  std::optional<std::uint16_t> durability_timeout{};
47
48
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
49
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
48
50
 
49
51
  void encode_to(encoded_request_type& encoded)
50
52
  {
@@ -20,6 +20,7 @@
20
20
  #include <gsl/gsl_assert>
21
21
  #include <document_id.hxx>
22
22
  #include <protocol/cmd_lookup_in.hxx>
23
+ #include <io/retry_context.hxx>
23
24
 
24
25
  namespace couchbase::operations
25
26
  {
@@ -50,6 +51,7 @@ struct lookup_in_request {
50
51
  bool access_deleted{ false };
51
52
  protocol::lookup_in_request_body::lookup_in_specs specs{};
52
53
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
54
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
53
55
 
54
56
  void encode_to(encoded_request_type& encoded)
55
57
  {
@@ -25,6 +25,8 @@
25
25
  #include <protocol/durability_level.hxx>
26
26
  #include <protocol/client_request.hxx>
27
27
 
28
+ #include <io/retry_context.hxx>
29
+
28
30
  #include <mutation_token.hxx>
29
31
  #include <document_id.hxx>
30
32
  #include <timeout_defaults.hxx>
@@ -67,6 +69,7 @@ struct mutate_in_request {
67
69
  protocol::durability_level durability_level{ protocol::durability_level::none };
68
70
  std::optional<std::uint16_t> durability_timeout{};
69
71
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
72
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
70
73
 
71
74
  void encode_to(encoded_request_type& encoded)
72
75
  {
@@ -168,6 +168,9 @@ struct query_request {
168
168
  std::optional<scan_consistency_type> scan_consistency{};
169
169
  std::vector<mutation_token> mutation_state{};
170
170
  std::chrono::milliseconds timeout{ timeout_defaults::query_timeout };
171
+ std::optional<std::string> bucket_name{};
172
+ std::optional<std::string> scope_name{};
173
+ std::optional<std::string> scope_qualifier{};
171
174
 
172
175
  enum class profile_mode {
173
176
  off,
@@ -255,6 +258,13 @@ struct query_request {
255
258
  if (check_scan_wait && scan_wait) {
256
259
  body["scan_wait"] = fmt::format("{}ms", scan_wait.value());
257
260
  }
261
+ if (scope_qualifier) {
262
+ body["query_context"] = scope_qualifier;
263
+ } else if (scope_name) {
264
+ if (bucket_name) {
265
+ body["query_context"] = fmt::format("`{}`.{}", *bucket_name, *scope_name);
266
+ }
267
+ }
258
268
  for (auto& param : raw) {
259
269
  body[param.first] = param.second;
260
270
  }
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_remove.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -41,6 +42,7 @@ struct remove_request {
41
42
  protocol::durability_level durability_level{ protocol::durability_level::none };
42
43
  std::optional<std::uint16_t> durability_timeout{};
43
44
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
45
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
44
46
 
45
47
  void encode_to(encoded_request_type& encoded)
46
48
  {
@@ -20,6 +20,7 @@
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_replace.hxx>
22
22
  #include <protocol/durability_level.hxx>
23
+ #include <io/retry_context.hxx>
23
24
 
24
25
  namespace couchbase::operations
25
26
  {
@@ -46,6 +47,7 @@ struct replace_request {
46
47
  protocol::durability_level durability_level{ protocol::durability_level::none };
47
48
  std::optional<std::uint16_t> durability_timeout{};
48
49
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
50
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
49
51
 
50
52
  void encode_to(encoded_request_type& encoded)
51
53
  {
@@ -231,7 +231,7 @@ make_response(std::error_code ec, search_request& request, search_request::encod
231
231
  search_response::search_row row{};
232
232
  row.index = entry.at("index").get_string();
233
233
  row.id = entry.at("id").get_string();
234
- row.score = entry.at("score").get_double();
234
+ row.score = entry.at("score").as<double>();
235
235
  const auto* locations = entry.find("locations");
236
236
  if (locations != nullptr && locations->is_object()) {
237
237
  for (const auto& field : locations->get_object()) {
@@ -306,7 +306,7 @@ make_response(std::error_code ec, search_request& request, search_request::encod
306
306
  const auto* min = numeric_range.find("min");
307
307
  if (min != nullptr) {
308
308
  if (min->is_double()) {
309
- nrf.min = min->get_double();
309
+ nrf.min = min->as<double>();
310
310
  } else if (min->is_integer()) {
311
311
  nrf.min = min->get_unsigned();
312
312
  }
@@ -314,7 +314,7 @@ make_response(std::error_code ec, search_request& request, search_request::encod
314
314
  const auto* max = numeric_range.find("max");
315
315
  if (max != nullptr) {
316
316
  if (max->is_double()) {
317
- nrf.max = max->get_double();
317
+ nrf.max = max->as<double>();
318
318
  } else if (max->is_integer()) {
319
319
  nrf.max = max->get_unsigned();
320
320
  }
@@ -346,6 +346,11 @@ make_response(std::error_code ec, search_request& request, search_request::encod
346
346
  response.ec = std::make_error_code(error::common_errc::index_not_found);
347
347
  return response;
348
348
  }
349
+ if (response.error.find("no planPIndexes for indexName") != std::string::npos ||
350
+ response.error.find("pindex_consistency mismatched partition") != std::string::npos) {
351
+ response.ec = std::make_error_code(error::search_errc::index_not_ready);
352
+ return response;
353
+ }
349
354
  }
350
355
  response.ec = std::make_error_code(error::common_errc::internal_server_failure);
351
356
  }
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_touch.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -39,6 +40,7 @@ struct touch_request {
39
40
  std::uint32_t opaque{};
40
41
  std::uint32_t expiry{};
41
42
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
43
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
42
44
 
43
45
  void encode_to(encoded_request_type& encoded)
44
46
  {
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_unlock.hxx>
22
+ #include <io/retry_context.hxx>
22
23
 
23
24
  namespace couchbase::operations
24
25
  {
@@ -39,6 +40,7 @@ struct unlock_request {
39
40
  uint32_t opaque{};
40
41
  uint64_t cas{};
41
42
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
43
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
42
44
 
43
45
  void encode_to(encoded_request_type& encoded)
44
46
  {
@@ -20,6 +20,7 @@
20
20
  #include <document_id.hxx>
21
21
  #include <protocol/cmd_upsert.hxx>
22
22
  #include <protocol/durability_level.hxx>
23
+ #include <io/retry_context.hxx>
23
24
 
24
25
  namespace couchbase::operations
25
26
  {
@@ -45,6 +46,7 @@ struct upsert_request {
45
46
  protocol::durability_level durability_level{ protocol::durability_level::none };
46
47
  std::optional<std::uint16_t> durability_timeout{};
47
48
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
49
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
48
50
 
49
51
  void encode_to(encoded_request_type& encoded)
50
52
  {
@@ -42,7 +42,10 @@ struct query_index_create_request {
42
42
  static const inline service_type type = service_type::query;
43
43
 
44
44
  std::string client_context_id{ uuid::to_string(uuid::random()) };
45
+ static constexpr auto namespace_id = "default";
45
46
  std::string bucket_name;
47
+ std::string scope_name;
48
+ std::string collection_name;
46
49
  std::string index_name{};
47
50
  std::vector<std::string> fields;
48
51
  bool is_primary{ false };
@@ -70,14 +73,21 @@ struct query_index_create_request {
70
73
  if (with) {
71
74
  with_clause = fmt::format("WITH {}", tao::json::to_string(with));
72
75
  }
76
+ std::string keyspace = fmt::format("{}:`{}`", namespace_id, bucket_name);
77
+ if (!scope_name.empty()) {
78
+ keyspace += ".`" + scope_name + "`";
79
+ }
80
+ if (!collection_name.empty()) {
81
+ keyspace += ".`" + collection_name + "`";
82
+ }
73
83
  tao::json::value body{ { "statement",
74
- is_primary ? fmt::format(R"(CREATE PRIMARY INDEX {} ON `{}` USING GSI {})",
84
+ is_primary ? fmt::format(R"(CREATE PRIMARY INDEX {} ON {} USING GSI {})",
75
85
  index_name.empty() ? "" : fmt::format("`{}`", index_name),
76
- bucket_name,
86
+ keyspace,
77
87
  with_clause)
78
- : fmt::format(R"(CREATE INDEX `{}` ON `{}`({}) {} USING GSI {})",
88
+ : fmt::format(R"(CREATE INDEX `{}` ON {}({}) {} USING GSI {})",
79
89
  index_name,
80
- bucket_name,
90
+ keyspace,
81
91
  fmt::join(fields, ", "),
82
92
  where_clause,
83
93
  with_clause) },
@@ -42,7 +42,10 @@ struct query_index_drop_request {
42
42
  static const inline service_type type = service_type::query;
43
43
 
44
44
  std::string client_context_id{ uuid::to_string(uuid::random()) };
45
+ static constexpr auto namespace_id = "default";
45
46
  std::string bucket_name;
47
+ std::string scope_name;
48
+ std::string collection_name;
46
49
  std::string index_name;
47
50
  bool is_primary{ false };
48
51
  bool ignore_if_does_not_exist{ false };
@@ -51,9 +54,16 @@ struct query_index_drop_request {
51
54
  void encode_to(encoded_request_type& encoded)
52
55
  {
53
56
  encoded.headers["content-type"] = "application/json";
57
+ std::string keyspace = fmt::format("`{}`", bucket_name);
58
+ if (!scope_name.empty()) {
59
+ keyspace += ".`" + scope_name + "`";
60
+ }
61
+ if (!collection_name.empty()) {
62
+ keyspace += ".`" + collection_name + "`";
63
+ }
54
64
  tao::json::value body{ { "statement",
55
- is_primary ? fmt::format(R"(DROP PRIMARY INDEX ON `{}` USING GSI)", bucket_name)
56
- : fmt::format(R"(DROP INDEX `{}`.`{}` USING GSI)", bucket_name, index_name) },
65
+ is_primary ? fmt::format(R"(DROP PRIMARY INDEX ON {} USING GSI)", keyspace)
66
+ : fmt::format(R"(DROP INDEX {}.`{}` USING GSI)", keyspace, index_name) },
57
67
  { "client_context_id", client_context_id } };
58
68
  encoded.method = "POST";
59
69
  encoded.path = "/query/service";
@@ -32,9 +32,12 @@ struct query_index_get_all_response {
32
32
  std::string datastore_id;
33
33
  std::string keyspace_id;
34
34
  std::string namespace_id;
35
+ std::string collection_name;
35
36
  std::string type;
36
37
  std::vector<std::string> index_key{};
37
38
  std::optional<std::string> condition{};
39
+ std::optional<std::string> bucket_id{};
40
+ std::optional<std::string> scope_id{};
38
41
  };
39
42
  std::string client_context_id;
40
43
  std::error_code ec;
@@ -59,8 +62,8 @@ struct query_index_get_all_request {
59
62
  tao::json::value body{
60
63
  { "statement",
61
64
  fmt::format(
62
- R"(SELECT idx.* FROM system:indexes AS idx WHERE keyspace_id = "{}" AND `using`="gsi" ORDER BY is_primary DESC, name ASC)",
63
- bucket_name) },
65
+ R"(SELECT idx.* FROM system:indexes AS idx WHERE ((keyspace_id = "{}" AND bucket_id IS MISSING) OR (bucket_id = "{}")) AND `using`="gsi" ORDER BY is_primary DESC, name ASC)",
66
+ bucket_name, bucket_name) },
64
67
  { "client_context_id", client_context_id }
65
68
  };
66
69
  encoded.method = "POST";
@@ -87,6 +90,12 @@ make_response(std::error_code ec, query_index_get_all_request& request, query_in
87
90
  index.type = entry.at("using").get_string();
88
91
  index.name = entry.at("name").get_string();
89
92
  index.state = entry.at("state").get_string();
93
+ if (const auto* prop = entry.find("bucket_id")) {
94
+ index.bucket_id = prop->get_string();
95
+ }
96
+ if (const auto* prop = entry.find("scope_id")) {
97
+ index.scope_id = prop->get_string();
98
+ }
90
99
  if (const auto* prop = entry.find("is_primary")) {
91
100
  index.is_primary = prop->get_boolean();
92
101
  }
@@ -23,6 +23,18 @@
23
23
 
24
24
  namespace couchbase
25
25
  {
26
+ struct cluster_credentials {
27
+ std::string username;
28
+ std::string password;
29
+ std::string certificate_path;
30
+ std::string key_path;
31
+
32
+ [[nodiscard]] bool uses_certificate() const
33
+ {
34
+ return !certificate_path.empty();
35
+ }
36
+ };
37
+
26
38
  struct origin {
27
39
  using node_entry = std::pair<std::string, std::string>;
28
40
  using node_list = std::vector<node_entry>;
@@ -33,26 +45,31 @@ struct origin {
33
45
 
34
46
  origin(const origin& other)
35
47
  : options_(other.options_)
36
- , username_(other.username_)
37
- , password_(other.password_)
48
+ , credentials_(std::move(other.credentials_))
38
49
  , nodes_(other.nodes_)
39
50
  , next_node_(nodes_.begin())
40
51
  {
41
52
  }
42
53
 
43
- origin(std::string username, std::string password, const std::string& hostname, std::uint16_t port, const cluster_options& options)
54
+ origin(cluster_credentials auth, const std::string& hostname, std::uint16_t port, const cluster_options& options)
44
55
  : options_(options)
45
- , username_(std::move(username))
46
- , password_(std::move(password))
56
+ , credentials_(std::move(auth))
47
57
  , nodes_{ { hostname, std::to_string(port) } }
48
58
  , next_node_(nodes_.begin())
49
59
  {
50
60
  }
51
61
 
52
- origin(std::string username, std::string password, const utils::connection_string& connstr)
62
+ origin(cluster_credentials auth, const std::string& hostname, const std::string& port, const cluster_options& options)
63
+ : options_(options)
64
+ , credentials_(std::move(auth))
65
+ , nodes_{ { hostname, port } }
66
+ , next_node_(nodes_.begin())
67
+ {
68
+ }
69
+
70
+ origin(cluster_credentials auth, const utils::connection_string& connstr)
53
71
  : options_(connstr.options)
54
- , username_(std::move(username))
55
- , password_(std::move(password))
72
+ , credentials_(std::move(auth))
56
73
  {
57
74
  nodes_.reserve(connstr.bootstrap_nodes.size());
58
75
  for (const auto& node : connstr.bootstrap_nodes) {
@@ -66,8 +83,7 @@ struct origin {
66
83
  {
67
84
  if (this != &other) {
68
85
  options_ = other.options_;
69
- username_ = other.username_;
70
- password_ = other.password_;
86
+ credentials_ = other.credentials_;
71
87
  nodes_ = other.nodes_;
72
88
  next_node_ = nodes_.begin();
73
89
  exhausted_ = false;
@@ -75,21 +91,31 @@ struct origin {
75
91
  return *this;
76
92
  }
77
93
 
78
- [[nodiscard]] const std::string& get_username() const
94
+ [[nodiscard]] const std::string& username() const
79
95
  {
80
- return username_;
96
+ return credentials_.username;
81
97
  }
82
98
 
83
- [[nodiscard]] const std::string& get_password() const
99
+ [[nodiscard]] const std::string& password() const
84
100
  {
85
- return password_;
101
+ return credentials_.password;
102
+ }
103
+
104
+ [[nodiscard]] const std::string& certificate_path() const
105
+ {
106
+ return credentials_.certificate_path;
107
+ }
108
+
109
+ [[nodiscard]] const std::string& key_path() const
110
+ {
111
+ return credentials_.key_path;
86
112
  }
87
113
 
88
114
  [[nodiscard]] std::vector<std::string> get_nodes() const
89
115
  {
90
116
  std::vector<std::string> res;
91
117
  res.reserve(nodes_.size());
92
- for (const auto &node : nodes_) {
118
+ for (const auto& node : nodes_) {
93
119
  res.emplace_back(fmt::format("\"{}:{}\"", node.first, node.second));
94
120
  }
95
121
  return res;
@@ -136,10 +162,14 @@ struct origin {
136
162
  return options_;
137
163
  }
138
164
 
165
+ [[nodiscard]] const couchbase::cluster_credentials& credentials() const
166
+ {
167
+ return credentials_;
168
+ }
169
+
139
170
  private:
140
171
  couchbase::cluster_options options_{};
141
- std::string username_{};
142
- std::string password_{};
172
+ cluster_credentials credentials_{};
143
173
  node_list nodes_{};
144
174
  node_list::iterator next_node_{};
145
175
  bool exhausted_{ false };