couchbase 4.2.6-dev.1 → 4.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. package/CONTRIBUTING.md +97 -0
  2. package/deps/couchbase-cxx-client/.github/workflows/windows.yml +0 -3
  3. package/deps/couchbase-cxx-client/CMakeLists.txt +4 -0
  4. package/deps/couchbase-cxx-client/bin/build-tests.rb +1 -1
  5. package/deps/couchbase-cxx-client/core/impl/lookup_in.cxx +1 -0
  6. package/deps/couchbase-cxx-client/core/impl/lookup_in_all_replicas.cxx +176 -0
  7. package/deps/couchbase-cxx-client/core/impl/lookup_in_all_replicas.hxx +80 -0
  8. package/deps/couchbase-cxx-client/core/impl/lookup_in_any_replica.cxx +167 -0
  9. package/deps/couchbase-cxx-client/core/impl/lookup_in_any_replica.hxx +75 -0
  10. package/deps/couchbase-cxx-client/core/impl/lookup_in_replica.cxx +97 -0
  11. package/deps/couchbase-cxx-client/core/impl/lookup_in_replica.hxx +67 -0
  12. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +48 -10
  13. package/deps/couchbase-cxx-client/core/io/http_session.hxx +24 -1
  14. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +22 -1
  15. package/deps/couchbase-cxx-client/core/logger/custom_rotating_file_sink.cxx +1 -1
  16. package/deps/couchbase-cxx-client/core/logger/logger.cxx +80 -20
  17. package/deps/couchbase-cxx-client/core/logger/logger.hxx +31 -0
  18. package/deps/couchbase-cxx-client/core/meta/features.hxx +19 -0
  19. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_all_replicas.hxx +192 -0
  20. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_any_replica.hxx +188 -0
  21. package/deps/couchbase-cxx-client/core/operations.hxx +2 -0
  22. package/deps/couchbase-cxx-client/core/protocol/cmd_hello.hxx +1 -0
  23. package/deps/couchbase-cxx-client/core/protocol/cmd_lookup_in_replica.cxx +107 -0
  24. package/deps/couchbase-cxx-client/core/protocol/cmd_lookup_in_replica.hxx +137 -0
  25. package/deps/couchbase-cxx-client/core/protocol/hello_feature.hxx +6 -0
  26. package/deps/couchbase-cxx-client/core/protocol/hello_feature_fmt.hxx +3 -0
  27. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +22 -1
  28. package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +2 -0
  29. package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +6 -0
  30. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +10 -0
  31. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +4 -1
  32. package/deps/couchbase-cxx-client/couchbase/collection.hxx +111 -0
  33. package/deps/couchbase-cxx-client/couchbase/get_and_lock_options.hxx +2 -2
  34. package/deps/couchbase-cxx-client/couchbase/get_and_touch_options.hxx +2 -2
  35. package/deps/couchbase-cxx-client/couchbase/get_options.hxx +2 -2
  36. package/deps/couchbase-cxx-client/couchbase/insert_options.hxx +3 -3
  37. package/deps/couchbase-cxx-client/couchbase/lookup_in_all_replicas_options.hxx +109 -0
  38. package/deps/couchbase-cxx-client/couchbase/lookup_in_any_replica_options.hxx +101 -0
  39. package/deps/couchbase-cxx-client/couchbase/lookup_in_options.hxx +2 -2
  40. package/deps/couchbase-cxx-client/couchbase/lookup_in_replica_result.hxx +74 -0
  41. package/deps/couchbase-cxx-client/couchbase/lookup_in_result.hxx +26 -0
  42. package/deps/couchbase-cxx-client/couchbase/mutate_in_options.hxx +2 -2
  43. package/deps/couchbase-cxx-client/couchbase/remove_options.hxx +2 -2
  44. package/deps/couchbase-cxx-client/couchbase/replace_options.hxx +3 -3
  45. package/deps/couchbase-cxx-client/couchbase/touch_options.hxx +2 -2
  46. package/deps/couchbase-cxx-client/couchbase/unlock_options.hxx +2 -2
  47. package/deps/couchbase-cxx-client/couchbase/upsert_options.hxx +3 -3
  48. package/deps/couchbase-cxx-client/docs/cbc-analytics.md +3 -2
  49. package/deps/couchbase-cxx-client/docs/cbc-get.md +3 -2
  50. package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +3 -2
  51. package/deps/couchbase-cxx-client/docs/cbc-query.md +3 -2
  52. package/deps/couchbase-cxx-client/test/test_integration_subdoc.cxx +655 -0
  53. package/deps/couchbase-cxx-client/test/utils/logger.cxx +7 -0
  54. package/deps/couchbase-cxx-client/tools/utils.cxx +9 -2
  55. package/dist/binding.d.ts +47 -0
  56. package/dist/collection.d.ts +53 -1
  57. package/dist/collection.js +139 -1
  58. package/dist/couchbase.d.ts +15 -0
  59. package/dist/couchbase.js +22 -1
  60. package/dist/crudoptypes.d.ts +24 -0
  61. package/dist/crudoptypes.js +14 -1
  62. package/package.json +13 -13
  63. package/src/binding.cpp +28 -0
  64. package/src/connection.cpp +4 -0
  65. package/src/connection.hpp +2 -0
  66. package/src/connection_autogen.cpp +28 -0
  67. package/src/jstocbpp_autogen.hpp +262 -0
