couchbase 3.1.0 → 3.1.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/build_version.hxx.in +1 -1
- data/ext/couchbase/cluster_options.hxx +1 -0
- data/ext/couchbase/couchbase.cxx +31 -0
- data/ext/couchbase/io/mcbp_session.hxx +3 -0
- data/ext/couchbase/operations/collection_create.hxx +11 -7
- data/ext/couchbase/operations/collection_drop.hxx +9 -5
- data/ext/couchbase/operations/document_decrement.hxx +4 -0
- data/ext/couchbase/operations/document_increment.hxx +4 -0
- data/ext/couchbase/operations/document_mutate_in.hxx +4 -0
- data/ext/couchbase/operations/document_query.hxx +8 -0
- data/ext/couchbase/operations/document_replace.hxx +4 -0
- data/ext/couchbase/operations/document_upsert.hxx +4 -0
- data/ext/couchbase/operations/scope_create.hxx +7 -6
- data/ext/couchbase/operations/scope_drop.hxx +7 -4
- data/ext/couchbase/protocol/client_opcode.hxx +5 -0
- data/ext/couchbase/protocol/cmd_decrement.hxx +18 -8
- data/ext/couchbase/protocol/cmd_hello.hxx +6 -1
- data/ext/couchbase/protocol/cmd_increment.hxx +18 -8
- data/ext/couchbase/protocol/cmd_mutate_in.hxx +17 -8
- data/ext/couchbase/protocol/cmd_replace.hxx +16 -7
- data/ext/couchbase/protocol/cmd_upsert.hxx +16 -7
- data/ext/couchbase/protocol/frame_info_id.hxx +1 -1
- data/ext/couchbase/utils/connection_string.hxx +9 -0
- data/ext/couchbase/version.hxx +1 -1
- data/lib/active_support/cache/couchbase_store.rb +1 -0
- data/lib/couchbase/options.rb +36 -0
- data/lib/couchbase/subdoc.rb +1 -1
- data/lib/couchbase/version.rb +8 -8
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24cc8f415bbff9e3e132ee47c16e04a2090c8a26cc9afbd21899263f735a10cd
|
4
|
+
data.tar.gz: 3e26641abb3b31354b496effc0002794c82af25a5626ccd784591f311c03c2c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f57fb43563e563c4d0ab75330108a199ec63c36794ceb3afe0b5702cf117a2350b3e9b02027ea1129de8a3e4cc464248284a8973d6c4d442ce8f83fc69d84b0
|
7
|
+
data.tar.gz: b020a7a1049d9d63d64684e83c82c7b8c8aae90a80188e79eb09850e6c7bad242ce4642be0051ed6355b3789c5bb7a0253523218b5917bb4f78e208b3edcd30e
|
data/README.md
CHANGED
data/ext/build_version.hxx.in
CHANGED
@@ -26,5 +26,5 @@ constexpr auto BACKEND_CXX_COMPILER = "@CMAKE_CXX_COMPILER_ID@ @CMAKE_CXX_COMPIL
|
|
26
26
|
constexpr auto BACKEND_C_COMPILER = "@CMAKE_C_COMPILER_ID@ @CMAKE_C_COMPILER_VERSION@";
|
27
27
|
constexpr auto BACKEND_SYSTEM = "@CMAKE_SYSTEM@";
|
28
28
|
constexpr auto BACKEND_SYSTEM_PROCESSOR = "@CMAKE_SYSTEM_PROCESSOR@";
|
29
|
-
constexpr auto BACKEND_GIT_REVISION = "
|
29
|
+
constexpr auto BACKEND_GIT_REVISION = "a79d098eb238b3883e49e1738c35167642e8834f";
|
30
30
|
} // namespace couchbase
|
@@ -42,6 +42,7 @@ struct cluster_options {
|
|
42
42
|
bool show_queries{ false };
|
43
43
|
bool enable_unordered_execution{ true };
|
44
44
|
bool enable_clustermap_notification{ true };
|
45
|
+
bool enable_compression{ true };
|
45
46
|
std::string network{ "auto" };
|
46
47
|
|
47
48
|
std::chrono::milliseconds tcp_keep_alive_interval = timeout_defaults::tcp_keep_alive_interval;
|
data/ext/couchbase/couchbase.cxx
CHANGED
@@ -2037,6 +2037,10 @@ cb_Backend_document_upsert(VALUE self, VALUE bucket, VALUE collection, VALUE id,
|
|
2037
2037
|
if (!NIL_P(expiry)) {
|
2038
2038
|
req.expiry = FIX2UINT(expiry);
|
2039
2039
|
}
|
2040
|
+
exc = cb_extract_option_bool(req.preserve_expiry, options, "preserve_expiry");
|
2041
|
+
if (!NIL_P(exc)) {
|
2042
|
+
break;
|
2043
|
+
}
|
2040
2044
|
|
2041
2045
|
auto barrier = std::make_shared<std::promise<couchbase::operations::upsert_response>>();
|
2042
2046
|
auto f = barrier->get_future();
|
@@ -2083,6 +2087,11 @@ cb_Backend_document_upsert_multi(VALUE self, VALUE id_content, VALUE options)
|
|
2083
2087
|
if (!NIL_P(exc)) {
|
2084
2088
|
break;
|
2085
2089
|
}
|
2090
|
+
bool preserve_expiry{ false };
|
2091
|
+
exc = cb_extract_option_bool(preserve_expiry, options, "preserve_expiry");
|
2092
|
+
if (!NIL_P(exc)) {
|
2093
|
+
break;
|
2094
|
+
}
|
2086
2095
|
|
2087
2096
|
std::vector<std::tuple<couchbase::document_id, std::string, std::uint32_t>> tuples{};
|
2088
2097
|
exc = cb_extract_array_of_id_content(tuples, id_content);
|
@@ -2105,6 +2114,7 @@ cb_Backend_document_upsert_multi(VALUE self, VALUE id_content, VALUE options)
|
|
2105
2114
|
if (!NIL_P(expiry)) {
|
2106
2115
|
req.expiry = FIX2UINT(expiry);
|
2107
2116
|
}
|
2117
|
+
req.preserve_expiry = preserve_expiry;
|
2108
2118
|
auto barrier = std::make_shared<std::promise<couchbase::operations::upsert_response>>();
|
2109
2119
|
backend->cluster->execute(req, [barrier](couchbase::operations::upsert_response&& resp) mutable { barrier->set_value(resp); });
|
2110
2120
|
barriers.emplace_back(barrier);
|
@@ -2276,6 +2286,10 @@ cb_Backend_document_replace(VALUE self, VALUE bucket, VALUE collection, VALUE id
|
|
2276
2286
|
if (!NIL_P(expiry)) {
|
2277
2287
|
req.expiry = FIX2UINT(expiry);
|
2278
2288
|
}
|
2289
|
+
exc = cb_extract_option_bool(req.preserve_expiry, options, "preserve_expiry");
|
2290
|
+
if (!NIL_P(exc)) {
|
2291
|
+
break;
|
2292
|
+
}
|
2279
2293
|
VALUE cas = Qnil;
|
2280
2294
|
exc = cb_extract_option_bignum(cas, options, "cas");
|
2281
2295
|
if (!NIL_P(exc)) {
|
@@ -2547,6 +2561,10 @@ cb_Backend_document_increment(VALUE self, VALUE bucket, VALUE collection, VALUE
|
|
2547
2561
|
if (!NIL_P(expiry)) {
|
2548
2562
|
req.expiry = FIX2UINT(expiry);
|
2549
2563
|
}
|
2564
|
+
exc = cb_extract_option_bool(req.preserve_expiry, options, "preserve_expiry");
|
2565
|
+
if (!NIL_P(exc)) {
|
2566
|
+
break;
|
2567
|
+
}
|
2550
2568
|
|
2551
2569
|
auto barrier = std::make_shared<std::promise<couchbase::operations::increment_response>>();
|
2552
2570
|
auto f = barrier->get_future();
|
@@ -2622,6 +2640,10 @@ cb_Backend_document_decrement(VALUE self, VALUE bucket, VALUE collection, VALUE
|
|
2622
2640
|
if (!NIL_P(expiry)) {
|
2623
2641
|
req.expiry = FIX2UINT(expiry);
|
2624
2642
|
}
|
2643
|
+
exc = cb_extract_option_bool(req.preserve_expiry, options, "preserve_expiry");
|
2644
|
+
if (!NIL_P(exc)) {
|
2645
|
+
break;
|
2646
|
+
}
|
2625
2647
|
|
2626
2648
|
auto barrier = std::make_shared<std::promise<couchbase::operations::decrement_response>>();
|
2627
2649
|
auto f = barrier->get_future();
|
@@ -2685,6 +2707,9 @@ cb_map_subdoc_opcode(couchbase::protocol::subdoc_opcode opcode)
|
|
2685
2707
|
case couchbase::protocol::subdoc_opcode::set_doc:
|
2686
2708
|
return rb_id2sym(rb_intern("set_doc"));
|
2687
2709
|
|
2710
|
+
case couchbase::protocol::subdoc_opcode::remove_doc:
|
2711
|
+
return rb_id2sym(rb_intern("remove_doc"));
|
2712
|
+
|
2688
2713
|
case couchbase::protocol::subdoc_opcode::replace_body_with_xattr:
|
2689
2714
|
return rb_id2sym(rb_intern("replace_body_with_xattr"));
|
2690
2715
|
}
|
@@ -2973,6 +2998,10 @@ cb_Backend_document_mutate_in(VALUE self, VALUE bucket, VALUE collection, VALUE
|
|
2973
2998
|
if (!NIL_P(expiry)) {
|
2974
2999
|
req.expiry = FIX2UINT(expiry);
|
2975
3000
|
}
|
3001
|
+
exc = cb_extract_option_bool(req.preserve_expiry, options, "preserve_expiry");
|
3002
|
+
if (!NIL_P(exc)) {
|
3003
|
+
break;
|
3004
|
+
}
|
2976
3005
|
exc = cb_extract_option_bool(req.access_deleted, options, "access_deleted");
|
2977
3006
|
if (!NIL_P(exc)) {
|
2978
3007
|
break;
|
@@ -3023,6 +3052,8 @@ cb_Backend_document_mutate_in(VALUE self, VALUE bucket, VALUE collection, VALUE
|
|
3023
3052
|
opcode = couchbase::protocol::subdoc_opcode::counter;
|
3024
3053
|
} else if (operation_id == rb_intern("set_doc")) {
|
3025
3054
|
opcode = couchbase::protocol::subdoc_opcode::set_doc;
|
3055
|
+
} else if (operation_id == rb_intern("remove_doc")) {
|
3056
|
+
opcode = couchbase::protocol::subdoc_opcode::remove_doc;
|
3026
3057
|
} else {
|
3027
3058
|
exc =
|
3028
3059
|
rb_exc_new_str(eInvalidArgument, rb_sprintf("unsupported operation for subdocument mutation: %+" PRIsVALUE, operation));
|
@@ -139,6 +139,9 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session>
|
|
139
139
|
if (session_->origin_.options().enable_clustermap_notification) {
|
140
140
|
hello_req.body().enable_clustermap_change_notification();
|
141
141
|
}
|
142
|
+
if (session_->origin_.options().enable_compression) {
|
143
|
+
hello_req.body().enable_compression();
|
144
|
+
}
|
142
145
|
hello_req.opaque(session_->next_opaque());
|
143
146
|
hello_req.body().user_agent(tao::json::to_string(user_agent));
|
144
147
|
spdlog::debug("{} user_agent={}, requested_features=[{}]",
|
@@ -60,27 +60,31 @@ struct collection_create_request {
|
|
60
60
|
};
|
61
61
|
|
62
62
|
collection_create_response
|
63
|
-
make_response(error_context::http&& ctx,
|
63
|
+
make_response(error_context::http&& ctx,
|
64
|
+
collection_create_request& /* request */,
|
65
|
+
collection_create_request::encoded_response_type&& encoded)
|
64
66
|
{
|
65
67
|
collection_create_response response{ ctx };
|
66
68
|
if (!response.ctx.ec) {
|
67
69
|
switch (encoded.status_code) {
|
68
|
-
case 400:
|
69
|
-
|
70
|
+
case 400: {
|
71
|
+
std::regex collection_exists("Collection with name .+ already exists");
|
72
|
+
if (std::regex_search(encoded.body, collection_exists)) {
|
70
73
|
response.ctx.ec = std::make_error_code(error::management_errc::collection_exists);
|
71
74
|
} else if (encoded.body.find("Not allowed on this version of cluster") != std::string::npos) {
|
72
75
|
response.ctx.ec = std::make_error_code(error::common_errc::feature_not_available);
|
73
76
|
} else {
|
74
77
|
response.ctx.ec = std::make_error_code(error::common_errc::invalid_argument);
|
75
78
|
}
|
76
|
-
|
77
|
-
case 404:
|
78
|
-
|
79
|
+
} break;
|
80
|
+
case 404: {
|
81
|
+
std::regex scope_not_found("Scope with name .+ is not found");
|
82
|
+
if (std::regex_search(encoded.body, scope_not_found)) {
|
79
83
|
response.ctx.ec = std::make_error_code(error::common_errc::scope_not_found);
|
80
84
|
} else {
|
81
85
|
response.ctx.ec = std::make_error_code(error::common_errc::bucket_not_found);
|
82
86
|
}
|
83
|
-
|
87
|
+
} break;
|
84
88
|
case 200: {
|
85
89
|
tao::json::value payload{};
|
86
90
|
try {
|
@@ -17,6 +17,8 @@
|
|
17
17
|
|
18
18
|
#pragma once
|
19
19
|
|
20
|
+
#include <regex>
|
21
|
+
|
20
22
|
#include <tao/json.hpp>
|
21
23
|
|
22
24
|
#include <version.hxx>
|
@@ -54,7 +56,7 @@ struct collection_drop_request {
|
|
54
56
|
};
|
55
57
|
|
56
58
|
collection_drop_response
|
57
|
-
make_response(error_context::http&& ctx, collection_drop_request
|
59
|
+
make_response(error_context::http&& ctx, collection_drop_request& /* request */, collection_drop_request::encoded_response_type&& encoded)
|
58
60
|
{
|
59
61
|
collection_drop_response response{ ctx };
|
60
62
|
if (!response.ctx.ec) {
|
@@ -62,15 +64,17 @@ make_response(error_context::http&& ctx, collection_drop_request&, collection_dr
|
|
62
64
|
case 400:
|
63
65
|
response.ctx.ec = std::make_error_code(error::common_errc::unsupported_operation);
|
64
66
|
break;
|
65
|
-
case 404:
|
66
|
-
|
67
|
+
case 404: {
|
68
|
+
std::regex scope_not_found("Scope with name .+ is not found");
|
69
|
+
std::regex collection_not_found("Collection with name .+ is not found");
|
70
|
+
if (std::regex_search(encoded.body, collection_not_found)) {
|
67
71
|
response.ctx.ec = std::make_error_code(error::common_errc::collection_not_found);
|
68
|
-
} else if (encoded.body
|
72
|
+
} else if (std::regex_search(encoded.body, scope_not_found)) {
|
69
73
|
response.ctx.ec = std::make_error_code(error::common_errc::scope_not_found);
|
70
74
|
} else {
|
71
75
|
response.ctx.ec = std::make_error_code(error::common_errc::bucket_not_found);
|
72
76
|
}
|
73
|
-
|
77
|
+
} break;
|
74
78
|
case 200: {
|
75
79
|
tao::json::value payload{};
|
76
80
|
try {
|
@@ -45,6 +45,7 @@ struct decrement_request {
|
|
45
45
|
std::optional<std::uint16_t> durability_timeout{};
|
46
46
|
std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
|
47
47
|
io::retry_context<io::retry_strategy::best_effort> retries{ false };
|
48
|
+
bool preserve_expiry{ false };
|
48
49
|
|
49
50
|
[[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
|
50
51
|
{
|
@@ -62,6 +63,9 @@ struct decrement_request {
|
|
62
63
|
if (durability_level != protocol::durability_level::none) {
|
63
64
|
encoded.body().durability(durability_level, durability_timeout);
|
64
65
|
}
|
66
|
+
if (preserve_expiry) {
|
67
|
+
encoded.body().preserve_expiry();
|
68
|
+
}
|
65
69
|
return {};
|
66
70
|
}
|
67
71
|
};
|
@@ -47,6 +47,7 @@ struct increment_request {
|
|
47
47
|
std::optional<std::uint16_t> durability_timeout{};
|
48
48
|
std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
|
49
49
|
io::retry_context<io::retry_strategy::best_effort> retries{ false };
|
50
|
+
bool preserve_expiry{ false };
|
50
51
|
|
51
52
|
[[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
|
52
53
|
{
|
@@ -64,6 +65,9 @@ struct increment_request {
|
|
64
65
|
if (durability_level != protocol::durability_level::none) {
|
65
66
|
encoded.body().durability(durability_level, durability_timeout);
|
66
67
|
}
|
68
|
+
if (preserve_expiry) {
|
69
|
+
encoded.body().preserve_expiry();
|
70
|
+
}
|
67
71
|
return {};
|
68
72
|
}
|
69
73
|
};
|
@@ -70,6 +70,7 @@ struct mutate_in_request {
|
|
70
70
|
std::optional<std::uint16_t> durability_timeout{};
|
71
71
|
std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
|
72
72
|
io::retry_context<io::retry_strategy::best_effort> retries{ false };
|
73
|
+
bool preserve_expiry{ false };
|
73
74
|
|
74
75
|
[[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&& ctx)
|
75
76
|
{
|
@@ -102,6 +103,9 @@ struct mutate_in_request {
|
|
102
103
|
if (durability_level != protocol::durability_level::none) {
|
103
104
|
encoded.body().durability(durability_level, durability_timeout);
|
104
105
|
}
|
106
|
+
if (preserve_expiry) {
|
107
|
+
encoded.body().preserve_expiry();
|
108
|
+
}
|
105
109
|
return {};
|
106
110
|
}
|
107
111
|
};
|
@@ -380,6 +380,7 @@ make_response(error_context::query&& ctx, query_request& request, query_request:
|
|
380
380
|
bool syntax_error = false;
|
381
381
|
bool server_timeout = false;
|
382
382
|
bool invalid_argument = false;
|
383
|
+
bool cas_mismatch = false;
|
383
384
|
|
384
385
|
if (response.payload.meta_data.errors) {
|
385
386
|
for (const auto& error : *response.payload.meta_data.errors) {
|
@@ -401,6 +402,11 @@ make_response(error_context::query&& ctx, query_request& request, query_request:
|
|
401
402
|
case 4090: /* IKey: "plan.build_prepared.name_not_in_encoded_plan" */
|
402
403
|
prepared_statement_failure = true;
|
403
404
|
break;
|
405
|
+
case 12009: /* IKey: "datastore.couchbase.DML_error" */
|
406
|
+
if (error.message.find("CAS mismatch") != std::string::npos) {
|
407
|
+
cas_mismatch = true;
|
408
|
+
}
|
409
|
+
break;
|
404
410
|
case 12004: /* IKey: "datastore.couchbase.primary_idx_not_found" */
|
405
411
|
case 12016: /* IKey: "datastore.couchbase.index_not_found" */
|
406
412
|
index_not_found = true;
|
@@ -429,6 +435,8 @@ make_response(error_context::query&& ctx, query_request& request, query_request:
|
|
429
435
|
response.ctx.ec = std::make_error_code(error::query_errc::planning_failure);
|
430
436
|
} else if (index_not_found) {
|
431
437
|
response.ctx.ec = std::make_error_code(error::common_errc::index_not_found);
|
438
|
+
} else if (cas_mismatch) {
|
439
|
+
response.ctx.ec = std::make_error_code(error::common_errc::cas_mismatch);
|
432
440
|
} else {
|
433
441
|
response.ctx.ec = std::make_error_code(error::common_errc::internal_server_failure);
|
434
442
|
}
|
@@ -46,6 +46,7 @@ struct replace_request {
|
|
46
46
|
std::optional<std::uint16_t> durability_timeout{};
|
47
47
|
std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
|
48
48
|
io::retry_context<io::retry_strategy::best_effort> retries{ false };
|
49
|
+
bool preserve_expiry{ false };
|
49
50
|
|
50
51
|
[[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
|
51
52
|
{
|
@@ -59,6 +60,9 @@ struct replace_request {
|
|
59
60
|
if (durability_level != protocol::durability_level::none) {
|
60
61
|
encoded.body().durability(durability_level, durability_timeout);
|
61
62
|
}
|
63
|
+
if (preserve_expiry) {
|
64
|
+
encoded.body().preserve_expiry();
|
65
|
+
}
|
62
66
|
return {};
|
63
67
|
}
|
64
68
|
};
|
@@ -45,6 +45,7 @@ struct upsert_request {
|
|
45
45
|
std::optional<std::uint16_t> durability_timeout{};
|
46
46
|
std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
|
47
47
|
io::retry_context<io::retry_strategy::best_effort> retries{ false };
|
48
|
+
bool preserve_expiry{ false };
|
48
49
|
|
49
50
|
[[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
|
50
51
|
{
|
@@ -57,6 +58,9 @@ struct upsert_request {
|
|
57
58
|
if (durability_level != protocol::durability_level::none) {
|
58
59
|
encoded.body().durability(durability_level, durability_timeout);
|
59
60
|
}
|
61
|
+
if (preserve_expiry) {
|
62
|
+
encoded.body().preserve_expiry();
|
63
|
+
}
|
60
64
|
return {};
|
61
65
|
}
|
62
66
|
};
|
@@ -17,6 +17,8 @@
|
|
17
17
|
|
18
18
|
#pragma once
|
19
19
|
|
20
|
+
#include <regex>
|
21
|
+
|
20
22
|
#include <tao/json.hpp>
|
21
23
|
|
22
24
|
#include <version.hxx>
|
@@ -55,22 +57,21 @@ struct scope_create_request {
|
|
55
57
|
};
|
56
58
|
|
57
59
|
scope_create_response
|
58
|
-
make_response(error_context::http&& ctx, scope_create_request
|
60
|
+
make_response(error_context::http&& ctx, scope_create_request& /* request */, scope_create_request::encoded_response_type&& encoded)
|
59
61
|
{
|
60
62
|
scope_create_response response{ ctx };
|
61
63
|
if (!response.ctx.ec) {
|
62
64
|
switch (encoded.status_code) {
|
63
|
-
case 400:
|
64
|
-
|
65
|
-
|
66
|
-
} else if (encoded.body.find("Scope with this name already exists") != std::string::npos) {
|
65
|
+
case 400: {
|
66
|
+
std::regex scope_exists("Scope with name .+ already exists");
|
67
|
+
if (std::regex_search(encoded.body, scope_exists)) {
|
67
68
|
response.ctx.ec = std::make_error_code(error::management_errc::scope_exists);
|
68
69
|
} else if (encoded.body.find("Not allowed on this version of cluster") != std::string::npos) {
|
69
70
|
response.ctx.ec = std::make_error_code(error::common_errc::feature_not_available);
|
70
71
|
} else {
|
71
72
|
response.ctx.ec = std::make_error_code(error::common_errc::invalid_argument);
|
72
73
|
}
|
73
|
-
|
74
|
+
} break;
|
74
75
|
case 404:
|
75
76
|
response.ctx.ec = std::make_error_code(error::common_errc::bucket_not_found);
|
76
77
|
break;
|
@@ -17,6 +17,8 @@
|
|
17
17
|
|
18
18
|
#pragma once
|
19
19
|
|
20
|
+
#include <regex>
|
21
|
+
|
20
22
|
#include <tao/json.hpp>
|
21
23
|
|
22
24
|
#include <version.hxx>
|
@@ -53,7 +55,7 @@ struct scope_drop_request {
|
|
53
55
|
};
|
54
56
|
|
55
57
|
scope_drop_response
|
56
|
-
make_response(error_context::http&& ctx, scope_drop_request
|
58
|
+
make_response(error_context::http&& ctx, scope_drop_request& /* request */, scope_drop_request::encoded_response_type&& encoded)
|
57
59
|
{
|
58
60
|
scope_drop_response response{ ctx };
|
59
61
|
if (!response.ctx.ec) {
|
@@ -61,13 +63,14 @@ make_response(error_context::http&& ctx, scope_drop_request&, scope_drop_request
|
|
61
63
|
case 400:
|
62
64
|
response.ctx.ec = std::make_error_code(error::common_errc::unsupported_operation);
|
63
65
|
break;
|
64
|
-
case 404:
|
65
|
-
|
66
|
+
case 404: {
|
67
|
+
std::regex scope_not_found("Scope with name .+ is not found");
|
68
|
+
if (std::regex_search(encoded.body, scope_not_found)) {
|
66
69
|
response.ctx.ec = std::make_error_code(error::common_errc::scope_not_found);
|
67
70
|
} else {
|
68
71
|
response.ctx.ec = std::make_error_code(error::common_errc::bucket_not_found);
|
69
72
|
}
|
70
|
-
|
73
|
+
} break;
|
71
74
|
case 200: {
|
72
75
|
tao::json::value payload{};
|
73
76
|
try {
|
@@ -233,6 +233,7 @@ enum class client_opcode : uint8_t {
|
|
233
233
|
enum class subdoc_opcode : uint8_t {
|
234
234
|
get_doc = 0x00,
|
235
235
|
set_doc = 0x01,
|
236
|
+
remove_doc = 0x04,
|
236
237
|
get = 0xc5,
|
237
238
|
exists = 0xc6,
|
238
239
|
dict_add = 0xc7,
|
@@ -345,6 +346,7 @@ is_valid_subdoc_opcode(uint8_t code)
|
|
345
346
|
case subdoc_opcode::get_count:
|
346
347
|
case subdoc_opcode::get_doc:
|
347
348
|
case subdoc_opcode::set_doc:
|
349
|
+
case subdoc_opcode::remove_doc:
|
348
350
|
case subdoc_opcode::replace_body_with_xattr:
|
349
351
|
return true;
|
350
352
|
}
|
@@ -626,6 +628,9 @@ struct fmt::formatter<couchbase::protocol::subdoc_opcode> : formatter<string_vie
|
|
626
628
|
case couchbase::protocol::subdoc_opcode::replace_body_with_xattr:
|
627
629
|
name = "replace_body_with_xattr (0xd3)";
|
628
630
|
break;
|
631
|
+
case couchbase::protocol::subdoc_opcode::remove_doc:
|
632
|
+
name = "remove_doc (0x04)";
|
633
|
+
break;
|
629
634
|
}
|
630
635
|
return formatter<string_view>::format(name, ctx);
|
631
636
|
}
|
@@ -48,7 +48,7 @@ class decrement_response_body
|
|
48
48
|
bool parse(protocol::status status,
|
49
49
|
const header_buffer& header,
|
50
50
|
std::uint8_t framing_extras_size,
|
51
|
-
std::uint16_t
|
51
|
+
std::uint16_t key_size,
|
52
52
|
std::uint8_t extras_size,
|
53
53
|
const std::vector<uint8_t>& body,
|
54
54
|
const cmd_info&)
|
@@ -66,6 +66,7 @@ class decrement_response_body
|
|
66
66
|
token_.sequence_number = utils::byte_swap_64(token_.sequence_number);
|
67
67
|
offset += 8;
|
68
68
|
}
|
69
|
+
offset += key_size;
|
69
70
|
memcpy(&content_, body.data() + offset, sizeof(content_));
|
70
71
|
content_ = utils::byte_swap_64(content_);
|
71
72
|
return true;
|
@@ -119,19 +120,28 @@ class decrement_request_body
|
|
119
120
|
return;
|
120
121
|
}
|
121
122
|
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::durability_requirement);
|
123
|
+
auto extras_size = framing_extras_.size();
|
122
124
|
if (timeout) {
|
123
|
-
framing_extras_.resize(4);
|
124
|
-
framing_extras_[0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
125
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
125
|
+
framing_extras_.resize(extras_size + 4);
|
126
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
127
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
126
128
|
uint16_t val = htons(*timeout);
|
127
|
-
memcpy(framing_extras_.data() + 2, &val, sizeof(val));
|
129
|
+
memcpy(framing_extras_.data() + extras_size + 2, &val, sizeof(val));
|
128
130
|
} else {
|
129
|
-
framing_extras_.resize(2);
|
130
|
-
framing_extras_[0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
131
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
131
|
+
framing_extras_.resize(extras_size + 2);
|
132
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
133
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
132
134
|
}
|
133
135
|
}
|
134
136
|
|
137
|
+
void preserve_expiry()
|
138
|
+
{
|
139
|
+
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::preserve_ttl);
|
140
|
+
auto extras_size = framing_extras_.size();
|
141
|
+
framing_extras_.resize(extras_size + 1);
|
142
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 0U);
|
143
|
+
}
|
144
|
+
|
135
145
|
const std::string& key()
|
136
146
|
{
|
137
147
|
return key_;
|
@@ -80,7 +80,6 @@ class hello_request_body
|
|
80
80
|
hello_feature::xattr,
|
81
81
|
hello_feature::xerror,
|
82
82
|
hello_feature::select_bucket,
|
83
|
-
hello_feature::snappy,
|
84
83
|
hello_feature::json,
|
85
84
|
hello_feature::duplex,
|
86
85
|
hello_feature::alt_request_support,
|
@@ -89,6 +88,7 @@ class hello_request_body
|
|
89
88
|
hello_feature::vattr,
|
90
89
|
hello_feature::collections,
|
91
90
|
hello_feature::subdoc_create_as_deleted,
|
91
|
+
hello_feature::preserve_ttl,
|
92
92
|
};
|
93
93
|
std::vector<std::uint8_t> value_;
|
94
94
|
|
@@ -113,6 +113,11 @@ class hello_request_body
|
|
113
113
|
features_.emplace_back(hello_feature::clustermap_change_notification);
|
114
114
|
}
|
115
115
|
|
116
|
+
void enable_compression()
|
117
|
+
{
|
118
|
+
features_.emplace_back(hello_feature::snappy);
|
119
|
+
}
|
120
|
+
|
116
121
|
[[nodiscard]] const std::vector<hello_feature>& features() const
|
117
122
|
{
|
118
123
|
return features_;
|
@@ -48,7 +48,7 @@ class increment_response_body
|
|
48
48
|
bool parse(protocol::status status,
|
49
49
|
const header_buffer& header,
|
50
50
|
std::uint8_t framing_extras_size,
|
51
|
-
std::uint16_t
|
51
|
+
std::uint16_t key_size,
|
52
52
|
std::uint8_t extras_size,
|
53
53
|
const std::vector<uint8_t>& body,
|
54
54
|
const cmd_info&)
|
@@ -66,6 +66,7 @@ class increment_response_body
|
|
66
66
|
token_.sequence_number = utils::byte_swap_64(token_.sequence_number);
|
67
67
|
offset += 8;
|
68
68
|
}
|
69
|
+
offset += key_size;
|
69
70
|
memcpy(&content_, body.data() + offset, sizeof(content_));
|
70
71
|
content_ = utils::byte_swap_64(content_);
|
71
72
|
return true;
|
@@ -119,19 +120,28 @@ class increment_request_body
|
|
119
120
|
return;
|
120
121
|
}
|
121
122
|
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::durability_requirement);
|
123
|
+
auto extras_size = framing_extras_.size();
|
122
124
|
if (timeout) {
|
123
|
-
framing_extras_.resize(4);
|
124
|
-
framing_extras_[0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
125
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
125
|
+
framing_extras_.resize(extras_size + 4);
|
126
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
127
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
126
128
|
uint16_t val = htons(*timeout);
|
127
|
-
memcpy(framing_extras_.data() + 2, &val, sizeof(val));
|
129
|
+
memcpy(framing_extras_.data() + extras_size + 2, &val, sizeof(val));
|
128
130
|
} else {
|
129
|
-
framing_extras_.resize(2);
|
130
|
-
framing_extras_[0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
131
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
131
|
+
framing_extras_.resize(extras_size + 2);
|
132
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
133
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
132
134
|
}
|
133
135
|
}
|
134
136
|
|
137
|
+
void preserve_expiry()
|
138
|
+
{
|
139
|
+
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::preserve_ttl);
|
140
|
+
auto extras_size = framing_extras_.size();
|
141
|
+
framing_extras_.resize(extras_size + 1);
|
142
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 0U);
|
143
|
+
}
|
144
|
+
|
135
145
|
const std::string& key()
|
136
146
|
{
|
137
147
|
return key_;
|
@@ -224,7 +224,7 @@ class mutate_in_request_body
|
|
224
224
|
|
225
225
|
void add_spec(subdoc_opcode operation, bool xattr, const std::string& path)
|
226
226
|
{
|
227
|
-
Expects(operation == protocol::subdoc_opcode::remove);
|
227
|
+
Expects(operation == protocol::subdoc_opcode::remove || operation == protocol::subdoc_opcode::remove_doc);
|
228
228
|
add_spec(static_cast<std::uint8_t>(operation), build_path_flags(xattr, false, false), path, "");
|
229
229
|
}
|
230
230
|
|
@@ -305,19 +305,28 @@ class mutate_in_request_body
|
|
305
305
|
return;
|
306
306
|
}
|
307
307
|
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::durability_requirement);
|
308
|
+
auto extras_size = framing_extras_.size();
|
308
309
|
if (timeout) {
|
309
|
-
framing_extras_.resize(4);
|
310
|
-
framing_extras_[0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
311
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
310
|
+
framing_extras_.resize(extras_size + 4);
|
311
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
312
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
312
313
|
uint16_t val = htons(*timeout);
|
313
|
-
memcpy(framing_extras_.data() + 2, &val, sizeof(val));
|
314
|
+
memcpy(framing_extras_.data() + extras_size + 2, &val, sizeof(val));
|
314
315
|
} else {
|
315
|
-
framing_extras_.resize(2);
|
316
|
-
framing_extras_[0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
317
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
316
|
+
framing_extras_.resize(extras_size + 2);
|
317
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
318
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
318
319
|
}
|
319
320
|
}
|
320
321
|
|
322
|
+
void preserve_expiry()
|
323
|
+
{
|
324
|
+
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::preserve_ttl);
|
325
|
+
auto extras_size = framing_extras_.size();
|
326
|
+
framing_extras_.resize(extras_size + 1);
|
327
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 0U);
|
328
|
+
}
|
329
|
+
|
321
330
|
const std::string& key()
|
322
331
|
{
|
323
332
|
return key_;
|
@@ -97,19 +97,28 @@ class replace_request_body
|
|
97
97
|
return;
|
98
98
|
}
|
99
99
|
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::durability_requirement);
|
100
|
+
auto extras_size = framing_extras_.size();
|
100
101
|
if (timeout) {
|
101
|
-
framing_extras_.resize(4);
|
102
|
-
framing_extras_[0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
103
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
102
|
+
framing_extras_.resize(extras_size + 4);
|
103
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
104
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
104
105
|
uint16_t val = htons(*timeout);
|
105
|
-
memcpy(framing_extras_.data() + 2, &val, sizeof(val));
|
106
|
+
memcpy(framing_extras_.data() + extras_size + 2, &val, sizeof(val));
|
106
107
|
} else {
|
107
|
-
framing_extras_.resize(2);
|
108
|
-
framing_extras_[0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
109
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
108
|
+
framing_extras_.resize(extras_size + 2);
|
109
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
110
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
110
111
|
}
|
111
112
|
}
|
112
113
|
|
114
|
+
void preserve_expiry()
|
115
|
+
{
|
116
|
+
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::preserve_ttl);
|
117
|
+
auto extras_size = framing_extras_.size();
|
118
|
+
framing_extras_.resize(extras_size + 1);
|
119
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 0U);
|
120
|
+
}
|
121
|
+
|
113
122
|
void content(const std::string& content)
|
114
123
|
{
|
115
124
|
content_ = { content.begin(), content.end() };
|
@@ -97,19 +97,28 @@ class upsert_request_body
|
|
97
97
|
return;
|
98
98
|
}
|
99
99
|
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::durability_requirement);
|
100
|
+
auto extras_size = framing_extras_.size();
|
100
101
|
if (timeout) {
|
101
|
-
framing_extras_.resize(4);
|
102
|
-
framing_extras_[0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
103
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
102
|
+
framing_extras_.resize(extras_size + 4);
|
103
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>((static_cast<std::uint32_t>(frame_id) << 4U) | 3U);
|
104
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
104
105
|
uint16_t val = htons(*timeout);
|
105
|
-
memcpy(framing_extras_.data() + 2, &val, sizeof(val));
|
106
|
+
memcpy(framing_extras_.data() + extras_size + 2, &val, sizeof(val));
|
106
107
|
} else {
|
107
|
-
framing_extras_.resize(2);
|
108
|
-
framing_extras_[0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
109
|
-
framing_extras_[1] = static_cast<std::uint8_t>(level);
|
108
|
+
framing_extras_.resize(extras_size + 2);
|
109
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 1U);
|
110
|
+
framing_extras_[extras_size + 1] = static_cast<std::uint8_t>(level);
|
110
111
|
}
|
111
112
|
}
|
112
113
|
|
114
|
+
void preserve_expiry()
|
115
|
+
{
|
116
|
+
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::preserve_ttl);
|
117
|
+
auto extras_size = framing_extras_.size();
|
118
|
+
framing_extras_.resize(extras_size + 1);
|
119
|
+
framing_extras_[extras_size + 0] = static_cast<std::uint8_t>(static_cast<std::uint32_t>(frame_id) << 4U | 0U);
|
120
|
+
}
|
121
|
+
|
113
122
|
void content(const std::string& content)
|
114
123
|
{
|
115
124
|
content_ = { content.begin(), content.end() };
|
@@ -90,7 +90,7 @@ enum class request_frame_info_id : uint8_t {
|
|
90
90
|
* If the request modifies an existing document the expiry time from the existing document should be used instead of the TTL provided.
|
91
91
|
* If document don't exist the provided TTL should be used. The frame info contains no value (length = 0).
|
92
92
|
*/
|
93
|
-
preserve_ttl =
|
93
|
+
preserve_ttl = 0x05,
|
94
94
|
};
|
95
95
|
|
96
96
|
constexpr inline bool
|
@@ -348,6 +348,15 @@ extract_options(connection_string& connstr)
|
|
348
348
|
} else if (param.second == "false" || param.second == "no" || param.second == "off") {
|
349
349
|
connstr.options.enable_unordered_execution = false;
|
350
350
|
}
|
351
|
+
} else if (param.first == "enable_compression") {
|
352
|
+
/**
|
353
|
+
* Announce support of compression (snappy) to server
|
354
|
+
*/
|
355
|
+
if (param.second == "true" || param.second == "yes" || param.second == "on") {
|
356
|
+
connstr.options.enable_compression = true;
|
357
|
+
} else if (param.second == "false" || param.second == "no" || param.second == "off") {
|
358
|
+
connstr.options.enable_compression = false;
|
359
|
+
}
|
351
360
|
} else {
|
352
361
|
spdlog::warn(R"(unknown parameter "{}" in connection string (value "{}"))", param.first, param.second);
|
353
362
|
}
|
data/ext/couchbase/version.hxx
CHANGED
data/lib/couchbase/options.rb
CHANGED
@@ -507,10 +507,13 @@ module Couchbase
|
|
507
507
|
attr_accessor :expiry # @return [Integer, #in_seconds, nil]
|
508
508
|
attr_accessor :transcoder # @return [JsonTranscoder, #encode(Object)]
|
509
509
|
attr_accessor :durability_level # @return [Symbol]
|
510
|
+
attr_accessor :preserve_expiry # @return [Boolean]
|
510
511
|
|
511
512
|
# Creates an instance of options for {Collection#upsert}
|
512
513
|
#
|
513
514
|
# @param [Integer, #in_seconds, Time, nil] expiry expiration time to associate with the document
|
515
|
+
# @param [Boolean] preserve_expiry if true and the document exists, the server will preserve current expiration
|
516
|
+
# for the document, otherwise will use {expiry} from the operation.
|
514
517
|
# @param [JsonTranscoder, #encode(Object)] transcoder used for encoding
|
515
518
|
# @param [Symbol] durability_level level of durability
|
516
519
|
# +:none+::
|
@@ -533,6 +536,7 @@ module Couchbase
|
|
533
536
|
#
|
534
537
|
# @yieldparam [Upsert]
|
535
538
|
def initialize(expiry: nil,
|
539
|
+
preserve_expiry: false,
|
536
540
|
transcoder: JsonTranscoder.new,
|
537
541
|
durability_level: :none,
|
538
542
|
timeout: nil,
|
@@ -541,6 +545,7 @@ module Couchbase
|
|
541
545
|
parent_span: nil)
|
542
546
|
super(timeout: timeout, retry_strategy: retry_strategy, client_context: client_context, parent_span: parent_span)
|
543
547
|
@expiry = Utils::Time.extract_expiry_time(expiry)
|
548
|
+
@preserve_expiry = preserve_expiry
|
544
549
|
@transcoder = transcoder
|
545
550
|
@durability_level = durability_level
|
546
551
|
yield self if block_given?
|
@@ -550,6 +555,7 @@ module Couchbase
|
|
550
555
|
{
|
551
556
|
timeout: @timeout.respond_to?(:in_milliseconds) ? @timeout.public_send(:in_milliseconds) : @timeout,
|
552
557
|
expiry: @expiry,
|
558
|
+
preserve_expiry: @preserve_expiry,
|
553
559
|
durability_level: @durability_level,
|
554
560
|
}
|
555
561
|
end
|
@@ -560,10 +566,13 @@ module Couchbase
|
|
560
566
|
attr_accessor :expiry # @return [Integer, #in_seconds, nil]
|
561
567
|
attr_accessor :transcoder # @return [JsonTranscoder, #encode(Object)]
|
562
568
|
attr_accessor :durability_level # @return [Symbol]
|
569
|
+
attr_accessor :preserve_expiry # @return [Boolean]
|
563
570
|
|
564
571
|
# Creates an instance of options for {Collection#upsert}
|
565
572
|
#
|
566
573
|
# @param [Integer, #in_seconds, Time, nil] expiry expiration time to associate with the document
|
574
|
+
# @param [Boolean] preserve_expiry if true and the document exists, the server will preserve current expiration
|
575
|
+
# for the document, otherwise will use {expiry} from the operation.
|
567
576
|
# @param [JsonTranscoder, #encode(Object)] transcoder used for encoding
|
568
577
|
# @param [Symbol] durability_level level of durability
|
569
578
|
# +:none+::
|
@@ -586,6 +595,7 @@ module Couchbase
|
|
586
595
|
#
|
587
596
|
# @yieldparam [Upsert]
|
588
597
|
def initialize(expiry: nil,
|
598
|
+
preserve_expiry: false,
|
589
599
|
transcoder: JsonTranscoder.new,
|
590
600
|
durability_level: :none,
|
591
601
|
timeout: nil,
|
@@ -594,6 +604,7 @@ module Couchbase
|
|
594
604
|
parent_span: nil)
|
595
605
|
super(timeout: timeout, retry_strategy: retry_strategy, client_context: client_context, parent_span: parent_span)
|
596
606
|
@expiry = Utils::Time.extract_expiry_time(expiry)
|
607
|
+
@preserve_expiry = preserve_expiry
|
597
608
|
@transcoder = transcoder
|
598
609
|
@durability_level = durability_level
|
599
610
|
yield self if block_given?
|
@@ -603,6 +614,7 @@ module Couchbase
|
|
603
614
|
{
|
604
615
|
timeout: @timeout.respond_to?(:in_milliseconds) ? @timeout.public_send(:in_milliseconds) : @timeout,
|
605
616
|
expiry: @expiry,
|
617
|
+
preserve_expiry: @preserve_expiry,
|
606
618
|
durability_level: @durability_level,
|
607
619
|
}
|
608
620
|
end
|
@@ -614,10 +626,13 @@ module Couchbase
|
|
614
626
|
attr_accessor :transcoder # @return [JsonTranscoder, #encode(Object)]
|
615
627
|
attr_accessor :cas # @return [Integer, nil]
|
616
628
|
attr_accessor :durability_level # @return [Symbol]
|
629
|
+
attr_accessor :preserve_expiry # @return [Boolean]
|
617
630
|
|
618
631
|
# Creates an instance of options for {Collection#replace}
|
619
632
|
#
|
620
633
|
# @param [Integer, #in_seconds, nil] expiry expiration time to associate with the document
|
634
|
+
# @param [Boolean] preserve_expiry if true and the document exists, the server will preserve current expiration
|
635
|
+
# for the document, otherwise will use {expiry} from the operation.
|
621
636
|
# @param [JsonTranscoder, #encode(Object)] transcoder used for encoding
|
622
637
|
# @param [Integer, nil] cas a CAS value that will be taken into account on the server side for optimistic concurrency
|
623
638
|
# @param [Symbol] durability_level level of durability
|
@@ -641,6 +656,7 @@ module Couchbase
|
|
641
656
|
#
|
642
657
|
# @yieldparam [Replace]
|
643
658
|
def initialize(expiry: nil,
|
659
|
+
preserve_expiry: false,
|
644
660
|
transcoder: JsonTranscoder.new,
|
645
661
|
cas: nil,
|
646
662
|
durability_level: :none,
|
@@ -650,6 +666,7 @@ module Couchbase
|
|
650
666
|
parent_span: nil)
|
651
667
|
super(timeout: timeout, retry_strategy: retry_strategy, client_context: client_context, parent_span: parent_span)
|
652
668
|
@expiry = Utils::Time.extract_expiry_time(expiry)
|
669
|
+
@preserve_expiry = preserve_expiry
|
653
670
|
@transcoder = transcoder
|
654
671
|
@cas = cas
|
655
672
|
@durability_level = durability_level
|
@@ -660,6 +677,7 @@ module Couchbase
|
|
660
677
|
{
|
661
678
|
timeout: @timeout.respond_to?(:in_milliseconds) ? @timeout.public_send(:in_milliseconds) : @timeout,
|
662
679
|
expiry: @expiry,
|
680
|
+
preserve_expiry: @preserve_expiry,
|
663
681
|
durability_level: @durability_level,
|
664
682
|
cas: @cas,
|
665
683
|
}
|
@@ -673,10 +691,13 @@ module Couchbase
|
|
673
691
|
attr_accessor :cas # @return [Integer, nil]
|
674
692
|
attr_accessor :durability_level # @return [Symbol]
|
675
693
|
attr_accessor :transcoder # @return [JsonTranscoder, #encode(Object)]
|
694
|
+
attr_accessor :preserve_expiry # @return [Boolean]
|
676
695
|
|
677
696
|
# Creates an instance of options for {Collection#mutate_in}
|
678
697
|
#
|
679
698
|
# @param [Integer, #in_seconds, Time, nil] expiry expiration time to associate with the document
|
699
|
+
# @param [Boolean] preserve_expiry if true and the document exists, the server will preserve current expiration
|
700
|
+
# for the document, otherwise will use {expiry} from the operation.
|
680
701
|
# @param [Symbol] store_semantics describes how the outer document store semantics on subdoc should act
|
681
702
|
# +:replace+:: replace the document, fail if it does not exist. This is the default
|
682
703
|
# +:upsert+:: replace the document or create if it does not exist
|
@@ -706,6 +727,7 @@ module Couchbase
|
|
706
727
|
#
|
707
728
|
# @yieldparam [MutateIn]
|
708
729
|
def initialize(expiry: nil,
|
730
|
+
preserve_expiry: false,
|
709
731
|
store_semantics: :replace,
|
710
732
|
cas: nil,
|
711
733
|
access_deleted: false,
|
@@ -718,6 +740,7 @@ module Couchbase
|
|
718
740
|
parent_span: nil)
|
719
741
|
super(timeout: timeout, retry_strategy: retry_strategy, client_context: client_context, parent_span: parent_span)
|
720
742
|
@expiry = Utils::Time.extract_expiry_time(expiry)
|
743
|
+
@preserve_expiry = preserve_expiry
|
721
744
|
@store_semantics = store_semantics
|
722
745
|
@cas = cas
|
723
746
|
@access_deleted = access_deleted
|
@@ -732,6 +755,7 @@ module Couchbase
|
|
732
755
|
{
|
733
756
|
timeout: @timeout.respond_to?(:in_milliseconds) ? @timeout.public_send(:in_milliseconds) : @timeout,
|
734
757
|
expiry: @expiry,
|
758
|
+
preserve_expiry: @preserve_expiry,
|
735
759
|
durability_level: @durability_level,
|
736
760
|
cas: @cas,
|
737
761
|
store_semantics: @store_semantics,
|
@@ -862,12 +886,15 @@ module Couchbase
|
|
862
886
|
attr_accessor :initial # @return [Integer]
|
863
887
|
attr_accessor :expiry # @return [Integer, #in_seconds]
|
864
888
|
attr_accessor :durability_level # @return [Symbol]
|
889
|
+
attr_accessor :preserve_expiry # @return [Boolean]
|
865
890
|
|
866
891
|
# Creates an instance of options for {BinaryCollection#increment}
|
867
892
|
#
|
868
893
|
# @param [Integer] delta the delta for the operation
|
869
894
|
# @param [Integer] initial if present, holds the initial value
|
870
895
|
# @param [Integer, #in_seconds, Time, nil] expiry if set, holds the expiration for the operation
|
896
|
+
# @param [Boolean] preserve_expiry if true and the document exists, the server will preserve current expiration
|
897
|
+
# for the document, otherwise will use {expiry} from the operation.
|
871
898
|
# @param [Symbol] durability_level level of durability
|
872
899
|
# +:none+::
|
873
900
|
# no enhanced durability required for the mutation
|
@@ -891,6 +918,7 @@ module Couchbase
|
|
891
918
|
def initialize(delta: 1,
|
892
919
|
initial: nil,
|
893
920
|
expiry: nil,
|
921
|
+
preserve_expiry: false,
|
894
922
|
durability_level: :none,
|
895
923
|
timeout: nil,
|
896
924
|
retry_strategy: nil,
|
@@ -902,6 +930,7 @@ module Couchbase
|
|
902
930
|
@delta = delta
|
903
931
|
@initial = initial
|
904
932
|
@expiry = Utils::Time.extract_expiry_time(expiry)
|
933
|
+
@preserve_expiry = preserve_expiry
|
905
934
|
@durability_level = durability_level
|
906
935
|
yield self if block_given?
|
907
936
|
end
|
@@ -920,6 +949,7 @@ module Couchbase
|
|
920
949
|
delta: @delta,
|
921
950
|
initial_value: @initial,
|
922
951
|
expiry: @expiry,
|
952
|
+
preserve_expiry: @preserve_expiry,
|
923
953
|
durability_level: @durability_level,
|
924
954
|
}
|
925
955
|
end
|
@@ -931,12 +961,15 @@ module Couchbase
|
|
931
961
|
attr_accessor :initial # @return [Integer]
|
932
962
|
attr_accessor :expiry # @return [Integer, #in_seconds]
|
933
963
|
attr_accessor :durability_level # @return [Symbol]
|
964
|
+
attr_accessor :preserve_expiry # @return [Boolean]
|
934
965
|
|
935
966
|
# Creates an instance of options for {BinaryCollection#decrement}
|
936
967
|
#
|
937
968
|
# @param [Integer] delta the delta for the operation
|
938
969
|
# @param [Integer] initial if present, holds the initial value
|
939
970
|
# @param [Integer, #in_seconds, Time, nil] expiry if set, holds the expiration for the operation
|
971
|
+
# @param [Boolean] preserve_expiry if true and the document exists, the server will preserve current expiration
|
972
|
+
# for the document, otherwise will use {expiry} from the operation.
|
940
973
|
# @param [Symbol] durability_level level of durability
|
941
974
|
# +:none+::
|
942
975
|
# no enhanced durability required for the mutation
|
@@ -960,6 +993,7 @@ module Couchbase
|
|
960
993
|
def initialize(delta: 1,
|
961
994
|
initial: nil,
|
962
995
|
expiry: nil,
|
996
|
+
preserve_expiry: false,
|
963
997
|
durability_level: :none,
|
964
998
|
timeout: nil,
|
965
999
|
retry_strategy: nil,
|
@@ -971,6 +1005,7 @@ module Couchbase
|
|
971
1005
|
@delta = delta
|
972
1006
|
@initial = initial
|
973
1007
|
@expiry = Utils::Time.extract_expiry_time(expiry)
|
1008
|
+
@preserve_expiry = preserve_expiry
|
974
1009
|
@durability_level = durability_level
|
975
1010
|
yield self if block_given?
|
976
1011
|
end
|
@@ -989,6 +1024,7 @@ module Couchbase
|
|
989
1024
|
delta: @delta,
|
990
1025
|
initial_value: @initial,
|
991
1026
|
expiry: @expiry,
|
1027
|
+
preserve_expiry: @preserve_expiry,
|
992
1028
|
durability_level: @durability_level,
|
993
1029
|
}
|
994
1030
|
end
|
data/lib/couchbase/subdoc.rb
CHANGED
@@ -134,7 +134,7 @@ module Couchbase
|
|
134
134
|
#
|
135
135
|
# @return [MutateInSpec]
|
136
136
|
def self.remove(path)
|
137
|
-
new(:remove, path, nil)
|
137
|
+
new(path.empty? ? :remove_doc : :remove, path, nil)
|
138
138
|
end
|
139
139
|
|
140
140
|
# Creates a command with the intention of upserting a value in a JSON object.
|
data/lib/couchbase/version.rb
CHANGED
@@ -17,21 +17,21 @@ module Couchbase
|
|
17
17
|
#
|
18
18
|
# @example Display version and all dependencies in command line
|
19
19
|
# # ruby -rcouchbase -e 'pp Couchbase::VERSION'
|
20
|
-
# {:sdk=>"3.0
|
21
|
-
# :backend=>"1.
|
22
|
-
# :build_timestamp=>"
|
23
|
-
# :revision=>"
|
20
|
+
# {:sdk=>"3.1.0",
|
21
|
+
# :backend=>"1.4.0",
|
22
|
+
# :build_timestamp=>"2021-03-24 11:25:34",
|
23
|
+
# :revision=>"7ba4f7d8b5b0b59b9971ad765876413be3064adb",
|
24
24
|
# :platform=>"Linux-4.15.0-66-generic",
|
25
25
|
# :cpu=>"x86_64",
|
26
26
|
# :cc=>"GNU 9.3.1",
|
27
27
|
# :cxx=>"GNU 9.3.1",
|
28
|
-
# :ruby=>"
|
28
|
+
# :ruby=>"3.0.0",
|
29
29
|
# :spdlog=>"1.8.1",
|
30
30
|
# :asio=>"1.18.0",
|
31
31
|
# :snappy=>"1.1.8",
|
32
32
|
# :http_parser=>"2.9.4",
|
33
|
-
# :openssl_headers=>"OpenSSL 1.1.
|
34
|
-
# :openssl_runtime=>"OpenSSL 1.1.
|
33
|
+
# :openssl_headers=>"OpenSSL 1.1.1g FIPS 21 Apr 2020",
|
34
|
+
# :openssl_runtime=>"OpenSSL 1.1.1g FIPS 21 Apr 2020"}
|
35
35
|
VERSION = {} unless defined?(VERSION) # rubocop:disable Style/MutableConstant
|
36
|
-
VERSION.update(:sdk => "3.1.
|
36
|
+
VERSION.update(:sdk => "3.1.1".freeze)
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Avseyev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Modern SDK for Couchbase Server
|
14
14
|
email:
|
@@ -1375,9 +1375,9 @@ metadata:
|
|
1375
1375
|
homepage_uri: https://docs.couchbase.com/ruby-sdk/3.0/hello-world/start-using-sdk.html
|
1376
1376
|
bug_tracker_uri: https://couchbase.com/issues/browse/RCBC
|
1377
1377
|
mailing_list_uri: https://forums.couchbase.com/c/ruby-sdk
|
1378
|
-
source_code_uri: https://github.com/couchbase/couchbase-ruby-client/tree/3.1.
|
1379
|
-
changelog_uri: https://github.com/couchbase/couchbase-ruby-client/releases/tag/3.1.
|
1380
|
-
documentation_uri: https://docs.couchbase.com/sdk-api/couchbase-ruby-client-3.1.
|
1378
|
+
source_code_uri: https://github.com/couchbase/couchbase-ruby-client/tree/3.1.1
|
1379
|
+
changelog_uri: https://github.com/couchbase/couchbase-ruby-client/releases/tag/3.1.1
|
1380
|
+
documentation_uri: https://docs.couchbase.com/sdk-api/couchbase-ruby-client-3.1.1/index.html
|
1381
1381
|
github_repo: ssh://github.com/couchbase/couchbase-ruby-client
|
1382
1382
|
post_install_message:
|
1383
1383
|
rdoc_options:
|