couchbase 4.4.6 → 4.5.1
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.
- package/deps/couchbase-cxx-cache/mozilla-ca-bundle.crt +79 -165
- package/deps/couchbase-cxx-cache/mozilla-ca-bundle.sha256 +1 -1
- package/deps/couchbase-cxx-client/CMakeLists.txt +14 -3
- package/deps/couchbase-cxx-client/README.md +2 -2
- package/deps/couchbase-cxx-client/cmake/Profiler.cmake +15 -0
- package/deps/couchbase-cxx-client/core/app_telemetry_address.cxx +55 -0
- package/deps/couchbase-cxx-client/core/app_telemetry_address.hxx +39 -0
- package/deps/couchbase-cxx-client/core/app_telemetry_meter.cxx +791 -0
- package/deps/couchbase-cxx-client/core/app_telemetry_meter.hxx +200 -0
- package/deps/couchbase-cxx-client/core/app_telemetry_reporter.cxx +895 -0
- package/deps/couchbase-cxx-client/core/app_telemetry_reporter.hxx +59 -0
- package/deps/couchbase-cxx-client/core/bucket.cxx +77 -35
- package/deps/couchbase-cxx-client/core/bucket.hxx +17 -10
- package/deps/couchbase-cxx-client/core/cluster.cxx +56 -17
- package/deps/couchbase-cxx-client/core/cluster_credentials.cxx +27 -0
- package/deps/couchbase-cxx-client/core/cluster_credentials.hxx +36 -0
- package/deps/couchbase-cxx-client/core/cluster_options.hxx +13 -0
- package/deps/couchbase-cxx-client/core/collections_component.cxx +7 -5
- package/deps/couchbase-cxx-client/core/http_component.cxx +6 -0
- package/deps/couchbase-cxx-client/core/impl/bucket_manager.cxx +2 -0
- package/deps/couchbase-cxx-client/core/impl/cluster.cxx +10 -0
- package/deps/couchbase-cxx-client/core/impl/collection.cxx +2 -0
- package/deps/couchbase-cxx-client/core/impl/error.cxx +22 -6
- package/deps/couchbase-cxx-client/core/impl/error.hxx +1 -1
- package/deps/couchbase-cxx-client/core/impl/logger.cxx +51 -0
- package/deps/couchbase-cxx-client/core/impl/replica_utils.cxx +1 -1
- package/deps/couchbase-cxx-client/core/impl/transaction_get_multi_replicas_from_preferred_server_group_spec.cxx +32 -0
- package/deps/couchbase-cxx-client/core/impl/transaction_get_multi_spec.cxx +30 -0
- package/deps/couchbase-cxx-client/core/impl/transaction_op_error_category.cxx +2 -0
- package/deps/couchbase-cxx-client/core/io/config_tracker.cxx +6 -6
- package/deps/couchbase-cxx-client/core/io/http_command.hxx +35 -11
- package/deps/couchbase-cxx-client/core/io/http_session.cxx +10 -0
- package/deps/couchbase-cxx-client/core/io/http_session.hxx +4 -0
- package/deps/couchbase-cxx-client/core/io/http_session_manager.hxx +87 -35
- package/deps/couchbase-cxx-client/core/io/mcbp_command.hxx +41 -2
- package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +52 -19
- package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +3 -0
- package/deps/couchbase-cxx-client/core/logger/logger.cxx +46 -0
- package/deps/couchbase-cxx-client/core/logger/logger.hxx +41 -1
- package/deps/couchbase-cxx-client/core/management/bucket_settings.hxx +1 -0
- package/deps/couchbase-cxx-client/core/management/bucket_settings_json.hxx +4 -0
- package/deps/couchbase-cxx-client/core/meta/features.hxx +32 -0
- package/deps/couchbase-cxx-client/core/operations/document_analytics.cxx +9 -9
- package/deps/couchbase-cxx-client/core/operations/document_get_all_replicas.hxx +10 -2
- package/deps/couchbase-cxx-client/core/operations/document_lookup_in.cxx +4 -0
- package/deps/couchbase-cxx-client/core/operations/document_lookup_in_all_replicas.hxx +14 -2
- package/deps/couchbase-cxx-client/core/operations/document_lookup_in_any_replica.hxx +4 -0
- package/deps/couchbase-cxx-client/core/operations/document_mutate_in.cxx +4 -0
- package/deps/couchbase-cxx-client/core/operations/document_mutate_in.hxx +1 -0
- package/deps/couchbase-cxx-client/core/operations/document_query.cxx +12 -10
- package/deps/couchbase-cxx-client/core/operations/http_noop.cxx +1 -0
- package/deps/couchbase-cxx-client/core/operations/management/bucket_create.cxx +3 -0
- package/deps/couchbase-cxx-client/core/operations/management/bucket_update.cxx +3 -0
- package/deps/couchbase-cxx-client/core/operations/management/search_index_get_all.cxx +3 -2
- package/deps/couchbase-cxx-client/core/origin.cxx +25 -5
- package/deps/couchbase-cxx-client/core/origin.hxx +18 -24
- package/deps/couchbase-cxx-client/core/platform/random.cc +6 -3
- package/deps/couchbase-cxx-client/core/platform/random.h +2 -2
- package/deps/couchbase-cxx-client/core/protocol/cmd_mutate_in.hxx +9 -0
- package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +4 -0
- package/deps/couchbase-cxx-client/core/topology/configuration.cxx +10 -13
- package/deps/couchbase-cxx-client/core/topology/configuration.hxx +14 -15
- package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +6 -0
- package/deps/couchbase-cxx-client/core/transactions/async_attempt_context.hxx +22 -2
- package/deps/couchbase-cxx-client/core/transactions/attempt_context.hxx +25 -7
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +723 -245
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.hxx +91 -12
- package/deps/couchbase-cxx-client/core/transactions/exceptions.cxx +5 -0
- package/deps/couchbase-cxx-client/core/transactions/exceptions.hxx +20 -0
- package/deps/couchbase-cxx-client/core/transactions/exceptions_fmt.hxx +3 -0
- package/deps/couchbase-cxx-client/core/transactions/forward_compat.cxx +71 -6
- package/deps/couchbase-cxx-client/core/transactions/forward_compat.hxx +45 -59
- package/deps/couchbase-cxx-client/core/transactions/get_multi_orchestrator.cxx +616 -0
- package/deps/couchbase-cxx-client/core/transactions/get_multi_orchestrator.hxx +61 -0
- package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.cxx +8 -0
- package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.hxx +16 -5
- package/deps/couchbase-cxx-client/core/transactions/internal/exceptions_internal.hxx +12 -0
- package/deps/couchbase-cxx-client/core/transactions/internal/transaction_context.hxx +13 -0
- package/deps/couchbase-cxx-client/core/transactions/internal/transaction_fields.hxx +1 -0
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +277 -96
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +28 -76
- package/deps/couchbase-cxx-client/core/transactions/transaction_context.cxx +33 -0
- package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_mode.hxx +28 -0
- package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +27 -0
- package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +72 -0
- package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_result.hxx +67 -0
- package/deps/couchbase-cxx-client/core/transactions/transaction_links.hxx +10 -0
- package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +8 -3
- package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +7 -0
- package/deps/couchbase-cxx-client/core/utils/connection_string.hxx +1 -0
- package/deps/couchbase-cxx-client/core/utils/url_codec.cxx +26 -0
- package/deps/couchbase-cxx-client/core/utils/url_codec.hxx +11 -0
- package/deps/couchbase-cxx-client/core/websocket_codec.cxx +647 -0
- package/deps/couchbase-cxx-client/core/websocket_codec.hxx +77 -0
- package/deps/couchbase-cxx-client/couchbase/analytics_options.hxx +70 -6
- package/deps/couchbase-cxx-client/couchbase/application_telemetry_options.hxx +124 -0
- package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +9 -0
- package/deps/couchbase-cxx-client/couchbase/cluster_options.hxx +17 -0
- package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/logger.hxx +16 -0
- package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/query_options.hxx +70 -6
- package/deps/couchbase-cxx-client/couchbase/transactions/async_attempt_context.hxx +29 -5
- package/deps/couchbase-cxx-client/couchbase/transactions/attempt_context.hxx +24 -7
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_mode.hxx +47 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_options.hxx +44 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +46 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_options.hxx +48 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +112 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_spec.hxx +47 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_result.hxx +105 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_spec.hxx +45 -0
- package/dist/analyticsindexmanager.d.ts +1 -0
- package/dist/binarycollection.d.ts +1 -0
- package/dist/binding.d.ts +82 -38
- package/dist/binding.js +14 -7
- package/dist/bindingutilities.d.ts +16 -4
- package/dist/bindingutilities.js +233 -31
- package/dist/cluster.d.ts +39 -0
- package/dist/cluster.js +21 -3
- package/dist/collection.d.ts +20 -1
- package/dist/collection.js +13 -0
- package/dist/errorcontexts.d.ts +24 -0
- package/dist/errorcontexts.js +12 -6
- package/dist/generaltypes.d.ts +16 -0
- package/dist/generaltypes.js +18 -1
- package/dist/httpexecutor.d.ts +1 -2
- package/dist/httpexecutor.js +0 -9
- package/dist/streamablepromises.d.ts +25 -7
- package/dist/streamablepromises.js +32 -7
- package/dist/transactions.d.ts +239 -1
- package/dist/transactions.js +316 -2
- package/dist/transcoders.d.ts +1 -0
- package/dist/utilities.d.ts +1 -0
- package/package.json +24 -24
- package/src/connection.cpp +34 -4
- package/src/constants.cpp +124 -0
- package/src/jstocbpp_autogen.hpp +22 -8
- package/src/jstocbpp_transactions.hpp +76 -2
- package/src/transaction.cpp +101 -0
- package/src/transaction.hpp +5 -0
- package/tools/gen-bindings-js.js +2 -1
- package/tools/gen-bindings-json.py +28 -3
@@ -59,6 +59,10 @@ std::shared_ptr<spdlog::logger> file_logger{};
|
|
59
59
|
std::mutex file_logger_mutex;
|
60
60
|
std::atomic_int file_logger_version{ 0 };
|
61
61
|
|
62
|
+
std::shared_ptr<couchbase::core::logger::log_callback> log_callback{};
|
63
|
+
std::mutex log_callback_mutex;
|
64
|
+
std::atomic_int log_callback_version{ 0 };
|
65
|
+
|
62
66
|
auto
|
63
67
|
get_file_logger() -> std::shared_ptr<spdlog::logger>
|
64
68
|
{
|
@@ -72,6 +76,27 @@ get_file_logger() -> std::shared_ptr<spdlog::logger>
|
|
72
76
|
return logger;
|
73
77
|
}
|
74
78
|
|
79
|
+
auto
|
80
|
+
get_custom_callback() -> std::shared_ptr<couchbase::core::logger::log_callback>
|
81
|
+
{
|
82
|
+
thread_local std::shared_ptr<couchbase::core::logger::log_callback> callback{ nullptr };
|
83
|
+
thread_local int version{ -1 };
|
84
|
+
if (version != log_callback_version) {
|
85
|
+
const std::scoped_lock lock(log_callback_mutex);
|
86
|
+
callback = log_callback;
|
87
|
+
version = log_callback_version;
|
88
|
+
}
|
89
|
+
return callback;
|
90
|
+
}
|
91
|
+
|
92
|
+
void
|
93
|
+
update_callback_logger(const std::shared_ptr<couchbase::core::logger::log_callback>& new_callback)
|
94
|
+
{
|
95
|
+
const std::scoped_lock lock(log_callback_mutex);
|
96
|
+
log_callback = new_callback;
|
97
|
+
++log_callback_version;
|
98
|
+
}
|
99
|
+
|
75
100
|
void
|
76
101
|
update_file_logger(const std::shared_ptr<spdlog::logger>& new_logger)
|
77
102
|
{
|
@@ -181,6 +206,14 @@ log(const char* file, int line, const char* function, level lvl, std::string_vie
|
|
181
206
|
spdlog::source_loc{ file, line, function }, translate_level(lvl), msg);
|
182
207
|
}
|
183
208
|
}
|
209
|
+
|
210
|
+
void
|
211
|
+
log_custom_logger(const char* file, int line, const char* function, level lvl, std::string_view msg)
|
212
|
+
{
|
213
|
+
if (auto callback = get_custom_callback()) {
|
214
|
+
(*callback)(msg, lvl, { file, function, line });
|
215
|
+
}
|
216
|
+
}
|
184
217
|
} // namespace detail
|
185
218
|
|
186
219
|
void
|
@@ -396,6 +429,19 @@ create_console_logger()
|
|
396
429
|
update_file_logger(new_logger);
|
397
430
|
}
|
398
431
|
|
432
|
+
void
|
433
|
+
register_log_callback(log_callback callback)
|
434
|
+
{
|
435
|
+
auto new_callback = std::make_shared<log_callback>(std::move(callback));
|
436
|
+
update_callback_logger(new_callback);
|
437
|
+
}
|
438
|
+
|
439
|
+
void
|
440
|
+
unregister_log_callback()
|
441
|
+
{
|
442
|
+
update_callback_logger(nullptr);
|
443
|
+
}
|
444
|
+
|
399
445
|
void
|
400
446
|
register_spdlog_logger(const std::shared_ptr<spdlog::logger>& l)
|
401
447
|
{
|
@@ -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) {
|
@@ -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{};
|
@@ -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:
|
@@ -71,9 +71,10 @@ search_index_get_all_request::make_response(error_context::http&& ctx,
|
|
71
71
|
for (const auto& [name, index] : indexes->get_object()) {
|
72
72
|
response.indexes.emplace_back(index.as<couchbase::core::management::search::index>());
|
73
73
|
}
|
74
|
-
return response;
|
75
74
|
}
|
76
|
-
|
75
|
+
return response;
|
76
|
+
}
|
77
|
+
if (encoded.status_code == 404) {
|
77
78
|
tao::json::value payload{};
|
78
79
|
try {
|
79
80
|
payload = utils::json::parse(encoded.body.data());
|
@@ -25,6 +25,8 @@
|
|
25
25
|
#include <spdlog/fmt/bundled/core.h>
|
26
26
|
|
27
27
|
#include <tao/json.hpp>
|
28
|
+
|
29
|
+
#include <random>
|
28
30
|
#include <utility>
|
29
31
|
|
30
32
|
namespace tao::json
|
@@ -298,11 +300,6 @@ origin::to_json() const -> std::string
|
|
298
300
|
return tao::json::to_string(json);
|
299
301
|
}
|
300
302
|
|
301
|
-
auto
|
302
|
-
cluster_credentials::uses_certificate() const -> bool
|
303
|
-
{
|
304
|
-
return !certificate_path.empty();
|
305
|
-
}
|
306
303
|
} // namespace couchbase::core
|
307
304
|
|
308
305
|
couchbase::core::origin::origin(const couchbase::core::origin& other)
|
@@ -343,6 +340,7 @@ couchbase::core::origin::origin(couchbase::core::cluster_credentials auth,
|
|
343
340
|
const couchbase::core::utils::connection_string& connstr)
|
344
341
|
: options_(connstr.options)
|
345
342
|
, credentials_(std::move(auth))
|
343
|
+
, connection_string_(connstr.input)
|
346
344
|
{
|
347
345
|
nodes_.reserve(connstr.bootstrap_nodes.size());
|
348
346
|
for (const auto& node : connstr.bootstrap_nodes) {
|
@@ -350,6 +348,9 @@ couchbase::core::origin::origin(couchbase::core::cluster_credentials auth,
|
|
350
348
|
node.port > 0 ? std::to_string(node.port)
|
351
349
|
: std::to_string(connstr.default_port));
|
352
350
|
}
|
351
|
+
if (!options_.preserve_bootstrap_nodes_order) {
|
352
|
+
shuffle_nodes();
|
353
|
+
}
|
353
354
|
next_node_ = nodes_.begin();
|
354
355
|
}
|
355
356
|
auto
|
@@ -365,6 +366,11 @@ couchbase::core::origin::operator=(const couchbase::core::origin& other) -> couc
|
|
365
366
|
return *this;
|
366
367
|
}
|
367
368
|
auto
|
369
|
+
couchbase::core::origin::connection_string() const -> const std::string&
|
370
|
+
{
|
371
|
+
return connection_string_;
|
372
|
+
}
|
373
|
+
auto
|
368
374
|
couchbase::core::origin::username() const -> const std::string&
|
369
375
|
{
|
370
376
|
return credentials_.username;
|
@@ -404,10 +410,21 @@ couchbase::core::origin::get_nodes() const -> std::vector<std::string>
|
|
404
410
|
}
|
405
411
|
return res;
|
406
412
|
}
|
413
|
+
|
414
|
+
void
|
415
|
+
couchbase::core::origin::shuffle_nodes()
|
416
|
+
{
|
417
|
+
static thread_local std::default_random_engine gen{ std::random_device{}() };
|
418
|
+
std::shuffle(nodes_.begin(), nodes_.end(), gen);
|
419
|
+
}
|
420
|
+
|
407
421
|
void
|
408
422
|
couchbase::core::origin::set_nodes(couchbase::core::origin::node_list nodes)
|
409
423
|
{
|
410
424
|
nodes_ = std::move(nodes);
|
425
|
+
if (!options_.preserve_bootstrap_nodes_order) {
|
426
|
+
shuffle_nodes();
|
427
|
+
}
|
411
428
|
next_node_ = nodes_.begin();
|
412
429
|
exhausted_ = false;
|
413
430
|
}
|
@@ -433,6 +450,9 @@ couchbase::core::origin::set_nodes_from_config(const topology::configuration& co
|
|
433
450
|
std::make_pair(node.hostname_for(options_.network), std::to_string(port)));
|
434
451
|
}
|
435
452
|
}
|
453
|
+
if (!options_.preserve_bootstrap_nodes_order) {
|
454
|
+
shuffle_nodes();
|
455
|
+
}
|
436
456
|
next_node_ = nodes_.begin();
|
437
457
|
}
|
438
458
|
auto
|
@@ -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>;
|
@@ -64,29 +55,31 @@ struct origin {
|
|
64
55
|
const std::string& port,
|
65
56
|
cluster_options options);
|
66
57
|
origin(cluster_credentials auth, const utils::connection_string& connstr);
|
67
|
-
|
68
|
-
|
58
|
+
auto operator=(origin&& other) -> origin& = default;
|
59
|
+
auto operator=(const origin& other) -> origin&;
|
69
60
|
|
70
|
-
[[nodiscard]] const std::string
|
71
|
-
[[nodiscard]] const std::string
|
72
|
-
[[nodiscard]] const std::string
|
73
|
-
[[nodiscard]] const std::string
|
61
|
+
[[nodiscard]] auto connection_string() const -> const std::string&;
|
62
|
+
[[nodiscard]] auto username() const -> const std::string&;
|
63
|
+
[[nodiscard]] auto password() const -> const std::string&;
|
64
|
+
[[nodiscard]] auto certificate_path() const -> const std::string&;
|
65
|
+
[[nodiscard]] auto key_path() const -> const std::string&;
|
74
66
|
|
75
|
-
[[nodiscard]] std::vector<std::string
|
76
|
-
[[nodiscard]] std::vector<std::string
|
67
|
+
[[nodiscard]] auto get_hostnames() const -> std::vector<std::string>;
|
68
|
+
[[nodiscard]] auto get_nodes() const -> std::vector<std::string>;
|
77
69
|
|
70
|
+
void shuffle_nodes();
|
78
71
|
void set_nodes(node_list nodes);
|
79
72
|
void set_nodes_from_config(const topology::configuration& config);
|
80
73
|
|
81
|
-
[[nodiscard]] std::pair<std::string, std::string
|
74
|
+
[[nodiscard]] auto next_address() -> std::pair<std::string, std::string>;
|
82
75
|
|
83
|
-
[[nodiscard]]
|
76
|
+
[[nodiscard]] auto exhausted() const -> bool;
|
84
77
|
|
85
78
|
void restart();
|
86
79
|
|
87
|
-
[[nodiscard]] const couchbase::core::cluster_options
|
88
|
-
[[nodiscard]] couchbase::core::cluster_options
|
89
|
-
[[nodiscard]] const couchbase::core::cluster_credentials
|
80
|
+
[[nodiscard]] auto options() const -> const couchbase::core::cluster_options&;
|
81
|
+
[[nodiscard]] auto options() -> couchbase::core::cluster_options&;
|
82
|
+
[[nodiscard]] auto credentials() const -> const couchbase::core::cluster_credentials&;
|
90
83
|
[[nodiscard]] auto to_json() const -> std::string;
|
91
84
|
|
92
85
|
private:
|
@@ -95,6 +88,7 @@ private:
|
|
95
88
|
node_list nodes_{};
|
96
89
|
node_list::iterator next_node_{};
|
97
90
|
bool exhausted_{ false };
|
91
|
+
std::string connection_string_{};
|
98
92
|
};
|
99
93
|
|
100
94
|
} // namespace couchbase::core
|
@@ -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 */
|