@@ -412,13 +412,33 @@ class range_scan_orchestrator_impl
412
412
  return tl::unexpected(errc::common::invalid_argument);
413
413
  }
414
414
 
415
+ // Get the collection ID before starting any of the streams
416
+ {
417
+ auto barrier = std::make_shared<std::promise<tl::expected<get_collection_id_result, std::error_code>>>();
418
+ auto f = barrier->get_future();
419
+ get_collection_id_options const get_cid_options{ options_.retry_strategy, options_.timeout, options_.parent_span };
420
+ agent_.get_collection_id(scope_name_, collection_name_, get_cid_options, [barrier](auto result, auto ec) {
421
+ if (ec) {
422
+ return barrier->set_value(tl::unexpected(ec));
423
+ }
424
+ barrier->set_value(result);
425
+ });
426
+ auto get_cid_res = f.get();
427
+ if (!get_cid_res.has_value()) {
428
+ return tl::unexpected(get_cid_res.error());
429
+ }
430
+ collection_id_ = get_cid_res->collection_id;
431
+ }
432
+
415
433
  auto batch_time_limit = std::chrono::duration_cast<std::chrono::milliseconds>(0.9 * options_.timeout);
416
434
  range_scan_continue_options const continue_options{
417
435
  options_.batch_item_limit, options_.batch_byte_limit, batch_time_limit, options_.timeout, options_.retry_strategy,
418
436
  };
