couchbase 3.4.1 → 3.4.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/couchbase/CMakeLists.txt +2 -0
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +4 -0
- data/ext/couchbase/core/cluster_options.hxx +0 -1
- data/ext/couchbase/core/config_profile.cxx +23 -1
- data/ext/couchbase/core/config_profile.hxx +2 -12
- data/ext/couchbase/core/impl/analytics.cxx +236 -0
- data/ext/couchbase/core/impl/cluster.cxx +0 -1
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +5 -3
- data/ext/couchbase/core/impl/query.cxx +5 -5
- data/ext/couchbase/core/io/dns_client.cxx +225 -0
- data/ext/couchbase/core/io/dns_client.hxx +19 -188
- data/ext/couchbase/core/transactions/active_transaction_record.hxx +2 -2
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +3 -0
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +1 -1
- data/ext/couchbase/core/transactions/internal/transaction_context.hxx +12 -12
- data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +7 -1
- data/ext/couchbase/core/transactions/transaction_context.cxx +1 -0
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +144 -155
- data/ext/couchbase/core/utils/connection_string.cxx +10 -3
- data/ext/couchbase/core/utils/connection_string.hxx +3 -3
- data/ext/couchbase/couchbase/analytics_error_context.hxx +143 -0
- data/ext/couchbase/couchbase/analytics_meta_data.hxx +155 -0
- data/ext/couchbase/couchbase/analytics_metrics.hxx +163 -0
- data/ext/couchbase/couchbase/analytics_options.hxx +359 -0
- data/ext/couchbase/couchbase/analytics_result.hxx +102 -0
- data/ext/couchbase/couchbase/analytics_scan_consistency.hxx +46 -0
- data/ext/couchbase/couchbase/analytics_status.hxx +41 -0
- data/ext/couchbase/couchbase/analytics_warning.hxx +85 -0
- data/ext/couchbase/couchbase/cluster.hxx +33 -0
- data/ext/couchbase/couchbase/fmt/analytics_status.hxx +76 -0
- data/ext/couchbase/couchbase/query_options.hxx +0 -1
- data/ext/couchbase/couchbase/scope.hxx +33 -0
- data/ext/couchbase/couchbase/transactions/attempt_context.hxx +1 -1
- data/ext/couchbase/test/CMakeLists.txt +1 -2
- data/ext/couchbase/test/test_helper.hxx +1 -1
- data/ext/couchbase/test/test_integration_analytics.cxx +289 -13
- data/ext/couchbase/test/test_integration_crud.cxx +8 -1
- data/ext/couchbase/test/test_integration_examples.cxx +41 -0
- data/ext/couchbase/test/test_integration_management.cxx +15 -3
- data/ext/couchbase/test/test_integration_search.cxx +601 -0
- data/ext/couchbase/test/test_transaction_transaction_simple.cxx +73 -0
- data/ext/couchbase/test/test_unit_config_profiles.cxx +12 -12
- data/ext/couchbase/test/test_unit_connection_string.cxx +35 -0
- data/ext/couchbase/third_party/snappy/CMakeLists.txt +150 -27
- data/ext/couchbase/third_party/snappy/cmake/config.h.in +28 -24
- data/ext/couchbase/third_party/snappy/snappy-internal.h +189 -25
- data/ext/couchbase/third_party/snappy/snappy-sinksource.cc +26 -9
- data/ext/couchbase/third_party/snappy/snappy-sinksource.h +11 -11
- data/ext/couchbase/third_party/snappy/snappy-stubs-internal.cc +1 -1
- data/ext/couchbase/third_party/snappy/snappy-stubs-internal.h +227 -308
- data/ext/couchbase/third_party/snappy/snappy-stubs-public.h.in +0 -11
- data/ext/couchbase/third_party/snappy/snappy.cc +1176 -410
- data/ext/couchbase/third_party/snappy/snappy.h +19 -4
- data/ext/couchbase.cxx +27 -6
- data/ext/revisions.rb +3 -3
- data/lib/couchbase/cluster.rb +13 -9
- data/lib/couchbase/cluster_registry.rb +7 -2
- data/lib/couchbase/configuration.rb +3 -4
- data/lib/couchbase/options.rb +85 -2
- data/lib/couchbase/search_options.rb +158 -240
- data/lib/couchbase/version.rb +1 -1
- metadata +17 -6
- data/ext/couchbase/core/CMakeLists.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright 2020-
|
3
|
+
* Copyright 2020-Present Couchbase, Inc.
|
4
4
|
*
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
* you may not use this file except in compliance with the License.
|
@@ -17,207 +17,38 @@
|
|
17
17
|
|
18
18
|
#pragma once
|
19
19
|
|
20
|
-
#include "core/utils/
|
21
|
-
#include "dns_codec.hxx"
|
20
|
+
#include "core/utils/movable_function.hxx"
|
22
21
|
#include "dns_config.hxx"
|
23
22
|
|
24
|
-
#include <
|
23
|
+
#include <asio/io_context.hpp>
|
25
24
|
|
26
|
-
#include <
|
27
|
-
#include <
|
28
|
-
#include <
|
29
|
-
|
30
|
-
#include <memory>
|
31
|
-
#include <sstream>
|
25
|
+
#include <cinttypes>
|
26
|
+
#include <string>
|
27
|
+
#include <vector>
|
32
28
|
|
33
29
|
namespace couchbase::core::io::dns
|
34
30
|
{
|
31
|
+
struct dns_srv_response {
|
32
|
+
struct address {
|
33
|
+
std::string hostname;
|
34
|
+
std::uint16_t port;
|
35
|
+
};
|
36
|
+
std::error_code ec;
|
37
|
+
std::vector<address> targets{};
|
38
|
+
};
|
39
|
+
|
35
40
|
class dns_client
|
36
41
|
{
|
37
42
|
public:
|
38
|
-
struct dns_srv_response {
|
39
|
-
struct address {
|
40
|
-
std::string hostname;
|
41
|
-
std::uint16_t port;
|
42
|
-
};
|
43
|
-
std::error_code ec;
|
44
|
-
std::vector<address> targets{};
|
45
|
-
};
|
46
|
-
|
47
|
-
class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
|
48
|
-
{
|
49
|
-
public:
|
50
|
-
dns_srv_command(asio::io_context& ctx,
|
51
|
-
const std::string& name,
|
52
|
-
const std::string& service,
|
53
|
-
const asio::ip::address& address,
|
54
|
-
std::uint16_t port)
|
55
|
-
: deadline_(ctx)
|
56
|
-
, udp_(ctx)
|
57
|
-
, tcp_(ctx)
|
58
|
-
, address_(address)
|
59
|
-
, port_(port)
|
60
|
-
{
|
61
|
-
static std::string protocol{ "_tcp" };
|
62
|
-
dns_message request{};
|
63
|
-
question_record qr;
|
64
|
-
qr.klass = resource_class::in;
|
65
|
-
qr.type = resource_type::srv;
|
66
|
-
qr.name.labels.push_back(service);
|
67
|
-
qr.name.labels.push_back(protocol);
|
68
|
-
std::string label;
|
69
|
-
std::istringstream name_stream(name);
|
70
|
-
while (std::getline(name_stream, label, '.')) {
|
71
|
-
qr.name.labels.push_back(label);
|
72
|
-
}
|
73
|
-
request.questions.emplace_back(qr);
|
74
|
-
send_buf_ = dns_codec::encode(request);
|
75
|
-
}
|
76
|
-
|
77
|
-
template<class Handler>
|
78
|
-
void execute(std::chrono::milliseconds timeout, Handler&& handler)
|
79
|
-
{
|
80
|
-
asio::ip::udp::endpoint endpoint(address_, port_);
|
81
|
-
udp_.open(endpoint.protocol());
|
82
|
-
udp_.async_send_to(asio::buffer(send_buf_),
|
83
|
-
endpoint,
|
84
|
-
[self = shared_from_this(), handler = std::forward<Handler>(handler)](
|
85
|
-
std::error_code ec1, std::size_t /* bytes_transferred */) mutable {
|
86
|
-
if (ec1 == asio::error::operation_aborted) {
|
87
|
-
self->deadline_.cancel();
|
88
|
-
return handler({ errc::common::unambiguous_timeout });
|
89
|
-
}
|
90
|
-
if (ec1) {
|
91
|
-
self->deadline_.cancel();
|
92
|
-
return handler({ ec1 });
|
93
|
-
}
|
94
|
-
|
95
|
-
self->recv_buf_.resize(512);
|
96
|
-
self->udp_.async_receive_from(asio::buffer(self->recv_buf_),
|
97
|
-
self->udp_sender_,
|
98
|
-
[self, handler = std::forward<Handler>(handler)](
|
99
|
-
std::error_code ec2, std::size_t bytes_transferred) mutable {
|
100
|
-
self->deadline_.cancel();
|
101
|
-
if (ec2) {
|
102
|
-
return handler({ ec2 });
|
103
|
-
}
|
104
|
-
self->recv_buf_.resize(bytes_transferred);
|
105
|
-
dns_message message = dns_codec::decode(self->recv_buf_);
|
106
|
-
if (message.header.flags.tc == truncation::yes) {
|
107
|
-
self->udp_.close();
|
108
|
-
return self->retry_with_tcp(std::forward<Handler>(handler));
|
109
|
-
}
|
110
|
-
dns_srv_response resp{ ec2 };
|
111
|
-
resp.targets.reserve(message.answers.size());
|
112
|
-
for (const auto& answer : message.answers) {
|
113
|
-
resp.targets.emplace_back(dns_srv_response::address{
|
114
|
-
utils::join_strings(answer.target.labels, "."), answer.port });
|
115
|
-
}
|
116
|
-
return handler(std::move(resp));
|
117
|
-
});
|
118
|
-
});
|
119
|
-
deadline_.expires_after(timeout);
|
120
|
-
deadline_.async_wait([self = shared_from_this()](std::error_code ec) {
|
121
|
-
if (ec == asio::error::operation_aborted) {
|
122
|
-
return;
|
123
|
-
}
|
124
|
-
self->udp_.cancel();
|
125
|
-
if (self->tcp_.is_open()) {
|
126
|
-
self->tcp_.cancel();
|
127
|
-
}
|
128
|
-
});
|
129
|
-
}
|
130
|
-
|
131
|
-
private:
|
132
|
-
template<class Handler>
|
133
|
-
void retry_with_tcp(Handler&& handler)
|
134
|
-
{
|
135
|
-
asio::ip::tcp::no_delay no_delay(true);
|
136
|
-
std::error_code ignore_ec;
|
137
|
-
tcp_.set_option(no_delay, ignore_ec);
|
138
|
-
asio::ip::tcp::endpoint endpoint(address_, port_);
|
139
|
-
tcp_.async_connect(
|
140
|
-
endpoint, [self = shared_from_this(), handler = std::forward<Handler>(handler)](std::error_code ec1) mutable {
|
141
|
-
if (ec1) {
|
142
|
-
self->deadline_.cancel();
|
143
|
-
return handler({ ec1 });
|
144
|
-
}
|
145
|
-
auto send_size = static_cast<std::uint16_t>(self->send_buf_.size());
|
146
|
-
self->send_buf_.insert(self->send_buf_.begin(), std::uint8_t(send_size & 0xffU));
|
147
|
-
self->send_buf_.insert(self->send_buf_.begin(), std::uint8_t(send_size >> 8U));
|
148
|
-
asio::async_write(
|
149
|
-
self->tcp_,
|
150
|
-
asio::buffer(self->send_buf_),
|
151
|
-
[self, handler = std::forward<Handler>(handler)](std::error_code ec2, std::size_t /* bytes_transferred */) mutable {
|
152
|
-
if (ec2) {
|
153
|
-
self->deadline_.cancel();
|
154
|
-
if (ec2 == asio::error::operation_aborted) {
|
155
|
-
ec2 = errc::common::unambiguous_timeout;
|
156
|
-
}
|
157
|
-
return handler({ ec2 });
|
158
|
-
}
|
159
|
-
asio::async_read(self->tcp_,
|
160
|
-
asio::buffer(&self->recv_buf_size_, sizeof(std::uint16_t)),
|
161
|
-
[self, handler = std::forward<Handler>(handler)](std::error_code ec3,
|
162
|
-
std::size_t /* bytes_transferred */) mutable {
|
163
|
-
if (ec3) {
|
164
|
-
self->deadline_.cancel();
|
165
|
-
return handler({ ec3 });
|
166
|
-
}
|
167
|
-
self->recv_buf_size_ = utils::byte_swap(self->recv_buf_size_);
|
168
|
-
self->recv_buf_.resize(self->recv_buf_size_);
|
169
|
-
asio::async_read(self->tcp_,
|
170
|
-
asio::buffer(self->recv_buf_),
|
171
|
-
[self, handler = std::forward<Handler>(handler)](
|
172
|
-
std::error_code ec4, std::size_t bytes_transferred) mutable {
|
173
|
-
self->deadline_.cancel();
|
174
|
-
if (ec4) {
|
175
|
-
return handler({ ec4 });
|
176
|
-
}
|
177
|
-
self->recv_buf_.resize(bytes_transferred);
|
178
|
-
dns_message message = dns_codec::decode(self->recv_buf_);
|
179
|
-
dns_srv_response resp{ ec4 };
|
180
|
-
resp.targets.reserve(message.answers.size());
|
181
|
-
for (const auto& answer : message.answers) {
|
182
|
-
resp.targets.emplace_back(dns_srv_response::address{
|
183
|
-
utils::join_strings(answer.target.labels, "."), answer.port });
|
184
|
-
}
|
185
|
-
return handler(std::move(resp));
|
186
|
-
});
|
187
|
-
});
|
188
|
-
});
|
189
|
-
});
|
190
|
-
}
|
191
|
-
|
192
|
-
asio::steady_timer deadline_;
|
193
|
-
asio::ip::udp::socket udp_;
|
194
|
-
asio::ip::udp::endpoint udp_sender_{};
|
195
|
-
asio::ip::tcp::socket tcp_;
|
196
|
-
|
197
|
-
asio::ip::address address_;
|
198
|
-
std::uint16_t port_;
|
199
|
-
|
200
|
-
std::vector<std::uint8_t> send_buf_{};
|
201
|
-
std::uint16_t recv_buf_size_{ 0 };
|
202
|
-
std::vector<std::uint8_t> recv_buf_{};
|
203
|
-
};
|
204
|
-
|
205
43
|
explicit dns_client(asio::io_context& ctx)
|
206
44
|
: ctx_(ctx)
|
207
45
|
{
|
208
46
|
}
|
209
47
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
auto address = asio::ip::address::from_string(config.nameserver(), ec);
|
215
|
-
if (ec) {
|
216
|
-
return handler({ ec });
|
217
|
-
}
|
218
|
-
auto cmd = std::make_shared<dns_srv_command>(ctx_, name, service, address, config.port());
|
219
|
-
cmd->execute(config.timeout(), std::forward<Handler>(handler));
|
220
|
-
}
|
48
|
+
void query_srv(const std::string& name,
|
49
|
+
const std::string& service,
|
50
|
+
const dns_config& config,
|
51
|
+
utils::movable_function<void(couchbase::core::io::dns::dns_srv_response&& resp)>&& handler);
|
221
52
|
|
222
53
|
asio::io_context& ctx_;
|
223
54
|
};
|
@@ -153,7 +153,7 @@ class active_transaction_record
|
|
153
153
|
if (const auto* compat = val.find(ATR_FIELD_FORWARD_COMPAT); compat != nullptr) {
|
154
154
|
forward_compat = *compat;
|
155
155
|
}
|
156
|
-
|
156
|
+
std::optional<uint32_t> expires_after_msec = std::max(val.optional<int32_t>(ATR_FIELD_EXPIRES_AFTER_MSECS).value_or(0), 0);
|
157
157
|
entries.emplace_back(resp.ctx.bucket(),
|
158
158
|
resp.ctx.id(),
|
159
159
|
key,
|
@@ -163,7 +163,7 @@ class active_transaction_record
|
|
163
163
|
parse_mutation_cas(val.optional<std::string>(ATR_FIELD_TIMESTAMP_COMPLETE).value_or("")),
|
164
164
|
parse_mutation_cas(val.optional<std::string>(ATR_FIELD_TIMESTAMP_ROLLBACK_START).value_or("")),
|
165
165
|
parse_mutation_cas(val.optional<std::string>(ATR_FIELD_TIMESTAMP_ROLLBACK_COMPLETE).value_or("")),
|
166
|
-
|
166
|
+
expires_after_msec,
|
167
167
|
process_document_ids(val, ATR_FIELD_DOCS_INSERTED),
|
168
168
|
process_document_ids(val, ATR_FIELD_DOCS_REPLACED),
|
169
169
|
process_document_ids(val, ATR_FIELD_DOCS_REMOVED),
|
@@ -1147,6 +1147,9 @@ attempt_context_impl::get_with_query(const core::document_id& id, bool optional,
|
|
1147
1147
|
// make a transaction_get_result from the row...
|
1148
1148
|
try {
|
1149
1149
|
if (resp.rows.empty()) {
|
1150
|
+
if (optional) {
|
1151
|
+
return op_completed_with_callback(std::move(cb), std::optional<transaction_get_result>());
|
1152
|
+
}
|
1150
1153
|
return op_completed_with_error(
|
1151
1154
|
std::move(cb), transaction_operation_failed(FAIL_DOC_NOT_FOUND, "document not found"));
|
1152
1155
|
}
|
@@ -49,30 +49,29 @@ class transaction_context
|
|
49
49
|
|
50
50
|
[[nodiscard]] std::size_t num_attempts() const
|
51
51
|
{
|
52
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
52
53
|
return attempts_.size();
|
53
54
|
}
|
54
|
-
[[nodiscard]] const std::vector<transaction_attempt>& attempts() const
|
55
|
-
{
|
56
|
-
return attempts_;
|
57
|
-
}
|
58
|
-
[[nodiscard]] std::vector<transaction_attempt>& attempts()
|
59
|
-
{
|
60
|
-
return const_cast<std::vector<transaction_attempt>&>(const_cast<const transaction_context*>(this)->attempts());
|
61
|
-
}
|
62
55
|
[[nodiscard]] const transaction_attempt& current_attempt() const
|
63
56
|
{
|
57
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
64
58
|
if (attempts_.empty()) {
|
65
59
|
throw std::runtime_error("transaction context has no attempts yet");
|
66
60
|
}
|
67
61
|
return attempts_.back();
|
68
62
|
}
|
69
|
-
[[nodiscard]] transaction_attempt& current_attempt()
|
70
|
-
{
|
71
|
-
return const_cast<transaction_attempt&>(const_cast<const transaction_context*>(this)->current_attempt());
|
72
|
-
}
|
73
63
|
|
74
64
|
void add_attempt();
|
75
65
|
|
66
|
+
void current_attempt_state(attempt_state s)
|
67
|
+
{
|
68
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
69
|
+
if (attempts_.empty()) {
|
70
|
+
throw std::runtime_error("transaction_context has no attempts yet");
|
71
|
+
}
|
72
|
+
attempts_.back().state = s;
|
73
|
+
}
|
74
|
+
|
76
75
|
[[nodiscard]] std::shared_ptr<core::cluster> cluster_ref()
|
77
76
|
{
|
78
77
|
return transactions_.cluster_ref();
|
@@ -191,6 +190,7 @@ class transaction_context
|
|
191
190
|
std::string atr_collection_;
|
192
191
|
transactions_cleanup& cleanup_;
|
193
192
|
std::shared_ptr<attempt_context_impl> current_attempt_context_;
|
193
|
+
mutable std::mutex mutex_;
|
194
194
|
|
195
195
|
std::unique_ptr<exp_delay> delay_;
|
196
196
|
};
|
@@ -145,6 +145,12 @@ class transactions_cleanup
|
|
145
145
|
|
146
146
|
void attempts_loop();
|
147
147
|
|
148
|
+
bool is_running()
|
149
|
+
{
|
150
|
+
std::unique_lock<std::mutex> lock(mutex_);
|
151
|
+
return running_;
|
152
|
+
}
|
153
|
+
|
148
154
|
template<class R, class P>
|
149
155
|
bool interruptable_wait(std::chrono::duration<R, P> time);
|
150
156
|
|
@@ -153,7 +159,7 @@ class transactions_cleanup
|
|
153
159
|
void create_client_record(const couchbase::transactions::transaction_keyspace& keyspace);
|
154
160
|
const atr_cleanup_stats handle_atr_cleanup(const core::document_id& atr_id,
|
155
161
|
std::vector<transactions_cleanup_attempt>* result = nullptr);
|
156
|
-
|
162
|
+
bool running_{ false };
|
157
163
|
};
|
158
164
|
} // namespace transactions
|
159
165
|
} // namespace couchbase::core
|