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