419
437
  for (std::uint16_t vbucket = 0; vbucket < gsl::narrow_cast<std::uint16_t>(vbucket_map_.size()); ++vbucket) {
420
438
  const range_scan_create_options create_options{
421
- scope_name_, collection_name_, scan_type_, options_.timeout, {}, vbucket_to_snapshot_requirements_[vbucket],
439
+ scope_name_, {},
440
+ scan_type_, options_.timeout,
441
+ collection_id_, vbucket_to_snapshot_requirements_[vbucket],
422
442
  options_.ids_only, options_.retry_strategy,
423
443
  };
424
444
 
@@ -653,6 +673,7 @@ class range_scan_orchestrator_impl
653
673
  topology::configuration::vbucket_map vbucket_map_;
654
674
  std::string scope_name_;
655
675
  std::string collection_name_;
676
+ std::uint32_t collection_id_;
656
677
  std::variant<std::monostate, range_scan, prefix_scan, sampling_scan> scan_type_;
657
678
  range_scan_orchestrator_options options_;
658
679
  std::map<std::size_t, std::optional<range_snapshot_requirements>> vbucket_to_snapshot_requirements_;
@@ -31,6 +31,8 @@ enum class bucket_capability {
31
31
  collections,
32
32
  durable_write,
33
33
  tombstoned_user_xattrs,
34
+ range_scan,
35
+ replica_read,
34
36
  };
35
37
 
36
38
  enum class cluster_capability {
@@ -67,6 +67,12 @@ struct fmt::formatter<couchbase::core::bucket_capability> {
67
67
  case couchbase::core::bucket_capability::tombstoned_user_xattrs:
68
68
  name = "tombstoned_user_xattrs";
69
69
  break;
70
+ case couchbase::core::bucket_capability::range_scan:
71
+ name = "range_scan";
72
+ break;
73
+ case couchbase::core::bucket_capability::replica_read:
74
+ name = "replica_read";
75
+ break;
70
76
  }
71
77
  return format_to(ctx.out(), "{}", name);
72
78
  }
@@ -117,6 +117,11 @@ struct configuration {
117
117
  return cluster_capabilities.find(cluster_capability::n1ql_read_from_replica) != cluster_capabilities.end();
118
118
  }
119
119
 
120
+ [[nodiscard]] bool supports_range_scan() const
121
+ {
122
+ return bucket_capabilities.find(bucket_capability::range_scan) != bucket_capabilities.end();
123
+ }
124
+
120
125
  [[nodiscard]] bool ephemeral() const
121
126
  {
122
127
  // Use bucket capabilities to identify if couchapi is missing (then its ephemeral). If its null then
@@ -124,6 +129,11 @@ struct configuration {
124
129
  return bucket_capabilities.count(couchbase::core::bucket_capability::couchapi) == 0;
125
130
  }
126
131
 
132
+ [[nodiscard]] bool supports_subdoc_read_replica() const
133
+ {
134
+ return bucket_capabilities.find(bucket_capability::replica_read) != bucket_capabilities.end();
135
+ }
136
+
127
137
  [[nodiscard]] std::size_t index_for_this_node() const;
128
138
  [[nodiscard]] bool has_node(const std::string& network,
129
139
  service_type type,
@@ -52,7 +52,6 @@ struct traits<couchbase::core::topology::configuration> {
52
52
  }
53
53
  if (const auto& hostname = o.find("hostname"); hostname != o.end()) {
54
54
  n.hostname = hostname->second.get_string();
55
- n.hostname = n.hostname.substr(0, n.hostname.rfind(':'));
56
55
  }
57
56
  const auto& s = o.at("services");
58
57
  n.services_plain.key_value = s.template optional<std::uint16_t>("kv");
@@ -233,6 +232,10 @@ struct traits<couchbase::core::topology::configuration> {
233
232
  result.bucket_capabilities.insert(couchbase::core::bucket_capability::nodes_ext);
234
233
  } else if (name == "xattr") {
235
234
  result.bucket_capabilities.insert(couchbase::core::bucket_capability::xattr);
235
+ } else if (name == "rangeScan") {
236
+ result.bucket_capabilities.insert(couchbase::core::bucket_capability::range_scan);
237
+ } else if (name == "subdoc.ReplicaRead") {
238
+ result.bucket_capabilities.insert(couchbase::core::bucket_capability::replica_read);
236
239
  }
237
240
  }
238
241
  }
@@ -28,6 +28,8 @@
28
28
  #include <couchbase/get_any_replica_options.hxx>
29
29
  #include <couchbase/get_options.hxx>
30
30
  #include <couchbase/insert_options.hxx>
31
+ #include <couchbase/lookup_in_all_replicas_options.hxx>
32
+ #include <couchbase/lookup_in_any_replica_options.hxx>
31
33
  #include <couchbase/lookup_in_options.hxx>
32
34
  #include <couchbase/lookup_in_specs.hxx>
33
35
  #include <couchbase/mutate_in_options.hxx>
@@ -856,6 +858,115 @@ class collection
856
858
  return future;
857
859
  }
