couchbase 3.4.1 → 3.4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|