couchbase 3.5.7 → 3.6.0
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 +1 -1
- data/ext/cache/extconf_include.rb +3 -3
- data/ext/cache/mozilla-ca-bundle.crt +3 -165
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/CMakeLists.txt +14 -10
- data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy.cc +7 -4
- data/ext/couchbase/CMakeLists.txt +12 -1
- data/ext/couchbase/cmake/Profiler.cmake +15 -0
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +2 -2
- data/ext/couchbase/cmake/couchbase_cxx_client.pc.in +1 -1
- data/ext/couchbase/core/app_telemetry_address.cxx +55 -0
- data/ext/couchbase/core/app_telemetry_address.hxx +39 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +753 -0
- data/ext/couchbase/core/app_telemetry_meter.hxx +198 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +895 -0
- data/ext/couchbase/core/app_telemetry_reporter.hxx +59 -0
- data/ext/couchbase/core/bucket.cxx +77 -35
- data/ext/couchbase/core/bucket.hxx +17 -10
- data/ext/couchbase/core/cluster.cxx +54 -16
- data/ext/couchbase/core/cluster_credentials.cxx +27 -0
- data/ext/couchbase/core/cluster_credentials.hxx +36 -0
- data/ext/couchbase/core/cluster_options.hxx +12 -0
- data/ext/couchbase/core/collections_component.cxx +7 -5
- data/ext/couchbase/core/http_component.cxx +6 -0
- data/ext/couchbase/core/impl/binary_collection.cxx +4 -0
- data/ext/couchbase/core/impl/bucket_manager.cxx +2 -0
- data/ext/couchbase/core/impl/cluster.cxx +9 -0
- data/ext/couchbase/core/impl/collection.cxx +2 -0
- data/ext/couchbase/core/impl/error.cxx +1 -0
- data/ext/couchbase/core/impl/logger.cxx +51 -0
- data/ext/couchbase/core/impl/replica_utils.cxx +1 -1
- data/ext/couchbase/core/impl/transaction_get_multi_replicas_from_preferred_server_group_spec.cxx +32 -0
- data/ext/couchbase/core/impl/transaction_get_multi_spec.cxx +30 -0
- data/ext/couchbase/core/impl/transaction_op_error_category.cxx +2 -0
- data/ext/couchbase/core/io/config_tracker.cxx +6 -6
- data/ext/couchbase/core/io/http_command.hxx +35 -11
- data/ext/couchbase/core/io/http_session.cxx +10 -0
- data/ext/couchbase/core/io/http_session.hxx +4 -0
- data/ext/couchbase/core/io/http_session_manager.hxx +83 -34
- data/ext/couchbase/core/io/mcbp_command.hxx +41 -2
- data/ext/couchbase/core/io/mcbp_session.cxx +52 -19
- data/ext/couchbase/core/io/mcbp_session.hxx +3 -0
- data/ext/couchbase/core/logger/logger.cxx +46 -0
- data/ext/couchbase/core/logger/logger.hxx +41 -1
- data/ext/couchbase/core/management/bucket_settings.hxx +1 -0
- data/ext/couchbase/core/management/bucket_settings_json.hxx +4 -0
- data/ext/couchbase/core/meta/features.hxx +32 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +9 -9
- data/ext/couchbase/core/operations/document_append.cxx +1 -0
- data/ext/couchbase/core/operations/document_append.hxx +1 -0
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +10 -2
- data/ext/couchbase/core/operations/document_lookup_in.cxx +4 -0
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +14 -2
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +4 -0
- data/ext/couchbase/core/operations/document_mutate_in.cxx +4 -0
- data/ext/couchbase/core/operations/document_mutate_in.hxx +1 -0
- data/ext/couchbase/core/operations/document_prepend.cxx +1 -0
- data/ext/couchbase/core/operations/document_prepend.hxx +1 -0
- data/ext/couchbase/core/operations/document_query.cxx +12 -10
- data/ext/couchbase/core/operations/http_noop.cxx +1 -0
- data/ext/couchbase/core/operations/management/bucket_create.cxx +3 -0
- data/ext/couchbase/core/operations/management/bucket_update.cxx +3 -0
- data/ext/couchbase/core/origin.cxx +0 -5
- data/ext/couchbase/core/origin.hxx +2 -11
- data/ext/couchbase/core/platform/random.cc +6 -3
- data/ext/couchbase/core/platform/random.h +2 -2
- data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +9 -0
- data/ext/couchbase/core/timeout_defaults.hxx +4 -0
- data/ext/couchbase/core/topology/configuration.cxx +10 -13
- data/ext/couchbase/core/topology/configuration.hxx +14 -15
- data/ext/couchbase/core/topology/configuration_json.hxx +6 -0
- data/ext/couchbase/core/transactions/async_attempt_context.hxx +22 -2
- data/ext/couchbase/core/transactions/attempt_context.hxx +25 -7
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +688 -238
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +91 -12
- data/ext/couchbase/core/transactions/exceptions.cxx +5 -0
- data/ext/couchbase/core/transactions/exceptions.hxx +20 -0
- data/ext/couchbase/core/transactions/exceptions_fmt.hxx +3 -0
- data/ext/couchbase/core/transactions/forward_compat.cxx +71 -6
- data/ext/couchbase/core/transactions/forward_compat.hxx +45 -59
- data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +616 -0
- data/ext/couchbase/core/transactions/get_multi_orchestrator.hxx +61 -0
- data/ext/couchbase/core/transactions/internal/doc_record.cxx +8 -0
- data/ext/couchbase/core/transactions/internal/doc_record.hxx +16 -5
- data/ext/couchbase/core/transactions/internal/exceptions_internal.hxx +12 -0
- data/ext/couchbase/core/transactions/internal/transaction_context.hxx +13 -0
- data/ext/couchbase/core/transactions/internal/transaction_fields.hxx +1 -0
- data/ext/couchbase/core/transactions/staged_mutation.cxx +277 -96
- data/ext/couchbase/core/transactions/staged_mutation.hxx +28 -76
- data/ext/couchbase/core/transactions/transaction_context.cxx +33 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_mode.hxx +28 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +27 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +71 -0
- data/ext/couchbase/core/transactions/transaction_get_multi_result.hxx +66 -0
- data/ext/couchbase/core/transactions/transaction_links.hxx +10 -0
- data/ext/couchbase/core/transactions/transactions.cxx +8 -3
- data/ext/couchbase/core/utils/connection_string.cxx +4 -0
- data/ext/couchbase/core/utils/url_codec.cxx +26 -0
- data/ext/couchbase/core/utils/url_codec.hxx +11 -0
- data/ext/couchbase/core/websocket_codec.cxx +647 -0
- data/ext/couchbase/core/websocket_codec.hxx +77 -0
- data/ext/couchbase/couchbase/analytics_options.hxx +70 -6
- data/ext/couchbase/couchbase/application_telemetry_options.hxx +124 -0
- data/ext/couchbase/couchbase/cluster_options.hxx +17 -0
- data/ext/couchbase/couchbase/error_codes.hxx +1 -0
- data/ext/couchbase/couchbase/logger.hxx +16 -0
- data/ext/couchbase/couchbase/management/bucket_settings.hxx +1 -0
- data/ext/couchbase/couchbase/query_options.hxx +70 -6
- data/ext/couchbase/couchbase/transactions/async_attempt_context.hxx +29 -5
- data/ext/couchbase/couchbase/transactions/attempt_context.hxx +24 -7
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_mode.hxx +47 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_options.hxx +44 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +46 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_options.hxx +48 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +109 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_spec.hxx +47 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +102 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_spec.hxx +45 -0
- data/ext/rcb_buckets.cxx +26 -0
- data/lib/active_support/cache/couchbase_store.rb +1 -1
- data/lib/couchbase/cluster.rb +1 -1
- data/lib/couchbase/collection.rb +1 -1
- data/lib/couchbase/collection_options.rb +2 -2
- data/lib/couchbase/management/analytics_index_manager.rb +4 -4
- data/lib/couchbase/management/bucket_manager.rb +8 -2
- data/lib/couchbase/protostellar/cluster.rb +2 -2
- data/lib/couchbase/protostellar/collection.rb +1 -1
- data/lib/couchbase/protostellar/management/collection_query_index_manager.rb +1 -1
- data/lib/couchbase/protostellar/request_generator/admin/bucket.rb +4 -4
- data/lib/couchbase/protostellar/request_generator/admin/collection.rb +6 -6
- data/lib/couchbase/protostellar/request_generator/admin/query.rb +13 -13
- data/lib/couchbase/protostellar/request_generator/kv.rb +25 -25
- data/lib/couchbase/protostellar/request_generator/query.rb +4 -4
- data/lib/couchbase/protostellar/request_generator/search.rb +25 -25
- data/lib/couchbase/protostellar/response_converter/search.rb +1 -1
- data/lib/couchbase/protostellar/retry/reason.rb +1 -1
- data/lib/couchbase/protostellar/timeouts.rb +1 -1
- data/lib/couchbase/scope.rb +1 -1
- data/lib/couchbase/transcoder_flags.rb +1 -1
- data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -1
- data/lib/couchbase/version.rb +1 -1
- metadata +47 -19
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/COPYING +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/cmake/SnappyConfig.cmake.in +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/cmake/config.h.in +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-c.cc +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-c.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-internal.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-sinksource.cc +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-sinksource.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-stubs-internal.cc +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-stubs-internal.h +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy-stubs-public.h.in +0 -0
- /data/ext/cache/snappy/{585305c8dbb8f762f2c2e17f937f1cf3ac6cbc9c → 3cde171792b3607f75c14e5011eaf69da4857bd8}/snappy/snappy.h +0 -0
@@ -25,6 +25,8 @@
|
|
25
25
|
|
26
26
|
#pragma once
|
27
27
|
|
28
|
+
#include <functional>
|
29
|
+
|
28
30
|
#include "level.hxx"
|
29
31
|
|
30
32
|
#include <spdlog/fmt/bundled/core.h>
|
@@ -36,8 +38,17 @@
|
|
36
38
|
|
37
39
|
namespace couchbase::core::logger
|
38
40
|
{
|
41
|
+
|
39
42
|
struct configuration;
|
40
43
|
|
44
|
+
struct log_location {
|
45
|
+
std::string file;
|
46
|
+
std::string function;
|
47
|
+
int line;
|
48
|
+
};
|
49
|
+
|
50
|
+
using log_callback = std::function<void(std::string_view, level, log_location)>;
|
51
|
+
|
41
52
|
auto
|
42
53
|
level_from_str(const std::string& str) -> level;
|
43
54
|
|
@@ -113,6 +124,12 @@ get() -> spdlog::logger*;
|
|
113
124
|
void
|
114
125
|
reset();
|
115
126
|
|
127
|
+
void
|
128
|
+
register_log_callback(log_callback callback);
|
129
|
+
|
130
|
+
void
|
131
|
+
unregister_log_callback();
|
132
|
+
|
116
133
|
/**
|
117
134
|
* Engines that create their own instances of an spdlog::logger should register the logger here to
|
118
135
|
* ensure that the verbosity of the logger is updated when memcached receives a request to update
|
@@ -179,6 +196,13 @@ log(const char* file, int line, const char* function, level lvl, std::string_vie
|
|
179
196
|
|
180
197
|
void
|
181
198
|
log_protocol(const char* file, int line, const char* function, std::string_view msg);
|
199
|
+
|
200
|
+
void
|
201
|
+
log_custom_logger(const char* file,
|
202
|
+
int line,
|
203
|
+
const char* function,
|
204
|
+
level lvl,
|
205
|
+
std::string_view msg);
|
182
206
|
} // namespace detail
|
183
207
|
|
184
208
|
/**
|
@@ -199,6 +223,19 @@ log(const char* file,
|
|
199
223
|
detail::log(file, line, function, lvl, fmt::format(msg, std::forward<Args>(args)...));
|
200
224
|
}
|
201
225
|
|
226
|
+
template<typename... Args>
|
227
|
+
inline void
|
228
|
+
log_custom_logger(const char* file,
|
229
|
+
int line,
|
230
|
+
const char* function,
|
231
|
+
level lvl,
|
232
|
+
fmt::format_string<Args...> msg,
|
233
|
+
Args&&... args)
|
234
|
+
{
|
235
|
+
detail::log_custom_logger(
|
236
|
+
file, line, function, lvl, fmt::format(msg, std::forward<Args>(args)...));
|
237
|
+
}
|
238
|
+
|
202
239
|
template<typename... Args>
|
203
240
|
inline void
|
204
241
|
log_protocol(const char* file,
|
@@ -228,7 +265,6 @@ shutdown();
|
|
228
265
|
*/
|
229
266
|
auto
|
230
267
|
is_initialized() -> bool;
|
231
|
-
|
232
268
|
} // namespace couchbase::core::logger
|
233
269
|
|
234
270
|
#if defined(__GNUC__) || defined(__clang__)
|
@@ -243,6 +279,8 @@ is_initialized() -> bool;
|
|
243
279
|
*/
|
244
280
|
#define COUCHBASE_LOG(file, line, function, severity, ...) \
|
245
281
|
do { \
|
282
|
+
couchbase::core::logger::log_custom_logger(file, line, function, severity, __VA_ARGS__); \
|
283
|
+
\
|
246
284
|
if (couchbase::core::logger::should_log(severity)) { \
|
247
285
|
couchbase::core::logger::log(file, line, function, severity, __VA_ARGS__); \
|
248
286
|
} \
|
@@ -305,6 +343,8 @@ is_initialized() -> bool;
|
|
305
343
|
*/
|
306
344
|
#define COUCHBASE_LOG_RAW(file, line, function, severity, msg) \
|
307
345
|
do { \
|
346
|
+
couchbase::core::logger::log_custom_logger(file, line, function, severity, msg); \
|
347
|
+
\
|
308
348
|
if (couchbase::core::logger::should_log(severity)) { \
|
309
349
|
couchbase::core::logger::detail::log(file, line, function, severity, msg); \
|
310
350
|
} \
|
@@ -136,6 +136,7 @@ struct bucket_settings {
|
|
136
136
|
std::optional<bool> history_retention_collection_default{};
|
137
137
|
std::optional<std::uint32_t> history_retention_bytes{};
|
138
138
|
std::optional<std::uint32_t> history_retention_duration{};
|
139
|
+
std::optional<std::uint16_t> num_vbuckets{};
|
139
140
|
|
140
141
|
/**
|
141
142
|
* UNCOMMITTED: This API may change in the future
|
@@ -56,6 +56,10 @@ struct traits<couchbase::core::management::cluster::bucket_settings> {
|
|
56
56
|
history_retention_duration->template as<std::optional<std::uint32_t>>();
|
57
57
|
}
|
58
58
|
|
59
|
+
if (auto* num_vbuckets = v.find("numVBuckets"); num_vbuckets != nullptr) {
|
60
|
+
result.num_vbuckets = num_vbuckets->template as<std::optional<std::uint16_t>>();
|
61
|
+
}
|
62
|
+
|
59
63
|
if (auto& str = v.at("bucketType").get_string(); str == "couchbase" || str == "membase") {
|
60
64
|
result.bucket_type = couchbase::core::management::cluster::bucket_type::couchbase;
|
61
65
|
} else if (str == "ephemeral") {
|
@@ -207,7 +207,39 @@
|
|
207
207
|
*/
|
208
208
|
#define COUCHBASE_CXX_CLIENT_PUBLIC_API_PARENT_SPAN 1
|
209
209
|
|
210
|
+
/**
|
211
|
+
* The library can be configured to use application telemetry (default is enabled)
|
212
|
+
* See couchbase::application_telemetry_options for available options
|
213
|
+
* to pass into couchbase::cluster_options
|
214
|
+
*/
|
215
|
+
#define COUCHBASE_CXX_CLIENT_SUPPORTS_APP_TELEMETRY 1
|
216
|
+
|
210
217
|
/**
|
211
218
|
* core API like with_bucket_configuration() yields shared_ptr instead of configuration copy
|
212
219
|
*/
|
213
220
|
#define COUCHBASE_CXX_CLIENT_CORE_RETURNS_POINTER_TO_CONFIG 1
|
221
|
+
|
222
|
+
/**
|
223
|
+
* bucket_settings in both the public and core management APIs have a num_vbuckets attribute
|
224
|
+
*/
|
225
|
+
#define COUCHBASE_CXX_CLIENT_HAS_BUCKET_SETTINGS_NUM_VBUCKETS 1
|
226
|
+
|
227
|
+
/**
|
228
|
+
* couchbase::query_options and couchbase::analytics_options provide the methods:
|
229
|
+
* - add_positional_parameter
|
230
|
+
* - add_named_parameter
|
231
|
+
* - clear_positional_parameters
|
232
|
+
* - clear_named_parameters
|
233
|
+
*/
|
234
|
+
#define COUCHBASE_CXX_CLIENT_QUERY_OPTIONS_HAVE_ADD_PARAMETER 1
|
235
|
+
|
236
|
+
/**
|
237
|
+
* couchbase::query_options and couchbase::analytics_options allow setting both positional and named
|
238
|
+
* parameters.
|
239
|
+
*/
|
240
|
+
#define COUCHBASE_CXX_CLIENT_QUERY_SUPPORTS_BOTH_POSITIONAL_NAMED_PARAMETERS 1
|
241
|
+
|
242
|
+
/**
|
243
|
+
* get_multi API is implemented for transactions
|
244
|
+
*/
|
245
|
+
#define COUCHBASE_CXX_CLIENT_HAS_TRANSACTIONS_GET_MULTI 1
|
@@ -35,16 +35,16 @@ analytics_request::encode_to(analytics_request::encoded_request_type& encoded,
|
|
35
35
|
tao::json::value body{ { "statement", statement },
|
36
36
|
{ "client_context_id", encoded.client_context_id },
|
37
37
|
{ "timeout", fmt::format("{}ms", encoded.timeout.count()) } };
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
}
|
45
|
-
body[key] = utils::json::parse(value);
|
38
|
+
|
39
|
+
for (const auto& [name, value] : named_parameters) {
|
40
|
+
Expects(name.empty() == false);
|
41
|
+
std::string key = name;
|
42
|
+
if (key[0] != '$') {
|
43
|
+
key.insert(key.begin(), '$');
|
46
44
|
}
|
47
|
-
|
45
|
+
body[key] = utils::json::parse(value);
|
46
|
+
}
|
47
|
+
if (!positional_parameters.empty()) {
|
48
48
|
std::vector<tao::json::value> parameters;
|
49
49
|
parameters.reserve(positional_parameters.size());
|
50
50
|
for (const auto& value : positional_parameters) {
|
@@ -50,6 +50,7 @@ struct append_request {
|
|
50
50
|
std::vector<std::byte> value;
|
51
51
|
std::uint16_t partition{};
|
52
52
|
std::uint32_t opaque{};
|
53
|
+
couchbase::cas cas{ 0 };
|
53
54
|
couchbase::durability_level durability_level{ durability_level::none };
|
54
55
|
std::optional<std::chrono::milliseconds> timeout{};
|
55
56
|
io::retry_context<false> retries{};
|
@@ -131,7 +131,11 @@ struct get_all_replicas_request {
|
|
131
131
|
}
|
132
132
|
}
|
133
133
|
if (local_handler) {
|
134
|
-
|
134
|
+
if (ctx->result_.empty()) {
|
135
|
+
// Return an error only when we have no results from any replica.
|
136
|
+
return local_handler({ std::move(resp.ctx), {} });
|
137
|
+
}
|
138
|
+
return local_handler({ {}, std::move(ctx->result_) });
|
135
139
|
}
|
136
140
|
});
|
137
141
|
} else {
|
@@ -158,7 +162,11 @@ struct get_all_replicas_request {
|
|
158
162
|
}
|
159
163
|
}
|
160
164
|
if (local_handler) {
|
161
|
-
|
165
|
+
if (ctx->result_.empty()) {
|
166
|
+
// Return an error only when we have no results from any replica.
|
167
|
+
return local_handler({ std::move(resp.ctx), {} });
|
168
|
+
}
|
169
|
+
return local_handler({ {}, std::move(ctx->result_) });
|
162
170
|
}
|
163
171
|
});
|
164
172
|
}
|
@@ -31,6 +31,10 @@ auto
|
|
31
31
|
lookup_in_request::encode_to(lookup_in_request::encoded_request_type& encoded,
|
32
32
|
mcbp_context&& context) -> std::error_code
|
33
33
|
{
|
34
|
+
if (specs.empty()) {
|
35
|
+
return errc::common::invalid_argument;
|
36
|
+
}
|
37
|
+
|
34
38
|
for (std::size_t i = 0; i < specs.size(); ++i) {
|
35
39
|
specs[i].original_index_ = i;
|
36
40
|
|
@@ -115,6 +115,10 @@ struct lookup_in_all_replicas_request {
|
|
115
115
|
ec = errc::key_value::document_irretrievable;
|
116
116
|
}
|
117
117
|
|
118
|
+
if (!ec && specs.empty()) {
|
119
|
+
ec = errc::common::invalid_argument;
|
120
|
+
}
|
121
|
+
|
118
122
|
if (ec) {
|
119
123
|
return h(response_type{ make_subdocument_error_context(
|
120
124
|
make_key_value_error_context(ec, id), ec, {}, {}, false) });
|
@@ -183,7 +187,11 @@ struct lookup_in_all_replicas_request {
|
|
183
187
|
}
|
184
188
|
}
|
185
189
|
if (local_handler) {
|
186
|
-
|
190
|
+
if (ctx->result_.empty()) {
|
191
|
+
// Return an error only when we have no results from any replica.
|
192
|
+
return local_handler({ std::move(resp.ctx), {} });
|
193
|
+
}
|
194
|
+
return local_handler({ {}, std::move(ctx->result_) });
|
187
195
|
}
|
188
196
|
});
|
189
197
|
} else {
|
@@ -227,7 +235,11 @@ struct lookup_in_all_replicas_request {
|
|
227
235
|
}
|
228
236
|
}
|
229
237
|
if (local_handler) {
|
230
|
-
|
238
|
+
if (ctx->result_.empty()) {
|
239
|
+
// Return an error only when we have no results from any replica.
|
240
|
+
return local_handler({ std::move(resp.ctx), {} });
|
241
|
+
}
|
242
|
+
return local_handler({ {}, std::move(ctx->result_) });
|
231
243
|
}
|
232
244
|
});
|
233
245
|
}
|
@@ -112,6 +112,10 @@ struct lookup_in_any_replica_request {
|
|
112
112
|
ec = errc::key_value::document_irretrievable;
|
113
113
|
}
|
114
114
|
|
115
|
+
if (!ec && specs.empty()) {
|
116
|
+
ec = errc::common::invalid_argument;
|
117
|
+
}
|
118
|
+
|
115
119
|
if (ec) {
|
116
120
|
return h(response_type{ make_subdocument_error_context(
|
117
121
|
make_key_value_error_context(ec, id), ec, {}, {}, false) });
|
@@ -36,6 +36,9 @@ mutate_in_request::encode_to(mutate_in_request::encoded_request_type& encoded,
|
|
36
36
|
!context.supports_feature(protocol::hello_feature::subdoc_create_as_deleted)) {
|
37
37
|
return errc::common::unsupported_operation;
|
38
38
|
}
|
39
|
+
if (specs.empty()) {
|
40
|
+
return errc::common::invalid_argument;
|
41
|
+
}
|
39
42
|
for (std::size_t i = 0; i < specs.size(); ++i) {
|
40
43
|
auto& entry = specs[i];
|
41
44
|
entry.original_index_ = i;
|
@@ -60,6 +63,7 @@ mutate_in_request::encode_to(mutate_in_request::encoded_request_type& encoded,
|
|
60
63
|
}
|
61
64
|
encoded.body().access_deleted(access_deleted);
|
62
65
|
encoded.body().create_as_deleted(create_as_deleted);
|
66
|
+
encoded.body().revive_document(revive_document);
|
63
67
|
encoded.body().store_semantics(store_semantics);
|
64
68
|
encoded.body().specs(specs);
|
65
69
|
if (preserve_expiry) {
|
@@ -63,6 +63,7 @@ struct mutate_in_request {
|
|
63
63
|
couchbase::cas cas{ 0 };
|
64
64
|
bool access_deleted{ false };
|
65
65
|
bool create_as_deleted{ false };
|
66
|
+
bool revive_document{ false };
|
66
67
|
std::optional<std::uint32_t> expiry{};
|
67
68
|
couchbase::store_semantics store_semantics{ couchbase::store_semantics::replace };
|
68
69
|
std::vector<couchbase::core::impl::subdoc::command> specs{};
|
@@ -50,6 +50,7 @@ struct prepend_request {
|
|
50
50
|
std::vector<std::byte> value;
|
51
51
|
std::uint16_t partition{};
|
52
52
|
std::uint32_t opaque{};
|
53
|
+
couchbase::cas cas{ 0 };
|
53
54
|
couchbase::durability_level durability_level{ durability_level::none };
|
54
55
|
std::optional<std::chrono::milliseconds> timeout{};
|
55
56
|
io::retry_context<false> retries{};
|
@@ -64,16 +64,16 @@ query_request::encode_to(query_request::encoded_request_type& encoded,
|
|
64
64
|
timeout_for_service -= std::chrono::milliseconds(500);
|
65
65
|
}
|
66
66
|
body["timeout"] = fmt::format("{}ms", timeout_for_service.count());
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
}
|
74
|
-
body[key] = utils::json::parse(value);
|
67
|
+
|
68
|
+
for (const auto& [name, value] : named_parameters) {
|
69
|
+
Expects(name.empty() == false);
|
70
|
+
std::string key = name;
|
71
|
+
if (key[0] != '$') {
|
72
|
+
key.insert(key.begin(), '$');
|
75
73
|
}
|
76
|
-
|
74
|
+
body[key] = utils::json::parse(value);
|
75
|
+
}
|
76
|
+
if (!positional_parameters.empty()) {
|
77
77
|
std::vector<tao::json::value> parameters;
|
78
78
|
parameters.reserve(positional_parameters.size());
|
79
79
|
for (const auto& value : positional_parameters) {
|
@@ -237,7 +237,9 @@ query_request::make_response(error_context::query&& ctx,
|
|
237
237
|
response.ctx.ec = errc::common::parsing_failure;
|
238
238
|
return response;
|
239
239
|
}
|
240
|
-
|
240
|
+
if (const auto* i = payload.find("requestID"); i != nullptr) {
|
241
|
+
response.meta.request_id = i->get_string();
|
242
|
+
}
|
241
243
|
|
242
244
|
if (const auto* i = payload.find("clientContextID"); i != nullptr) {
|
243
245
|
response.meta.client_context_id = i->get_string();
|
@@ -25,6 +25,7 @@ auto
|
|
25
25
|
http_noop_request::encode_to(http_noop_request::encoded_request_type& encoded,
|
26
26
|
http_context& /* context */) -> std::error_code
|
27
27
|
{
|
28
|
+
encoded.type = type;
|
28
29
|
encoded.headers["connection"] = "keep-alive";
|
29
30
|
encoded.method = "GET";
|
30
31
|
encoded.path = "/";
|
@@ -86,6 +86,9 @@ bucket_create_request::encode_to(encoded_request_type& encoded,
|
|
86
86
|
if (bucket.flush_enabled.has_value()) {
|
87
87
|
encoded.body.append(fmt::format("&flushEnabled={}", bucket.flush_enabled.value() ? "1" : "0"));
|
88
88
|
}
|
89
|
+
if (bucket.num_vbuckets.has_value()) {
|
90
|
+
encoded.body.append(fmt::format("&numVBuckets={}", bucket.num_vbuckets.value()));
|
91
|
+
}
|
89
92
|
|
90
93
|
switch (bucket.eviction_policy) {
|
91
94
|
case couchbase::core::management::cluster::bucket_eviction_policy::full:
|
@@ -69,6 +69,9 @@ bucket_update_request::encode_to(encoded_request_type& encoded,
|
|
69
69
|
if (bucket.flush_enabled.has_value()) {
|
70
70
|
encoded.body.append(fmt::format("&flushEnabled={}", bucket.flush_enabled.value() ? "1" : "0"));
|
71
71
|
}
|
72
|
+
if (bucket.num_vbuckets.has_value()) {
|
73
|
+
encoded.body.append(fmt::format("&numVBuckets={}", bucket.num_vbuckets.value()));
|
74
|
+
}
|
72
75
|
|
73
76
|
switch (bucket.eviction_policy) {
|
74
77
|
case couchbase::core::management::cluster::bucket_eviction_policy::full:
|
@@ -298,11 +298,6 @@ origin::to_json() const -> std::string
|
|
298
298
|
return tao::json::to_string(json);
|
299
299
|
}
|
300
300
|
|
301
|
-
auto
|
302
|
-
cluster_credentials::uses_certificate() const -> bool
|
303
|
-
{
|
304
|
-
return !certificate_path.empty();
|
305
|
-
}
|
306
301
|
} // namespace couchbase::core
|
307
302
|
|
308
303
|
couchbase::core::origin::origin(const couchbase::core::origin& other)
|
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
#pragma once
|
19
19
|
|
20
|
+
#include "cluster_credentials.hxx"
|
20
21
|
#include "cluster_options.hxx"
|
21
22
|
|
22
23
|
#include <string>
|
@@ -30,20 +31,10 @@ namespace utils
|
|
30
31
|
struct connection_string;
|
31
32
|
} // namespace utils
|
32
33
|
|
33
|
-
struct cluster_credentials {
|
34
|
-
std::string username{};
|
35
|
-
std::string password{};
|
36
|
-
std::string certificate_path{};
|
37
|
-
std::string key_path{};
|
38
|
-
std::optional<std::vector<std::string>> allowed_sasl_mechanisms{};
|
39
|
-
|
40
|
-
[[nodiscard]] bool uses_certificate() const;
|
41
|
-
};
|
42
|
-
|
43
34
|
namespace topology
|
44
35
|
{
|
45
36
|
struct configuration;
|
46
|
-
}
|
37
|
+
} // namespace topology
|
47
38
|
|
48
39
|
struct origin {
|
49
40
|
using node_entry = std::pair<std::string, std::string>;
|
@@ -82,9 +82,12 @@ public:
|
|
82
82
|
#ifdef WIN32
|
83
83
|
return CryptGenRandom(handle, (DWORD)size, static_cast<BYTE*>(dest));
|
84
84
|
#else
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
#if defined(__clang__) && defined(__clang_analyzer__)
|
86
|
+
[[clang::suppress]]
|
87
|
+
#endif
|
88
|
+
// TODO(CXXCBC-549)
|
89
|
+
// NOLINTNEXTLINE(clang-analyzer-unix.BlockInCriticalSection)
|
90
|
+
return static_cast<std::size_t>(read(handle, dest, size)) == size;
|
88
91
|
#endif
|
89
92
|
}
|
90
93
|
|
@@ -32,8 +32,8 @@ class RandomGenerator
|
|
32
32
|
public:
|
33
33
|
RandomGenerator();
|
34
34
|
|
35
|
-
|
35
|
+
auto next() -> std::uint64_t;
|
36
36
|
|
37
|
-
static
|
37
|
+
static auto getBytes(void* dest, size_t size) -> bool;
|
38
38
|
};
|
39
39
|
} // namespace couchbase::core
|
@@ -151,6 +151,15 @@ public:
|
|
151
151
|
}
|
152
152
|
}
|
153
153
|
|
154
|
+
void revive_document(bool value)
|
155
|
+
{
|
156
|
+
if (value) {
|
157
|
+
flags_ |= doc_flag_revive_document;
|
158
|
+
} else {
|
159
|
+
flags_ &= ~doc_flag_revive_document;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
154
163
|
void store_semantics(couchbase::store_semantics semantics)
|
155
164
|
{
|
156
165
|
flags_ &= std::byte{ 0b1111'1100U }; /* reset first two bits */
|
@@ -42,4 +42,8 @@ constexpr std::chrono::milliseconds config_poll_interval{ 2'500 };
|
|
42
42
|
constexpr std::chrono::milliseconds config_poll_floor{ 50 };
|
43
43
|
constexpr std::chrono::milliseconds config_idle_redial_timeout{ 5 * 60'000 };
|
44
44
|
constexpr std::chrono::milliseconds idle_http_connection_timeout{ 1'000 };
|
45
|
+
|
46
|
+
constexpr std::chrono::milliseconds app_telemetry_ping_interval{ 30'000 };
|
47
|
+
constexpr std::chrono::milliseconds app_telemetry_ping_timeout{ 2'000 };
|
48
|
+
constexpr std::chrono::milliseconds app_telemetry_backoff_interval{ std::chrono::hours{ 1 } };
|
45
49
|
} // namespace couchbase::core::timeout_defaults
|
@@ -29,9 +29,8 @@
|
|
29
29
|
namespace couchbase::core::topology
|
30
30
|
{
|
31
31
|
auto
|
32
|
-
configuration::node::port_or(service_type type,
|
33
|
-
|
34
|
-
std::uint16_t default_value) const -> std::uint16_t
|
32
|
+
configuration::node::port_or(service_type type, bool is_tls, std::uint16_t default_value) const
|
33
|
+
-> std::uint16_t
|
35
34
|
{
|
36
35
|
if (is_tls) {
|
37
36
|
switch (type) {
|
@@ -90,7 +89,7 @@ configuration::node::hostname_for(const std::string& network) const -> const std
|
|
90
89
|
}
|
91
90
|
const auto& address = alt.find(network);
|
92
91
|
if (address == alt.end()) {
|
93
|
-
|
92
|
+
CB_LOG_DEBUG(R"(requested network "{}" is not found, fallback to "default" host)", network);
|
94
93
|
return hostname;
|
95
94
|
}
|
96
95
|
return address->second.hostname;
|
@@ -107,10 +106,9 @@ configuration::node::port_or(const std::string& network,
|
|
107
106
|
}
|
108
107
|
const auto& address = alt.find(network);
|
109
108
|
if (address == alt.end()) {
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
type);
|
109
|
+
CB_LOG_DEBUG(R"(requested network "{}" is not found, fallback to "default" port of {} service)",
|
110
|
+
network,
|
111
|
+
type);
|
114
112
|
return port_or(type, is_tls, default_value);
|
115
113
|
}
|
116
114
|
if (is_tls) {
|
@@ -163,9 +161,8 @@ configuration::node::port_or(const std::string& network,
|
|
163
161
|
}
|
164
162
|
|
165
163
|
auto
|
166
|
-
configuration::node::endpoint(const std::string& network,
|
167
|
-
|
168
|
-
bool is_tls) const -> std::optional<std::string>
|
164
|
+
configuration::node::endpoint(const std::string& network, service_type type, bool is_tls) const
|
165
|
+
-> std::optional<std::string>
|
169
166
|
{
|
170
167
|
auto p = port_or(type, is_tls, 0);
|
171
168
|
if (p == 0) {
|
@@ -234,8 +231,8 @@ configuration::index_for_this_node() const -> std::size_t
|
|
234
231
|
}
|
235
232
|
|
236
233
|
auto
|
237
|
-
configuration::server_by_vbucket(std::uint16_t vbucket,
|
238
|
-
|
234
|
+
configuration::server_by_vbucket(std::uint16_t vbucket, std::size_t index) const
|
235
|
+
-> std::optional<std::size_t>
|
239
236
|
{
|
240
237
|
if (!vbmap.has_value() || vbucket >= vbmap->size()) {
|
241
238
|
return {};
|
@@ -61,6 +61,8 @@ struct configuration {
|
|
61
61
|
port_map services_tls{};
|
62
62
|
std::map<std::string, alternate_address> alt{};
|
63
63
|
std::string server_group{};
|
64
|
+
std::optional<std::string> app_telemetry_path{};
|
65
|
+
std::string node_uuid{};
|
64
66
|
|
65
67
|
auto operator!=(const node& other) const -> bool
|
66
68
|
{
|
@@ -69,9 +71,8 @@ struct configuration {
|
|
69
71
|
services_tls.key_value != other.services_tls.key_value;
|
70
72
|
}
|
71
73
|
|
72
|
-
[[nodiscard]] auto port_or(service_type type,
|
73
|
-
|
74
|
-
std::uint16_t default_value) const -> std::uint16_t;
|
74
|
+
[[nodiscard]] auto port_or(service_type type, bool is_tls, std::uint16_t default_value) const
|
75
|
+
-> std::uint16_t;
|
75
76
|
|
76
77
|
[[nodiscard]] auto port_or(const std::string& network,
|
77
78
|
service_type type,
|
@@ -80,9 +81,8 @@ struct configuration {
|
|
80
81
|
|
81
82
|
[[nodiscard]] auto hostname_for(const std::string& network) const -> const std::string&;
|
82
83
|
|
83
|
-
[[nodiscard]] auto endpoint(const std::string& network,
|
84
|
-
|
85
|
-
bool is_tls) const -> std::optional<std::string>;
|
84
|
+
[[nodiscard]] auto endpoint(const std::string& network, service_type type, bool is_tls) const
|
85
|
+
-> std::optional<std::string>;
|
86
86
|
};
|
87
87
|
|
88
88
|
[[nodiscard]] auto select_network(const std::string& bootstrap_hostname) const -> std::string;
|
@@ -128,13 +128,13 @@ struct configuration {
|
|
128
128
|
const std::string& hostname,
|
129
129
|
const std::string& port) const -> bool;
|
130
130
|
|
131
|
-
auto map_key(const std::string& key,
|
132
|
-
|
133
|
-
auto map_key(const std::vector<std::byte>& key,
|
134
|
-
|
131
|
+
auto map_key(const std::string& key, std::size_t index) const
|
132
|
+
-> std::pair<std::uint16_t, std::optional<std::size_t>>;
|
133
|
+
auto map_key(const std::vector<std::byte>& key, std::size_t index) const
|
134
|
+
-> std::pair<std::uint16_t, std::optional<std::size_t>>;
|
135
135
|
|
136
|
-
auto server_by_vbucket(std::uint16_t vbucket,
|
137
|
-
|
136
|
+
auto server_by_vbucket(std::uint16_t vbucket, std::size_t index) const
|
137
|
+
-> std::optional<std::size_t>;
|
138
138
|
};
|
139
139
|
|
140
140
|
using endpoint = std::pair<std::string, std::string>;
|
@@ -145,7 +145,6 @@ make_blank_configuration(const std::string& hostname,
|
|
145
145
|
std::uint16_t tls_port) -> configuration;
|
146
146
|
|
147
147
|
auto
|
148
|
-
make_blank_configuration(const std::vector<endpoint>& endpoints,
|
149
|
-
|
150
|
-
bool force = false) -> configuration;
|
148
|
+
make_blank_configuration(const std::vector<endpoint>& endpoints, bool use_tls, bool force = false)
|
149
|
+
-> configuration;
|
151
150
|
} // namespace couchbase::core::topology
|
@@ -61,6 +61,12 @@ struct traits<couchbase::core::topology::configuration> {
|
|
61
61
|
if (const auto& group = o.find("serverGroup"); group != o.end()) {
|
62
62
|
n.server_group = group->second.get_string();
|
63
63
|
}
|
64
|
+
if (const auto& path = o.find("appTelemetryPath"); path != o.end()) {
|
65
|
+
n.app_telemetry_path = path->second.get_string();
|
66
|
+
}
|
67
|
+
if (const auto& uuid = o.find("nodeUUID"); uuid != o.end()) {
|
68
|
+
n.node_uuid = uuid->second.get_string();
|
69
|
+
}
|
64
70
|
const auto& s = o.at("services");
|
65
71
|
n.services_plain.key_value = s.template optional<std::uint16_t>("kv");
|
66
72
|
n.services_plain.management = s.template optional<std::uint16_t>("mgmt");
|