858
860
 
861
+ /**
862
+ * Performs lookups to document fragments with default options from all replicas and the active node and returns the result as a vector.
863
+ *
864
+ * @tparam Handler type of the handler that implements @ref lookup_in_all_replicas_handler
865
+ *
866
+ * @param document_id the outer document ID
867
+ * @param specs an object that specifies the types of lookups to perform
868
+ * @param options custom options to modify the lookup options
869
+ * @param handler callable that implements @ref lookup_in_all_replicas_handler
870
+ *
871
+ * @exception errc::key_value::document_not_found the given document id is not found in the collection.
872
+ * @exception errc::common::ambiguous_timeout
873
+ * @exception errc::common::unambiguous_timeout
874
+ *
875
+ * @since 1.0.0
876
+ * @committed
877
+ */
878
+ template<typename Handler>
879
+ void lookup_in_all_replicas(std::string document_id,
880
+ lookup_in_specs specs,
881
+ const lookup_in_all_replicas_options& options,
882
+ Handler&& handler) const
883
+ {
884
+ return core::impl::initiate_lookup_in_all_replicas_operation(
885
+ core_, bucket_name_, scope_name_, name_, std::move(document_id), specs.specs(), options.build(), std::forward<Handler>(handler));
886
+ }
887
+
888
+ /**
889
+ * Performs lookups to document fragments with default options from all replicas and the active node and returns the result as a vector.
890
+ *
891
+ * @param document_id the outer document ID
892
+ * @param specs an object that specifies the types of lookups to perform
893
+ * @param options custom options to modify the lookup options
894
+ * @return future object that carries result of the operation
895
+ *
896
+ * @exception errc::key_value::document_not_found the given document id is not found in the collection.
897
+ * @exception errc::common::ambiguous_timeout
898
+ * @exception errc::common::unambiguous_timeout
899
+ *
900
+ * @since 1.0.0
901
+ * @committed
902
+ */
903
+ [[nodiscard]] auto lookup_in_all_replicas(std::string document_id,
904
+ lookup_in_specs specs,
905
+ const lookup_in_all_replicas_options& options = {}) const
906
+ -> std::future<std::pair<subdocument_error_context, lookup_in_all_replicas_result>>
907
+ {
908
+ auto barrier = std::make_shared<std::promise<std::pair<subdocument_error_context, lookup_in_all_replicas_result>>>();
909
+ auto future = barrier->get_future();
910
+ lookup_in_all_replicas(std::move(document_id), std::move(specs), options, [barrier](auto ctx, auto result) {
911
+ barrier->set_value({ std::move(ctx), std::move(result) });
912
+ });
913
+ return future;
914
+ }
915
+
916
+ /**
917
+ * Performs lookups to document fragments with default options from all replicas and returns the first found.
918
+ *
919
+ * @tparam Handler type of the handler that implements @ref lookup_in_any_replica_handler
920
+ *
921
+ * @param document_id the outer document ID
922
+ * @param specs an object that specifies the types of lookups to perform
923
+ * @param options custom options to modify the lookup options
924
+ *
925
+ * @exception errc::key_value::document_not_found the given document id is not found in the collection.
926
+ * @exception errc::common::ambiguous_timeout
927
+ * @exception errc::common::unambiguous_timeout
928
+ *
929
+ * @since 1.0.0
930
+ * @committed
931
+ */
932
+ template<typename Handler>
933
+ void lookup_in_any_replica(std::string document_id,
934
+ lookup_in_specs specs,
935
+ const lookup_in_any_replica_options& options,
936
+ Handler&& handler) const
937
+ {
938
+ return core::impl::initiate_lookup_in_any_replica_operation(
939
+ core_, bucket_name_, scope_name_, name_, std::move(document_id), specs.specs(), options.build(), std::forward<Handler>(handler));
940
+ }
941
+
942
+ /**
943
+ * Performs lookups to document fragments with default options from all replicas and returns the first found.
944
+ *
945
+ * @param document_id the outer document ID
946
+ * @param specs an object that specifies the types of lookups to perform
947
+ * @param options custom options to modify the lookup options
948
+ * @return future object that carries result of the operation
949
+ *
950
+ * @exception errc::key_value::document_not_found the given document id is not found in the collection.
951
+ * @exception errc::common::ambiguous_timeout
952
+ * @exception errc::common::unambiguous_timeout
953
+ *
954
+ * @since 1.0.0
955
+ * @committed
956
+ */
957
+ [[nodiscard]] auto lookup_in_any_replica(std::string document_id,
958
+ lookup_in_specs specs,
959
+ const lookup_in_any_replica_options& options = {}) const
960
+ -> std::future<std::pair<subdocument_error_context, lookup_in_replica_result>>
961
+ {
962
+ auto barrier = std::make_shared<std::promise<std::pair<subdocument_error_context, lookup_in_replica_result>>>();
963
+ auto future = barrier->get_future();
964
+ lookup_in_any_replica(std::move(document_id), std::move(specs), options, [barrier](auto ctx, auto result) {
965
+ barrier->set_value({ std::move(ctx), std::move(result) });
966
+ });
967
+ return future;
968
+ }
969
+
859
970
  /**
860
971
  * Gets a document for a given id and places a pessimistic lock on it for mutations
861
972
  *
@@ -86,8 +86,8 @@ initiate_get_and_lock_operation(std::shared_ptr<couchbase::core::cluster> core,
86
86
  std::string collection_name,
87
87
  std::string document_key,
88
88
  std::chrono::seconds lock_duration,
89
- get_and_lock_options::built options,
90
- get_and_lock_handler&& handler);
89
+ couchbase::get_and_lock_options::built options,
90
+ couchbase::get_and_lock_handler&& handler);
91
91
  #endif
92
92
  } // namespace impl
93
93
  } // namespace core
@@ -86,8 +86,8 @@ initiate_get_and_touch_operation(std::shared_ptr<couchbase::core::cluster> core,
86
86
  std::string collection_name,
87
87
  std::string document_key,
88
88
  std::uint32_t expiry,
89
- get_and_touch_options::built options,
90
- get_and_touch_handler&& handler);
89
+ couchbase::get_and_touch_options::built options,
90
+ couchbase::get_and_touch_handler&& handler);
91
91
  #endif
92
92
  } // namespace impl
93
93
  } // namespace core
@@ -129,8 +129,8 @@ initiate_get_operation(std::shared_ptr<couchbase::core::cluster> core,
129
129
  std::string scope_name,
130
130
  std::string collection_name,
131
131
  std::string document_key,
132
- get_options::built options,
133
- get_handler&& handler);
132
+ couchbase::get_options::built options,
133
+ couchbase::get_handler&& handler);
134
134
  #endif
135
135
  } // namespace impl
136
136
  } // namespace core
@@ -127,9 +127,9 @@ initiate_insert_operation(std::shared_ptr<couchbase::core::cluster> core,
127
127
  std::string scope_name,
128
128
  std::string collection_name,
129
129
  std::string document_key,
130
- codec::encoded_value encoded,
131
- insert_options::built options,
132
- insert_handler&& handler);
130
+ couchbase::codec::encoded_value encoded,
131
+ couchbase::insert_options::built options,
132
+ couchbase::insert_handler&& handler);
133
133
  #endif
134
134
  } // namespace impl
135
135
  } // namespace core
@@ -0,0 +1,109 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-Present 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
+
18
+ #pragma once
19
+
20
+ #include <couchbase/subdoc/fwd/command_bundle.hxx>
21
+
22
+ #include <core/impl/subdoc/command.hxx>
23
+ #include <couchbase/codec/encoded_value.hxx>
24
+ #include <couchbase/common_options.hxx>
25
+ #include <couchbase/expiry.hxx>
26
+ #include <couchbase/lookup_in_replica_result.hxx>
27
+ #include <couchbase/store_semantics.hxx>
28
+ #include <couchbase/subdocument_error_context.hxx>
29
+
30
+ #include <chrono>
31
+ #include <functional>
32
+ #include <memory>
33
+ #include <optional>
34
+ #include <vector>
35
+
36
+ namespace couchbase
37
+ {
38
+ /**
39
+ * Options for @ref collection#lookup_in_all_replicas().
40
+ *
41
+ * @since 1.0.0
42
+ * @committed
43
+ */
44
+ struct lookup_in_all_replicas_options : common_options<lookup_in_all_replicas_options> {
45
+ /**
46
+ * Immutable value object representing consistent options.
47
+ *
48
+ * @since 1.0.0
49
+ * @internal
50
+ */
51
+ struct built : public common_options<lookup_in_all_replicas_options>::built {
52
+ };
53
+
54
+ /**
55
+ * Validates options and returns them as an immutable value.
56
+ *
57
+ * @return consistent options as an immutable value
58
+ *
59
+ * @exception std::system_error with code errc::common::invalid_argument if the options are not valid
60
+ *
61
+ * @since 1.0.0
62
+ * @internal
63
+ */
64
+ [[nodiscard]] auto build() const -> built
65
+ {
66
+ return { build_common_options() };
67
+ }
68
+ };
69
+
70
+ /**
71
+ * The result for the @ref collection#lookup_in_all_replicas() operation
72
+ *
73
+ * @since 1.0.0
74
+ * @uncommitted
75
+ */
76
+ using lookup_in_all_replicas_result = std::vector<lookup_in_replica_result>;
77
+
78
+ /**
79
+ * The signature for the handler of the @ref collection#lookup_in_all_replicas() operation
80
+ *
81
+ * @since 1.0.0
82
+ * @uncommitted
83
+ */
84
+ using lookup_in_all_replicas_handler = std::function<void(couchbase::subdocument_error_context, lookup_in_all_replicas_result)>;
85
+
86
+ #ifndef COUCHBASE_CXX_CLIENT_DOXYGEN
87
+ namespace core
88
+ {
89
+ class cluster;
90
+ namespace impl
91
+ {
92
+
93
+ /**
94
+ * @since 1.0.0
95
+ * @internal
96
+ */
97
+ void
98
+ initiate_lookup_in_all_replicas_operation(std::shared_ptr<couchbase::core::cluster> core,
99
+ const std::string& bucket_name,
100
+ const std::string& scope_name,
101
+ const std::string& collection_name,
102
+ std::string document_key,
103
+ const std::vector<couchbase::core::impl::subdoc::command>& specs,
104
+ lookup_in_all_replicas_options::built options,
105
+ lookup_in_all_replicas_handler&& handler);
106
+ #endif
107
+ } // namespace impl
108
+ } // namespace core
109
+ } // namespace couchbase
@@ -0,0 +1,101 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-Present 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
+
18
+ #pragma once
19
+
20
+ #include <couchbase/subdoc/fwd/command_bundle.hxx>
21
+
22
+ #include <core/impl/subdoc/command.hxx>
23
+ #include <couchbase/codec/encoded_value.hxx>
24
+ #include <couchbase/common_options.hxx>
25
+ #include <couchbase/expiry.hxx>
26
+ #include <couchbase/lookup_in_replica_result.hxx>
27
+ #include <couchbase/store_semantics.hxx>
28
+ #include <couchbase/subdocument_error_context.hxx>
29
+
30
+ #include <chrono>
31
+ #include <functional>
32
+ #include <memory>
33
+ #include <optional>
34
+ #include <vector>
35
+
36
+ namespace couchbase
37
+ {
38
+ /**
39
+ * Options for @ref collection#lookup_in_any_replica().
40
+ *
41
+ * @since 1.0.0
42
+ * @committed
43
+ */
44
+ struct lookup_in_any_replica_options : common_options<lookup_in_any_replica_options> {
45
+ /**
46
+ * Immutable value object representing consistent options.
47
+ *
48
+ * @since 1.0.0
49
+ * @internal
50
+ */
51
+ struct built : public common_options<lookup_in_any_replica_options>::built {
52
+ };
53
+
54
+ /**
55
+ * Validates options and returns them as an immutable value.
56
+ *
57
+ * @return consistent options as an immutable value
58
+ *
59
+ * @exception std::system_error with code errc::common::invalid_argument if the options are not valid
60
+ *
61
+ * @since 1.0.0
62
+ * @internal
63
+ */
64
+ [[nodiscard]] auto build() const -> built
65
+ {
66
+ return { build_common_options() };
67
+ }
68
+ };
69
+
70
+ /**
71
+ * The signature for the handler of the @ref collection#lookup_in_any_replica() operation
72
+ *
73
+ * @since 1.0.0
74
+ * @uncommitted
75
+ */
76
+ using lookup_in_any_replica_handler = std::function<void(couchbase::subdocument_error_context, lookup_in_replica_result)>;
77
+
78
+ #ifndef COUCHBASE_CXX_CLIENT_DOXYGEN
79
+ namespace core
80
+ {
81
+ class cluster;
82
+ namespace impl
83
+ {
84
+
85
+ /**
86
+ * @since 1.0.0
87
+ * @internal
88
+ */
89
+ void
90
+ initiate_lookup_in_any_replica_operation(std::shared_ptr<couchbase::core::cluster> core,
91
+ const std::string& bucket_name,
92
+ const std::string& scope_name,
93
+ const std::string& collection_name,
94
+ std::string document_key,
95
+ const std::vector<couchbase::core::impl::subdoc::command>& specs,
96
+ lookup_in_any_replica_options::built options,
97
+ lookup_in_any_replica_handler&& handler);
98
+ #endif
99
+ } // namespace impl
100
+ } // namespace core
101
+ } // namespace couchbase
@@ -111,8 +111,8 @@ initiate_lookup_in_operation(std::shared_ptr<couchbase::core::cluster> core,
111
111
  std::string collection_name,
112
112
  std::string document_key,
113
113
  const std::vector<couchbase::core::impl::subdoc::command>& specs,
114
- lookup_in_options::built options,
115
- lookup_in_handler&& handler);
114
+ couchbase::lookup_in_options::built options,
115
+ couchbase::lookup_in_handler&& handler);
116
116
  #endif
