couchbase 3.8.0 → 3.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/cache/extconf_include.rb +4 -4
- data/ext/cache/mozilla-ca-bundle.crt +96 -675
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +3 -1
- data/ext/couchbase/core/error_context/base_error_context.hxx +32 -0
- data/ext/couchbase/core/error_context/key_value.cxx +1 -0
- data/ext/couchbase/core/error_context/key_value.hxx +23 -0
- data/ext/couchbase/core/error_context/key_value_error_context.hxx +35 -0
- data/ext/couchbase/core/error_context/subdocument_error_context.hxx +41 -0
- data/ext/couchbase/core/impl/binary_collection.cxx +123 -88
- data/ext/couchbase/core/impl/collection.cxx +416 -189
- data/ext/couchbase/core/impl/error.cxx +29 -4
- data/ext/couchbase/core/impl/invoke_with_node_id.hxx +44 -0
- data/ext/couchbase/core/impl/node_id.cxx +110 -0
- data/ext/couchbase/core/impl/node_id.hxx +40 -0
- data/ext/couchbase/core/impl/public_cluster.cxx +118 -5
- data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +67 -0
- data/ext/couchbase/core/io/http_session_manager.hxx +97 -57
- data/ext/couchbase/core/io/mcbp_session.cxx +7 -16
- data/ext/couchbase/core/io/streams.cxx +143 -12
- data/ext/couchbase/core/io/streams.hxx +6 -0
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +14 -4
- data/ext/couchbase/core/operations/document_get_projected.cxx +3 -4
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +4 -0
- data/ext/couchbase/core/operations/document_query.cxx +12 -12
- data/ext/couchbase/core/operations/management/bucket_create.cxx +37 -38
- data/ext/couchbase/core/operations/management/bucket_update.cxx +26 -28
- data/ext/couchbase/core/operations/management/collection_create.cxx +11 -11
- data/ext/couchbase/core/operations/management/collection_drop.cxx +11 -11
- data/ext/couchbase/core/operations/management/collection_update.cxx +11 -11
- data/ext/couchbase/core/operations/management/error_utils.cxx +9 -6
- data/ext/couchbase/core/operations/management/query_index_create.cxx +5 -4
- data/ext/couchbase/core/operations/management/query_index_drop.cxx +7 -6
- data/ext/couchbase/core/operations/management/scope_create.cxx +12 -13
- data/ext/couchbase/core/operations/management/scope_drop.cxx +8 -9
- data/ext/couchbase/core/topology/configuration.cxx +21 -0
- data/ext/couchbase/core/topology/configuration.hxx +28 -0
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +254 -178
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +5 -1
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +42 -7
- data/ext/couchbase/core/transactions/waitable_op_list.hxx +13 -2
- data/ext/couchbase/core/utils/contains_string.cxx +61 -0
- data/ext/couchbase/core/utils/contains_string.hxx +26 -0
- data/ext/couchbase/couchbase/cluster.hxx +33 -0
- data/ext/couchbase/couchbase/collection.hxx +73 -0
- data/ext/couchbase/couchbase/error.hxx +16 -0
- data/ext/couchbase/couchbase/node_id.hxx +123 -0
- data/ext/couchbase/couchbase/node_id_for_options.hxx +61 -0
- data/ext/couchbase/couchbase/node_ids_options.hxx +62 -0
- data/ext/couchbase/couchbase/result.hxx +42 -0
- data/ext/rcb_crud.cxx +2 -0
- data/ext/rcb_logger.cxx +15 -17
- data/lib/couchbase/cluster.rb +16 -14
- data/lib/couchbase/datastructures/couchbase_list.rb +1 -0
- data/lib/couchbase/datastructures/couchbase_map.rb +1 -0
- data/lib/couchbase/datastructures/couchbase_queue.rb +1 -0
- data/lib/couchbase/datastructures/couchbase_set.rb +1 -0
- data/lib/couchbase/errors.rb +1 -1
- data/lib/couchbase/json_transcoder.rb +1 -1
- data/lib/couchbase/options.rb +9 -4
- data/lib/couchbase/protostellar/client.rb +0 -2
- data/lib/couchbase/protostellar/cluster.rb +4 -0
- data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_pb.rb +54 -0
- data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_services_pb.rb +51 -0
- data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_pb.rb +5 -24
- data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_services_pb.rb +16 -0
- data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_pb.rb +5 -24
- data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_services_pb.rb +16 -0
- data/lib/couchbase/protostellar/generated/admin/query/v1/query_pb.rb +5 -24
- data/lib/couchbase/protostellar/generated/admin/query/v1/query_services_pb.rb +18 -0
- data/lib/couchbase/protostellar/generated/admin/search/v1/search_pb.rb +2 -23
- data/lib/couchbase/protostellar/generated/admin/search/v1/search_services_pb.rb +23 -0
- data/lib/couchbase/protostellar/generated/analytics/v1/analytics_pb.rb +4 -25
- data/lib/couchbase/protostellar/generated/analytics/v1/analytics_services_pb.rb +10 -0
- data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_pb.rb +6 -25
- data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_services_pb.rb +18 -0
- data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_pb.rb +46 -0
- data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_services_pb.rb +56 -0
- data/lib/couchbase/protostellar/generated/kv/v1/kv_pb.rb +3 -26
- data/lib/couchbase/protostellar/generated/kv/v1/kv_services_pb.rb +47 -0
- data/lib/couchbase/protostellar/generated/query/v1/query_pb.rb +4 -26
- data/lib/couchbase/protostellar/generated/query/v1/query_services_pb.rb +10 -0
- data/lib/couchbase/protostellar/generated/routing/v2/routing_pb.rb +26 -0
- data/lib/couchbase/protostellar/generated/routing/v2/routing_services_pb.rb +43 -0
- data/lib/couchbase/protostellar/generated/search/v1/search_pb.rb +5 -26
- data/lib/couchbase/protostellar/generated/search/v1/search_services_pb.rb +11 -0
- data/lib/couchbase/protostellar/generated/transactions/v1/transactions_pb.rb +2 -23
- data/lib/couchbase/protostellar/generated/transactions/v1/transactions_services_pb.rb +30 -0
- data/lib/couchbase/protostellar/generated/view/v1/view_pb.rb +2 -23
- data/lib/couchbase/protostellar/generated/view/v1/view_services_pb.rb +9 -0
- data/lib/couchbase/protostellar/request_generator/admin/collection.rb +4 -2
- data/lib/couchbase/protostellar/request_generator/admin/query.rb +2 -0
- data/lib/couchbase/protostellar/request_generator/kv.rb +1 -1
- data/lib/couchbase/protostellar/scope.rb +4 -0
- data/lib/couchbase/utils/observability.rb +10 -4
- data/lib/couchbase/version.rb +1 -1
- metadata +20 -7
- data/lib/couchbase/protostellar/generated/routing/v1/routing_pb.rb +0 -52
- data/lib/couchbase/protostellar/generated/routing/v1/routing_services_pb.rb +0 -30
|
@@ -79,6 +79,15 @@ public:
|
|
|
79
79
|
// we have the lock. Block all further ops
|
|
80
80
|
allow_ops_ = false;
|
|
81
81
|
}
|
|
82
|
+
// Peek at whether query mode has already been entered. Briefly acquires mutex_ but, unlike
|
|
83
|
+
// get_mode(), never waits on cv_query_ for the query node to be set, so it returns immediately.
|
|
84
|
+
// Used by defensive invariant checks: a KV mutation must never be staged once query mode is
|
|
85
|
+
// entered.
|
|
86
|
+
auto query_mode_entered() const -> bool
|
|
87
|
+
{
|
|
88
|
+
const std::scoped_lock lock(mutex_);
|
|
89
|
+
return mode_.mode == attempt_mode::modes::QUERY;
|
|
90
|
+
}
|
|
82
91
|
auto get_mode() -> attempt_mode
|
|
83
92
|
{
|
|
84
93
|
std::unique_lock<std::mutex> lock(mutex_);
|
|
@@ -143,8 +152,10 @@ public:
|
|
|
143
152
|
{
|
|
144
153
|
// when begin work errors out, it is fatal, so reset to kv mode here, allowing
|
|
145
154
|
// rollback to function properly.
|
|
146
|
-
std::
|
|
155
|
+
const std::scoped_lock lock(mutex_);
|
|
147
156
|
mode_.mode = attempt_mode::modes::KV;
|
|
157
|
+
// query_node is intentionally left populated: a retry runs with a fresh waitable_op_list, and
|
|
158
|
+
// get_mode()'s wait predicate keys on query_node, so clearing it here would serve no purpose.
|
|
148
159
|
cv_query_.notify_all();
|
|
149
160
|
}
|
|
150
161
|
|
|
@@ -199,6 +210,6 @@ private:
|
|
|
199
210
|
std::condition_variable cv_ops_;
|
|
200
211
|
std::condition_variable cv_query_;
|
|
201
212
|
std::condition_variable cv_in_flight_;
|
|
202
|
-
std::mutex mutex_;
|
|
213
|
+
mutable std::mutex mutex_;
|
|
203
214
|
};
|
|
204
215
|
} // namespace couchbase::core::transactions
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021-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
|
+
#include "contains_string.hxx"
|
|
19
|
+
|
|
20
|
+
namespace couchbase::core::utils
|
|
21
|
+
{
|
|
22
|
+
|
|
23
|
+
namespace
|
|
24
|
+
{
|
|
25
|
+
constexpr auto ascii_lower = [](unsigned char c) -> unsigned char {
|
|
26
|
+
return (c >= 'A' && c <= 'Z') ? static_cast<unsigned char>(c + ('a' - 'A')) : c;
|
|
27
|
+
};
|
|
28
|
+
} // namespace
|
|
29
|
+
|
|
30
|
+
auto
|
|
31
|
+
contains_string(std::string_view input, std::string_view substr, bool ignore_case) -> bool
|
|
32
|
+
{
|
|
33
|
+
if (substr.empty()) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (input.empty() || substr.size() > input.size()) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!ignore_case) {
|
|
42
|
+
return input.find(substr) != std::string_view::npos;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const auto end = input.size() - substr.size() + 1;
|
|
46
|
+
for (std::size_t i = 0; i < end; i++) {
|
|
47
|
+
bool match = true;
|
|
48
|
+
for (std::size_t j = 0; j < substr.size(); j++) {
|
|
49
|
+
if (ascii_lower(static_cast<unsigned char>(input[i + j])) !=
|
|
50
|
+
ascii_lower(static_cast<unsigned char>(substr[j]))) {
|
|
51
|
+
match = false;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (match) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
} // namespace couchbase::core::utils
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2021-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 <string_view>
|
|
21
|
+
|
|
22
|
+
namespace couchbase::core::utils
|
|
23
|
+
{
|
|
24
|
+
auto
|
|
25
|
+
contains_string(std::string_view input, std::string_view substr, bool ignore_case = false) -> bool;
|
|
26
|
+
} // namespace couchbase::core::utils
|
|
@@ -97,6 +97,39 @@ public:
|
|
|
97
97
|
auto operator=(const cluster& other) -> cluster& = default;
|
|
98
98
|
auto operator=(cluster&& other) -> cluster& = default;
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Notify the cluster of a fork-related event, so it can keep its I/O usable
|
|
102
|
+
* across @c fork().
|
|
103
|
+
*
|
|
104
|
+
* Call it three times, in this order: @ref fork_event::prepare in the parent
|
|
105
|
+
* before forking, then @ref fork_event::child in the child and @ref
|
|
106
|
+
* fork_event::parent in the parent.
|
|
107
|
+
*
|
|
108
|
+
* NOTE: @ref fork_event::child reconnects this cluster on a fresh set of
|
|
109
|
+
* sockets, because the inherited ones belong to the parent. Any @ref bucket,
|
|
110
|
+
* @ref scope or @ref collection handle obtained before the fork still refers to
|
|
111
|
+
* the pre-fork connections, so in the child those handles must be re-acquired
|
|
112
|
+
* from the cluster -- using a stale one fails with @ref
|
|
113
|
+
* errc::network::cluster_closed. Handles held in the parent stay valid.
|
|
114
|
+
*
|
|
115
|
+
* This function must not be called while operations are in flight on this
|
|
116
|
+
* cluster from another thread.
|
|
117
|
+
*
|
|
118
|
+
* On platforms without @c fork(), Windows in particular, this function does
|
|
119
|
+
* nothing. It remains callable everywhere so that portable code does not have to
|
|
120
|
+
* guard the calls, but nothing about the cluster changes.
|
|
121
|
+
*
|
|
122
|
+
* @param event the fork-related event that is about to happen, or just happened.
|
|
123
|
+
*
|
|
124
|
+
* @throws std::system_error if the I/O backend cannot be carried across the fork.
|
|
125
|
+
* There is no recovery for this: the cluster's io_context is unusable afterwards
|
|
126
|
+
* and the only thing left to do with the cluster is destroy it. It is reported
|
|
127
|
+
* rather than swallowed because a caller that went on using such a cluster would
|
|
128
|
+
* be operating on a reactor that no longer tracks its sockets.
|
|
129
|
+
*
|
|
130
|
+
* @since 1.0.0
|
|
131
|
+
* @uncommitted
|
|
132
|
+
*/
|
|
100
133
|
void notify_fork(fork_event event);
|
|
101
134
|
|
|
102
135
|
void close(std::function<void()>&& handler);
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
#include <couchbase/lookup_in_specs.hxx>
|
|
36
36
|
#include <couchbase/mutate_in_options.hxx>
|
|
37
37
|
#include <couchbase/mutate_in_specs.hxx>
|
|
38
|
+
#include <couchbase/node_id_for_options.hxx>
|
|
39
|
+
#include <couchbase/node_ids_options.hxx>
|
|
38
40
|
#include <couchbase/query_options.hxx>
|
|
39
41
|
#include <couchbase/remove_options.hxx>
|
|
40
42
|
#include <couchbase/replace_options.hxx>
|
|
@@ -1090,6 +1092,77 @@ public:
|
|
|
1090
1092
|
[[nodiscard]] auto scan(const scan_type& scan_type, const scan_options& options = {}) const
|
|
1091
1093
|
-> std::future<std::pair<error, scan_result>>;
|
|
1092
1094
|
|
|
1095
|
+
/**
|
|
1096
|
+
* Resolves a document key to the identity of the cluster node that currently
|
|
1097
|
+
* owns it, using the client-side vBucket map (no network round-trip).
|
|
1098
|
+
*
|
|
1099
|
+
* @param document_id the document id to resolve
|
|
1100
|
+
* @param options options to customize the request
|
|
1101
|
+
* @param handler the handler that receives the result
|
|
1102
|
+
*
|
|
1103
|
+
* @since 1.3.2
|
|
1104
|
+
* @uncommitted
|
|
1105
|
+
*/
|
|
1106
|
+
void node_id_for(std::string document_id,
|
|
1107
|
+
const node_id_for_options& options,
|
|
1108
|
+
node_id_for_handler&& handler) const;
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Resolves a document key to the identity of the cluster node that currently
|
|
1112
|
+
* owns it, using the client-side vBucket map (no network round-trip).
|
|
1113
|
+
*
|
|
1114
|
+
* @param document_id the document id to resolve
|
|
1115
|
+
* @param options options to customize the request
|
|
1116
|
+
* @return future carrying the error (if any) and node_id
|
|
1117
|
+
*
|
|
1118
|
+
* @since 1.3.2
|
|
1119
|
+
* @uncommitted
|
|
1120
|
+
*/
|
|
1121
|
+
[[nodiscard]] auto node_id_for(std::string document_id,
|
|
1122
|
+
const node_id_for_options& options = {}) const
|
|
1123
|
+
-> std::future<std::pair<error, node_id>>;
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Returns the set of cluster nodes that currently serve key-value
|
|
1127
|
+
* traffic for this collection's bucket, drawn from the client-side
|
|
1128
|
+
* topology snapshot (no network round-trip).
|
|
1129
|
+
*
|
|
1130
|
+
* Each entry corresponds to one cluster node and is the same node_id
|
|
1131
|
+
* the SDK reports on KV results and errors that touched that node, so
|
|
1132
|
+
* the returned set is directly comparable to the keys of any
|
|
1133
|
+
* application-side state that is keyed by node_id (e.g. a per-node
|
|
1134
|
+
* circuit breaker registry). A periodic sweep that diffs the
|
|
1135
|
+
* registry's keys against this set is the canonical way to retire
|
|
1136
|
+
* tracker state for a node that has been removed from the cluster
|
|
1137
|
+
* topology.
|
|
1138
|
+
*
|
|
1139
|
+
* Nodes that do not expose a key-value port for the configured
|
|
1140
|
+
* transport (TLS or plain) are excluded from the returned set, since
|
|
1141
|
+
* they do not serve KV operations and therefore have no meaningful
|
|
1142
|
+
* identity from the SDK's point of view.
|
|
1143
|
+
*
|
|
1144
|
+
* @param options options to customize the request
|
|
1145
|
+
* @param handler the handler that receives the result
|
|
1146
|
+
*
|
|
1147
|
+
* @since 1.3.2
|
|
1148
|
+
* @uncommitted
|
|
1149
|
+
*/
|
|
1150
|
+
void node_ids(const node_ids_options& options, node_ids_handler&& handler) const;
|
|
1151
|
+
|
|
1152
|
+
/**
|
|
1153
|
+
* Returns the set of cluster nodes that currently serve key-value
|
|
1154
|
+
* traffic for this collection's bucket, drawn from the client-side
|
|
1155
|
+
* topology snapshot (no network round-trip).
|
|
1156
|
+
*
|
|
1157
|
+
* @param options options to customize the request
|
|
1158
|
+
* @return future carrying the error (if any) and the set of node_ids
|
|
1159
|
+
*
|
|
1160
|
+
* @since 1.3.2
|
|
1161
|
+
* @uncommitted
|
|
1162
|
+
*/
|
|
1163
|
+
[[nodiscard]] auto node_ids(const node_ids_options& options = {}) const
|
|
1164
|
+
-> std::future<std::pair<error, std::vector<node_id>>>;
|
|
1165
|
+
|
|
1093
1166
|
[[nodiscard]] auto query_indexes() const -> collection_query_index_manager;
|
|
1094
1167
|
|
|
1095
1168
|
private:
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
#pragma once
|
|
19
19
|
|
|
20
20
|
#include <couchbase/error_context.hxx>
|
|
21
|
+
#include <couchbase/node_id.hxx>
|
|
21
22
|
|
|
22
23
|
#include <memory>
|
|
23
24
|
#include <optional>
|
|
@@ -32,12 +33,26 @@ public:
|
|
|
32
33
|
error() = default;
|
|
33
34
|
error(std::error_code ec, std::string message = {}, error_context ctx = {});
|
|
34
35
|
error(std::error_code ec, std::string message, error_context ctx, error cause);
|
|
36
|
+
error(std::error_code ec, std::string message, error_context ctx, couchbase::node_id node_id);
|
|
35
37
|
|
|
36
38
|
[[nodiscard]] auto ec() const -> std::error_code;
|
|
37
39
|
[[nodiscard]] auto message() const -> const std::string&;
|
|
38
40
|
[[nodiscard]] auto ctx() const -> const error_context&;
|
|
39
41
|
[[nodiscard]] auto cause() const -> std::optional<error>;
|
|
40
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Returns the identity of the cluster node where the error occurred.
|
|
45
|
+
*
|
|
46
|
+
* The returned node_id is default-constructed (falsy) when the node
|
|
47
|
+
* could not be determined (e.g. for non-KV errors).
|
|
48
|
+
*
|
|
49
|
+
* @return identity of the node that returned the error
|
|
50
|
+
*
|
|
51
|
+
* @since 1.3.2
|
|
52
|
+
* @uncommitted
|
|
53
|
+
*/
|
|
54
|
+
[[nodiscard]] auto node_id() const -> const couchbase::node_id&;
|
|
55
|
+
|
|
41
56
|
explicit operator bool() const;
|
|
42
57
|
auto operator==(const error& other) const -> bool;
|
|
43
58
|
|
|
@@ -46,6 +61,7 @@ private:
|
|
|
46
61
|
std::string message_{};
|
|
47
62
|
error_context ctx_{};
|
|
48
63
|
std::shared_ptr<error> cause_{};
|
|
64
|
+
couchbase::node_id node_id_{};
|
|
49
65
|
};
|
|
50
66
|
|
|
51
67
|
} // namespace couchbase
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2024-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 <cstdint>
|
|
21
|
+
#include <functional>
|
|
22
|
+
#include <string>
|
|
23
|
+
|
|
24
|
+
namespace couchbase
|
|
25
|
+
{
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Uniquely identifies a cluster node.
|
|
29
|
+
*
|
|
30
|
+
* On Couchbase Server 8.0.1+ the identifier is the server-assigned node UUID.
|
|
31
|
+
* On older releases, a stable opaque token is derived from the node's hostname
|
|
32
|
+
* and management port.
|
|
33
|
+
*
|
|
34
|
+
* The type is equality-comparable, ordered, and hashable.
|
|
35
|
+
*
|
|
36
|
+
* @since 1.3.2
|
|
37
|
+
* @uncommitted
|
|
38
|
+
*/
|
|
39
|
+
class node_id
|
|
40
|
+
{
|
|
41
|
+
public:
|
|
42
|
+
/**
|
|
43
|
+
* Creates an empty (invalid) node_id.
|
|
44
|
+
*
|
|
45
|
+
* @since 1.3.2
|
|
46
|
+
* @uncommitted
|
|
47
|
+
*/
|
|
48
|
+
node_id() = default;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* User-facing identifier string.
|
|
52
|
+
*
|
|
53
|
+
* Returns node_uuid when the server provides one, otherwise a stable
|
|
54
|
+
* hex-encoded hash derived from hostname and management port.
|
|
55
|
+
*
|
|
56
|
+
* @return opaque identifier string (empty for default-constructed instances)
|
|
57
|
+
*
|
|
58
|
+
* @since 1.3.2
|
|
59
|
+
* @uncommitted
|
|
60
|
+
*/
|
|
61
|
+
[[nodiscard]] auto id() const -> const std::string&;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The server-assigned node UUID (empty on servers before 8.0.1).
|
|
65
|
+
*
|
|
66
|
+
* @since 1.3.2
|
|
67
|
+
* @uncommitted
|
|
68
|
+
*/
|
|
69
|
+
[[nodiscard]] auto node_uuid() const -> const std::string&;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The hostname of the node.
|
|
73
|
+
*
|
|
74
|
+
* @since 1.3.2
|
|
75
|
+
* @uncommitted
|
|
76
|
+
*/
|
|
77
|
+
[[nodiscard]] auto hostname() const -> const std::string&;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The port of the node's key-value service.
|
|
81
|
+
*
|
|
82
|
+
* This reflects the port actually used by the client: the TLS port when the
|
|
83
|
+
* cluster connection is TLS-enabled, otherwise the plain port.
|
|
84
|
+
*
|
|
85
|
+
* @since 1.3.2
|
|
86
|
+
* @uncommitted
|
|
87
|
+
*/
|
|
88
|
+
[[nodiscard]] auto port() const -> std::uint16_t;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Returns true when the node_id was properly initialized (not default-constructed).
|
|
92
|
+
*
|
|
93
|
+
* @since 1.3.2
|
|
94
|
+
* @uncommitted
|
|
95
|
+
*/
|
|
96
|
+
explicit operator bool() const;
|
|
97
|
+
|
|
98
|
+
auto operator==(const node_id& other) const -> bool;
|
|
99
|
+
auto operator!=(const node_id& other) const -> bool;
|
|
100
|
+
auto operator<(const node_id& other) const -> bool;
|
|
101
|
+
|
|
102
|
+
private:
|
|
103
|
+
friend class internal_node_id;
|
|
104
|
+
|
|
105
|
+
node_id(std::string node_uuid, std::string hostname, std::uint16_t port);
|
|
106
|
+
|
|
107
|
+
std::string node_uuid_{};
|
|
108
|
+
std::string hostname_{};
|
|
109
|
+
std::uint16_t port_{ 0 };
|
|
110
|
+
// Computed once at construction: node_uuid_ if non-empty, otherwise a
|
|
111
|
+
// deterministic hex-encoded CRC32 hash of "hostname:port".
|
|
112
|
+
std::string id_{};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
} // namespace couchbase
|
|
116
|
+
|
|
117
|
+
template<>
|
|
118
|
+
struct std::hash<couchbase::node_id> {
|
|
119
|
+
auto operator()(const couchbase::node_id& nid) const noexcept -> std::size_t
|
|
120
|
+
{
|
|
121
|
+
return std::hash<std::string>{}(nid.id());
|
|
122
|
+
}
|
|
123
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2024-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/common_options.hxx>
|
|
21
|
+
#include <couchbase/error.hxx>
|
|
22
|
+
#include <couchbase/node_id.hxx>
|
|
23
|
+
|
|
24
|
+
#include <functional>
|
|
25
|
+
|
|
26
|
+
namespace couchbase
|
|
27
|
+
{
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Options for @ref collection#node_id_for().
|
|
31
|
+
*
|
|
32
|
+
* @since 1.3.2
|
|
33
|
+
* @uncommitted
|
|
34
|
+
*/
|
|
35
|
+
struct node_id_for_options : public common_options<node_id_for_options> {
|
|
36
|
+
/**
|
|
37
|
+
* Immutable value object representing consistent options.
|
|
38
|
+
*
|
|
39
|
+
* @since 1.3.2
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
struct built : public common_options<node_id_for_options>::built {
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Validates options and returns them as an immutable value.
|
|
47
|
+
*
|
|
48
|
+
* @return consistent options as an immutable value
|
|
49
|
+
*
|
|
50
|
+
* @since 1.3.2
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
[[nodiscard]] auto build() const -> built
|
|
54
|
+
{
|
|
55
|
+
return { build_common_options() };
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
using node_id_for_handler = std::function<void(error, node_id)>;
|
|
60
|
+
|
|
61
|
+
} // namespace couchbase
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2024-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/common_options.hxx>
|
|
21
|
+
#include <couchbase/error.hxx>
|
|
22
|
+
#include <couchbase/node_id.hxx>
|
|
23
|
+
|
|
24
|
+
#include <functional>
|
|
25
|
+
#include <vector>
|
|
26
|
+
|
|
27
|
+
namespace couchbase
|
|
28
|
+
{
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Options for @ref collection#node_ids().
|
|
32
|
+
*
|
|
33
|
+
* @since 1.3.2
|
|
34
|
+
* @uncommitted
|
|
35
|
+
*/
|
|
36
|
+
struct node_ids_options : public common_options<node_ids_options> {
|
|
37
|
+
/**
|
|
38
|
+
* Immutable value object representing consistent options.
|
|
39
|
+
*
|
|
40
|
+
* @since 1.3.2
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
struct built : public common_options<node_ids_options>::built {
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Validates options and returns them as an immutable value.
|
|
48
|
+
*
|
|
49
|
+
* @return consistent options as an immutable value
|
|
50
|
+
*
|
|
51
|
+
* @since 1.3.2
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
[[nodiscard]] auto build() const -> built
|
|
55
|
+
{
|
|
56
|
+
return { build_common_options() };
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
using node_ids_handler = std::function<void(error, std::vector<node_id>)>;
|
|
61
|
+
|
|
62
|
+
} // namespace couchbase
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
#pragma once
|
|
19
19
|
|
|
20
20
|
#include <couchbase/cas.hxx>
|
|
21
|
+
#include <couchbase/node_id.hxx>
|
|
22
|
+
|
|
23
|
+
#include <utility>
|
|
21
24
|
|
|
22
25
|
namespace couchbase
|
|
23
26
|
{
|
|
@@ -48,6 +51,19 @@ public:
|
|
|
48
51
|
{
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
/**
|
|
55
|
+
* @param cas
|
|
56
|
+
* @param node_id identity of the node that served the request
|
|
57
|
+
*
|
|
58
|
+
* @since 1.3.2
|
|
59
|
+
* @uncommitted
|
|
60
|
+
*/
|
|
61
|
+
result(couchbase::cas cas, couchbase::node_id node_id)
|
|
62
|
+
: cas_(cas)
|
|
63
|
+
, node_id_(std::move(node_id))
|
|
64
|
+
{
|
|
65
|
+
}
|
|
66
|
+
|
|
51
67
|
/**
|
|
52
68
|
* @return
|
|
53
69
|
*
|
|
@@ -59,8 +75,34 @@ public:
|
|
|
59
75
|
return cas_;
|
|
60
76
|
}
|
|
61
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Returns the identity of the cluster node that served this request.
|
|
80
|
+
*
|
|
81
|
+
* The returned node_id is default-constructed (falsy) when the node
|
|
82
|
+
* could not be determined.
|
|
83
|
+
*
|
|
84
|
+
* @return identity of the serving node
|
|
85
|
+
*
|
|
86
|
+
* @since 1.3.2
|
|
87
|
+
* @uncommitted
|
|
88
|
+
*/
|
|
89
|
+
[[nodiscard]] auto node_id() const -> const couchbase::node_id&
|
|
90
|
+
{
|
|
91
|
+
return node_id_;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @since 1.3.2
|
|
96
|
+
* @internal
|
|
97
|
+
*/
|
|
98
|
+
void node_id(couchbase::node_id id)
|
|
99
|
+
{
|
|
100
|
+
node_id_ = std::move(id);
|
|
101
|
+
}
|
|
102
|
+
|
|
62
103
|
private:
|
|
63
104
|
couchbase::cas cas_{ 0U };
|
|
105
|
+
couchbase::node_id node_id_{};
|
|
64
106
|
};
|
|
65
107
|
|
|
66
108
|
} // namespace couchbase
|
data/ext/rcb_crud.cxx
CHANGED
|
@@ -734,6 +734,7 @@ cb_Backend_document_append(VALUE self,
|
|
|
734
734
|
cb_extract_content(req, content);
|
|
735
735
|
cb_extract_timeout(req, options);
|
|
736
736
|
cb_extract_durability_level(req, options);
|
|
737
|
+
cb_extract_cas(req, options);
|
|
737
738
|
|
|
738
739
|
auto parent_span = cb_create_parent_span(req, self);
|
|
739
740
|
|
|
@@ -807,6 +808,7 @@ cb_Backend_document_prepend(VALUE self,
|
|
|
807
808
|
cb_extract_content(req, content);
|
|
808
809
|
cb_extract_timeout(req, options);
|
|
809
810
|
cb_extract_durability_level(req, options);
|
|
811
|
+
cb_extract_cas(req, options);
|
|
810
812
|
|
|
811
813
|
auto parent_span = cb_create_parent_span(req, self);
|
|
812
814
|
|
data/ext/rcb_logger.cxx
CHANGED
|
@@ -184,19 +184,19 @@ cb_Backend_set_log_level(VALUE /* self */, VALUE log_level)
|
|
|
184
184
|
{
|
|
185
185
|
Check_Type(log_level, T_SYMBOL);
|
|
186
186
|
if (ID type = rb_sym2id(log_level); type == rb_intern("trace")) {
|
|
187
|
-
|
|
187
|
+
core::logger::set_log_levels(core::logger::level::trace);
|
|
188
188
|
} else if (type == rb_intern("debug")) {
|
|
189
|
-
|
|
189
|
+
core::logger::set_log_levels(core::logger::level::debug);
|
|
190
190
|
} else if (type == rb_intern("info")) {
|
|
191
|
-
|
|
191
|
+
core::logger::set_log_levels(core::logger::level::info);
|
|
192
192
|
} else if (type == rb_intern("warn")) {
|
|
193
|
-
|
|
193
|
+
core::logger::set_log_levels(core::logger::level::warn);
|
|
194
194
|
} else if (type == rb_intern("error")) {
|
|
195
|
-
|
|
195
|
+
core::logger::set_log_levels(core::logger::level::err);
|
|
196
196
|
} else if (type == rb_intern("critical")) {
|
|
197
|
-
|
|
197
|
+
core::logger::set_log_levels(core::logger::level::critical);
|
|
198
198
|
} else if (type == rb_intern("off")) {
|
|
199
|
-
|
|
199
|
+
core::logger::set_log_levels(core::logger::level::off);
|
|
200
200
|
} else {
|
|
201
201
|
rb_raise(rb_eArgError, "Unsupported log level type: %+" PRIsVALUE, log_level);
|
|
202
202
|
return Qnil;
|
|
@@ -207,23 +207,21 @@ cb_Backend_set_log_level(VALUE /* self */, VALUE log_level)
|
|
|
207
207
|
static VALUE
|
|
208
208
|
cb_Backend_get_log_level(VALUE /* self */)
|
|
209
209
|
{
|
|
210
|
-
switch (
|
|
211
|
-
case
|
|
210
|
+
switch (core::logger::get_lowest_log_level()) {
|
|
211
|
+
case core::logger::level::trace:
|
|
212
212
|
return rb_id2sym(rb_intern("trace"));
|
|
213
|
-
case
|
|
213
|
+
case core::logger::level::debug:
|
|
214
214
|
return rb_id2sym(rb_intern("debug"));
|
|
215
|
-
case
|
|
215
|
+
case core::logger::level::info:
|
|
216
216
|
return rb_id2sym(rb_intern("info"));
|
|
217
|
-
case
|
|
217
|
+
case core::logger::level::warn:
|
|
218
218
|
return rb_id2sym(rb_intern("warn"));
|
|
219
|
-
case
|
|
219
|
+
case core::logger::level::err:
|
|
220
220
|
return rb_id2sym(rb_intern("error"));
|
|
221
|
-
case
|
|
221
|
+
case core::logger::level::critical:
|
|
222
222
|
return rb_id2sym(rb_intern("critical"));
|
|
223
|
-
case
|
|
223
|
+
case core::logger::level::off:
|
|
224
224
|
return rb_id2sym(rb_intern("off"));
|
|
225
|
-
case spdlog::level::n_levels:
|
|
226
|
-
return Qnil;
|
|
227
225
|
}
|
|
228
226
|
return Qnil;
|
|
229
227
|
}
|