couchbase 3.0.0.beta.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) 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/management/analytics_index_manager.rb +37 -37
  90. data/lib/couchbase/management/bucket_manager.rb +25 -25
  91. data/lib/couchbase/management/collection_manager.rb +3 -3
  92. data/lib/couchbase/management/query_index_manager.rb +59 -14
  93. data/lib/couchbase/management/search_index_manager.rb +15 -12
  94. data/lib/couchbase/management/user_manager.rb +1 -1
  95. data/lib/couchbase/management/view_index_manager.rb +11 -5
  96. data/lib/couchbase/mutation_state.rb +12 -0
  97. data/lib/couchbase/query_options.rb +23 -9
  98. data/lib/couchbase/scope.rb +61 -1
  99. data/lib/couchbase/search_options.rb +40 -27
  100. data/lib/couchbase/subdoc.rb +31 -28
  101. data/lib/couchbase/version.rb +2 -2
  102. data/lib/couchbase/view_options.rb +0 -1
  103. metadata +22 -9
@@ -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 };