117
117
  } // namespace impl
118
118
  } // namespace core
@@ -0,0 +1,74 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-Present 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
+
18
+ #pragma once
19
+
20
+ #include <couchbase/lookup_in_result.hxx>
21
+
22
+ #include <vector>
23
+
24
+ namespace couchbase
25
+ {
26
+
27
+ /**
28
+ * Represents result of lookup_in_replica operations.
29
+ *
30
+ * @since 1.0.0
31
+ * @committed
32
+ */
33
+ class lookup_in_replica_result : public lookup_in_result
34
+ {
35
+ public:
36
+ /**
37
+ * @since 1.0.0
38
+ * @internal
39
+ */
40
+ lookup_in_replica_result() = default;
41
+
42
+ /**
43
+ * Constructs result for lookup_in_replica operation
44
+ *
45
+ * @param cas
46
+ * @param entries list of the fields returned by the server
47
+ * @param is_deleted
48
+ * @param is_replica true if document originates from replica node
49
+ *
50
+ * @since 1.0.0
51
+ * @committed
52
+ */
53
+ lookup_in_replica_result(couchbase::cas cas, std::vector<entry> entries, bool is_deleted, bool is_replica)
54
+ : lookup_in_result{ cas, std::move(entries), is_deleted }
55
+ , is_replica_{ is_replica }
56
+ {
57
+ }
58
+
59
+ /**
60
+ * Returns whether this document originates from a replica node
61
+ *
62
+ * @return whether document originates from a replica node
63
+ *
64
+ * @since 1.0.0
65
+ */
66
+ [[nodiscard]] auto is_replica() const -> bool
67
+ {
68
+ return is_replica_;
69
+ }
70
+
71
+ private:
72
+ bool is_replica_{ false };
73
+ };
74
+ } // namespace couchbase
@@ -44,6 +44,7 @@ class lookup_in_result : public result
44
44
  codec::binary value;
45
45
  std::size_t original_index;
46
46
  bool exists;
47
+ std::error_code ec;
47
48
  };
48
49
 
49
50
  /**
@@ -84,6 +85,11 @@ class lookup_in_result : public result
84
85
  {
85
86
  for (const entry& e : entries_) {
86
87
  if (e.original_index == index) {
88
+ if (e.ec) {
89
+ throw std::system_error(
90
+ e.ec, "error getting result for spec at index " + std::to_string(index) + ", path \"" + e.path + "\"");
91
+ }
92
+
87
93
  return codec::tao_json_serializer::deserialize<Document>(e.value);
88
94
  }
89
95
  }
@@ -105,6 +111,10 @@ class lookup_in_result : public result
105
111
  {
106
112
  for (const entry& e : entries_) {
107
113
  if (e.path == path) {
114
+ if (e.ec) {
115
+ throw std::system_error(e.ec, "error getting result for path \"" + e.path + "\"");
116
+ }
117
+
108
118
  return codec::tao_json_serializer::deserialize<Document>(e.value);
109
119
  }
110
120
  }
@@ -127,6 +137,10 @@ class lookup_in_result : public result
127
137
  const auto& macro_string = subdoc::to_string(macro);
128
138
  for (const entry& e : entries_) {
129
139
  if (e.path == macro_string) {
140
+ if (e.ec) {
141
+ throw std::system_error(e.ec, "error getting result for macro \"" + macro_string + "\"");
142
+ }
143
+
130
144
  return codec::tao_json_serializer::deserialize<Document>(e.value);
131
145
  }
132
146
  }
@@ -147,6 +161,10 @@ class lookup_in_result : public result
147
161
  {
148
162
  for (const entry& e : entries_) {
149
163
  if (e.original_index == index) {
164
+ if (e.ec && e.ec != couchbase::errc::key_value::path_not_found) {
165
+ throw std::system_error(e.ec, "error getting result for path \"" + e.path + "\"");
166
+ }
167
+
150
168
  return e.exists;
151
169
  }
152
170
  }
@@ -167,6 +185,10 @@ class lookup_in_result : public result
167
185
  const auto& macro_string = subdoc::to_string(macro);
168
186
  for (const entry& e : entries_) {
169
187
  if (e.path == macro_string) {
188
+ if (e.ec && e.ec != couchbase::errc::key_value::path_not_found) {
189
+ throw std::system_error(e.ec, "error getting result for macro \"" + macro_string + "\"");
190
+ }
191
+
170
192
  return e.exists;
171
193
  }
172
194
  }
@@ -186,6 +208,10 @@ class lookup_in_result : public result
186
208
  {
187
209
  for (const entry& e : entries_) {
188
210
  if (e.path == path) {
211
+ if (e.ec && e.ec != couchbase::errc::key_value::path_not_found) {
212
+ throw std::system_error(e.ec, "error getting result for path \"" + e.path + "\"");
213
+ }
214
+
189
215
  return e.exists;
190
216
  }
191
217
  }
@@ -225,8 +225,8 @@ initiate_mutate_in_operation(std::shared_ptr<couchbase::core::cluster> core,
225
225
  std::string collection_name,
226
226
  std::string document_key,
227
227
  const std::vector<couchbase::core::impl::subdoc::command>& specs,
228
- mutate_in_options::built options,
229
- mutate_in_handler&& handler);
228
+ couchbase::mutate_in_options::built options,
229
+ couchbase::mutate_in_handler&& handler);
230
230
  #endif
231
231
  } // namespace impl
232
232
  } // namespace core