couchbase 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +73 -4
- data/ext/build_config.hxx.in +2 -0
- data/ext/build_version.hxx.in +11 -8
- data/ext/cmake/BuildTracing.cmake +1 -1
- data/ext/cmake/CompilerWarnings.cmake +5 -0
- data/ext/cmake/Testing.cmake +3 -6
- data/ext/couchbase/bucket.hxx +9 -1
- data/ext/couchbase/cbsasl/client.h +1 -1
- data/ext/couchbase/cluster.hxx +89 -6
- data/ext/couchbase/configuration.hxx +2 -0
- data/ext/couchbase/couchbase.cxx +1647 -507
- data/ext/couchbase/diagnostics.hxx +0 -3
- data/ext/couchbase/io/dns_client.hxx +2 -2
- data/ext/couchbase/io/http_command.hxx +6 -3
- data/ext/couchbase/io/http_session.hxx +14 -18
- data/ext/couchbase/io/http_session_manager.hxx +83 -2
- data/ext/couchbase/io/mcbp_command.hxx +4 -1
- data/ext/couchbase/io/mcbp_context.hxx +37 -0
- data/ext/couchbase/io/mcbp_session.hxx +91 -30
- data/ext/couchbase/operations.hxx +5 -0
- data/ext/couchbase/operations/analytics_dataset_create.hxx +3 -2
- data/ext/couchbase/operations/analytics_dataset_drop.hxx +3 -2
- data/ext/couchbase/operations/analytics_dataset_get_all.hxx +3 -2
- data/ext/couchbase/operations/analytics_dataverse_create.hxx +3 -2
- data/ext/couchbase/operations/analytics_dataverse_drop.hxx +3 -2
- data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +3 -2
- data/ext/couchbase/operations/analytics_index_create.hxx +3 -2
- data/ext/couchbase/operations/analytics_index_drop.hxx +3 -2
- data/ext/couchbase/operations/analytics_index_get_all.hxx +5 -2
- data/ext/couchbase/operations/analytics_link_connect.hxx +3 -2
- data/ext/couchbase/operations/analytics_link_disconnect.hxx +3 -2
- data/ext/couchbase/operations/bucket_create.hxx +3 -2
- data/ext/couchbase/operations/bucket_drop.hxx +3 -2
- data/ext/couchbase/operations/bucket_flush.hxx +3 -2
- data/ext/couchbase/operations/bucket_get.hxx +3 -2
- data/ext/couchbase/operations/bucket_get_all.hxx +3 -2
- data/ext/couchbase/operations/bucket_update.hxx +3 -2
- data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +3 -2
- data/ext/couchbase/operations/collection_create.hxx +3 -2
- data/ext/couchbase/operations/collection_drop.hxx +3 -2
- data/ext/couchbase/operations/collections_manifest_get.hxx +3 -2
- data/ext/couchbase/operations/document_analytics.hxx +3 -2
- data/ext/couchbase/operations/document_append.hxx +77 -0
- data/ext/couchbase/operations/document_decrement.hxx +3 -2
- data/ext/couchbase/operations/document_exists.hxx +3 -2
- data/ext/couchbase/operations/document_get.hxx +3 -2
- data/ext/couchbase/operations/document_get_and_lock.hxx +3 -2
- data/ext/couchbase/operations/document_get_and_touch.hxx +3 -2
- data/ext/couchbase/operations/document_get_projected.hxx +3 -2
- data/ext/couchbase/operations/document_increment.hxx +3 -2
- data/ext/couchbase/operations/document_insert.hxx +3 -2
- data/ext/couchbase/operations/document_lookup_in.hxx +8 -2
- data/ext/couchbase/operations/document_mutate_in.hxx +13 -2
- data/ext/couchbase/operations/document_prepend.hxx +77 -0
- data/ext/couchbase/operations/document_query.hxx +3 -2
- data/ext/couchbase/operations/document_remove.hxx +5 -2
- data/ext/couchbase/operations/document_replace.hxx +3 -2
- data/ext/couchbase/operations/document_search.hxx +3 -2
- data/ext/couchbase/operations/document_touch.hxx +3 -2
- data/ext/couchbase/operations/document_unlock.hxx +3 -2
- data/ext/couchbase/operations/document_upsert.hxx +3 -2
- data/ext/couchbase/operations/document_view.hxx +3 -2
- data/ext/couchbase/operations/group_drop.hxx +3 -2
- data/ext/couchbase/operations/group_get.hxx +3 -2
- data/ext/couchbase/operations/group_get_all.hxx +3 -2
- data/ext/couchbase/operations/group_upsert.hxx +3 -2
- data/ext/couchbase/operations/http_noop.hxx +78 -0
- data/ext/couchbase/operations/mcbp_noop.hxx +61 -0
- data/ext/couchbase/operations/query_index_build_deferred.hxx +3 -2
- data/ext/couchbase/operations/query_index_create.hxx +3 -2
- data/ext/couchbase/operations/query_index_drop.hxx +3 -2
- data/ext/couchbase/operations/query_index_get_all.hxx +3 -2
- data/ext/couchbase/operations/role_get_all.hxx +3 -2
- data/ext/couchbase/operations/scope_create.hxx +3 -2
- data/ext/couchbase/operations/scope_drop.hxx +3 -2
- data/ext/couchbase/operations/scope_get_all.hxx +3 -2
- data/ext/couchbase/operations/search_get_stats.hxx +3 -2
- data/ext/couchbase/operations/search_index_analyze_document.hxx +3 -2
- data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -2
- data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +3 -2
- data/ext/couchbase/operations/search_index_control_query.hxx +3 -2
- data/ext/couchbase/operations/search_index_drop.hxx +3 -2
- data/ext/couchbase/operations/search_index_get.hxx +3 -2
- data/ext/couchbase/operations/search_index_get_all.hxx +3 -2
- data/ext/couchbase/operations/search_index_get_documents_count.hxx +3 -2
- data/ext/couchbase/operations/search_index_get_stats.hxx +3 -2
- data/ext/couchbase/operations/search_index_upsert.hxx +3 -2
- data/ext/couchbase/operations/user_drop.hxx +3 -2
- data/ext/couchbase/operations/user_get.hxx +3 -2
- data/ext/couchbase/operations/user_get_all.hxx +3 -2
- data/ext/couchbase/operations/user_upsert.hxx +3 -2
- data/ext/couchbase/operations/view_index_drop.hxx +3 -2
- data/ext/couchbase/operations/view_index_get.hxx +3 -2
- data/ext/couchbase/operations/view_index_get_all.hxx +3 -2
- data/ext/couchbase/operations/view_index_upsert.hxx +3 -2
- data/ext/couchbase/platform/terminate_handler.cc +5 -2
- data/ext/couchbase/protocol/client_opcode.hxx +368 -0
- data/ext/couchbase/protocol/cmd_append.hxx +145 -0
- data/ext/couchbase/protocol/cmd_hello.hxx +1 -0
- data/ext/couchbase/protocol/cmd_lookup_in.hxx +11 -3
- data/ext/couchbase/protocol/cmd_mutate_in.hxx +46 -4
- data/ext/couchbase/protocol/cmd_noop.hxx +82 -0
- data/ext/couchbase/protocol/cmd_prepend.hxx +145 -0
- data/ext/couchbase/protocol/durability_level.hxx +16 -0
- data/ext/couchbase/protocol/hello_feature.hxx +9 -0
- data/ext/couchbase/protocol/unsigned_leb128.h +2 -2
- data/ext/couchbase/service_type.hxx +1 -1
- data/ext/couchbase/version.hxx +18 -4
- data/ext/extconf.rb +9 -6
- data/ext/test/CMakeLists.txt +5 -0
- data/ext/test/test_helper.hxx +3 -3
- data/ext/test/test_helper_native.hxx +2 -5
- data/ext/test/test_native_binary_operations.cxx +186 -0
- data/ext/test/test_native_diagnostics.cxx +54 -3
- data/ext/test/test_ruby_trivial_crud.cxx +1 -1
- data/lib/couchbase.rb +1 -0
- data/lib/couchbase/analytics_options.rb +1 -71
- data/lib/couchbase/binary_collection.rb +60 -22
- data/lib/couchbase/binary_collection_options.rb +0 -76
- data/lib/couchbase/bucket.rb +40 -36
- data/lib/couchbase/cluster.rb +89 -156
- data/lib/couchbase/collection.rb +290 -72
- data/lib/couchbase/collection_options.rb +30 -243
- data/lib/couchbase/datastructures/couchbase_list.rb +5 -16
- data/lib/couchbase/datastructures/couchbase_map.rb +5 -16
- data/lib/couchbase/datastructures/couchbase_queue.rb +5 -16
- data/lib/couchbase/datastructures/couchbase_set.rb +5 -16
- data/lib/couchbase/diagnostics.rb +181 -0
- data/lib/couchbase/json_transcoder.rb +1 -1
- data/lib/couchbase/{common_options.rb → logger.rb} +24 -11
- data/lib/couchbase/management/query_index_manager.rb +1 -1
- data/lib/couchbase/management/user_manager.rb +3 -0
- data/lib/couchbase/options.rb +2094 -0
- data/lib/couchbase/query_options.rb +1 -144
- data/lib/couchbase/scope.rb +8 -25
- data/lib/couchbase/search_options.rb +0 -93
- data/lib/couchbase/version.rb +20 -1
- data/lib/couchbase/view_options.rb +1 -91
- metadata +19 -7
@@ -0,0 +1,145 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2020 Couchbase, Inc.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
|
18
|
+
#pragma once
|
19
|
+
|
20
|
+
#include <document_id.hxx>
|
21
|
+
#include <protocol/status.hxx>
|
22
|
+
#include <protocol/client_opcode.hxx>
|
23
|
+
#include <protocol/frame_info_id.hxx>
|
24
|
+
#include <protocol/unsigned_leb128.h>
|
25
|
+
#include <protocol/durability_level.hxx>
|
26
|
+
#include <protocol/cmd_info.hxx>
|
27
|
+
#include <mutation_token.hxx>
|
28
|
+
#include <utils/byteswap.hxx>
|
29
|
+
|
30
|
+
namespace couchbase::protocol
|
31
|
+
{
|
32
|
+
|
33
|
+
class append_response_body
|
34
|
+
{
|
35
|
+
public:
|
36
|
+
static const inline client_opcode opcode = client_opcode::append;
|
37
|
+
|
38
|
+
private:
|
39
|
+
mutation_token token_;
|
40
|
+
|
41
|
+
public:
|
42
|
+
mutation_token& token()
|
43
|
+
{
|
44
|
+
return token_;
|
45
|
+
}
|
46
|
+
|
47
|
+
bool parse(protocol::status status,
|
48
|
+
const header_buffer& header,
|
49
|
+
std::uint8_t framing_extras_size,
|
50
|
+
std::uint16_t,
|
51
|
+
std::uint8_t extras_size,
|
52
|
+
const std::vector<uint8_t>& body,
|
53
|
+
const cmd_info&)
|
54
|
+
{
|
55
|
+
Expects(header[1] == static_cast<uint8_t>(opcode));
|
56
|
+
if (status == protocol::status::success) {
|
57
|
+
std::vector<uint8_t>::difference_type offset = framing_extras_size;
|
58
|
+
if (extras_size == 16) {
|
59
|
+
memcpy(&token_.partition_uuid, body.data() + offset, sizeof(token_.partition_uuid));
|
60
|
+
token_.partition_uuid = utils::byte_swap_64(token_.partition_uuid);
|
61
|
+
offset += 8;
|
62
|
+
|
63
|
+
memcpy(&token_.sequence_number, body.data() + offset, sizeof(token_.sequence_number));
|
64
|
+
token_.sequence_number = utils::byte_swap_64(token_.sequence_number);
|
65
|
+
return true;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
return false;
|
69
|
+
}
|
70
|
+
};
|
71
|
+
|
72
|
+
class append_request_body
|
73
|
+
{
|
74
|
+
public:
|
75
|
+
using response_body_type = append_response_body;
|
76
|
+
static const inline client_opcode opcode = client_opcode::append;
|
77
|
+
|
78
|
+
private:
|
79
|
+
std::string key_{};
|
80
|
+
std::vector<std::uint8_t> extras_{};
|
81
|
+
std::vector<std::uint8_t> content_{};
|
82
|
+
std::vector<std::uint8_t> framing_extras_{};
|
83
|
+
|
84
|
+
public:
|
85
|
+
void id(const document_id& id)
|
86
|
+
{
|
87
|
+
key_ = id.key;
|
88
|
+
if (id.collection_uid) {
|
89
|
+
unsigned_leb128<uint32_t> encoded(*id.collection_uid);
|
90
|
+
key_.insert(0, encoded.get());
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
void durability(protocol::durability_level level, std::optional<std::uint16_t> timeout)
|
95
|
+
{
|
96
|
+
if (level == protocol::durability_level::none) {
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::durability_requirement);
|
100
|
+
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);
|
104
|
+
uint16_t val = htons(*timeout);
|
105
|
+
memcpy(framing_extras_.data() + 2, &val, sizeof(val));
|
106
|
+
} 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);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
void content(const std::string& content)
|
114
|
+
{
|
115
|
+
content_ = { content.begin(), content.end() };
|
116
|
+
}
|
117
|
+
|
118
|
+
const std::string& key()
|
119
|
+
{
|
120
|
+
return key_;
|
121
|
+
}
|
122
|
+
|
123
|
+
const std::vector<std::uint8_t>& framing_extras()
|
124
|
+
{
|
125
|
+
return framing_extras_;
|
126
|
+
}
|
127
|
+
|
128
|
+
const std::vector<std::uint8_t>& extras()
|
129
|
+
{
|
130
|
+
static std::vector<std::uint8_t> empty;
|
131
|
+
return empty;
|
132
|
+
}
|
133
|
+
|
134
|
+
const std::vector<std::uint8_t>& value()
|
135
|
+
{
|
136
|
+
return content_;
|
137
|
+
}
|
138
|
+
|
139
|
+
std::size_t size()
|
140
|
+
{
|
141
|
+
return framing_extras_.size() + key_.size() + content_.size();
|
142
|
+
}
|
143
|
+
};
|
144
|
+
|
145
|
+
} // namespace couchbase::protocol
|
@@ -53,7 +53,8 @@ class lookup_in_response_body
|
|
53
53
|
const cmd_info&)
|
54
54
|
{
|
55
55
|
Expects(header[1] == static_cast<uint8_t>(opcode));
|
56
|
-
if (status == protocol::status::success || status == protocol::status::subdoc_multi_path_failure
|
56
|
+
if (status == protocol::status::success || status == protocol::status::subdoc_multi_path_failure ||
|
57
|
+
status == protocol::status::subdoc_success_deleted || status == protocol::status::subdoc_multi_path_failure_deleted) {
|
57
58
|
using offset_type = std::vector<uint8_t>::difference_type;
|
58
59
|
offset_type offset = framing_extras_size + key_size + extras_size;
|
59
60
|
fields_.reserve(16); /* we won't have more than 16 entries anyway */
|
@@ -91,10 +92,17 @@ class lookup_in_request_body
|
|
91
92
|
using response_body_type = lookup_in_response_body;
|
92
93
|
static const inline client_opcode opcode = client_opcode::subdoc_multi_lookup;
|
93
94
|
|
94
|
-
|
95
|
+
/**
|
96
|
+
* Allow access to XATTRs for deleted documents (instead of returning KEY_ENOENT).
|
97
|
+
*/
|
98
|
+
static const inline uint8_t doc_flag_access_deleted = 0b0000'0100;
|
95
99
|
|
96
100
|
struct lookup_in_specs {
|
97
|
-
|
101
|
+
/**
|
102
|
+
* If set, the path refers to an Extended Attribute (XATTR).
|
103
|
+
* If clear, the path refers to a path inside the document body.
|
104
|
+
*/
|
105
|
+
static const inline uint8_t path_flag_xattr = 0b0000'0100;
|
98
106
|
|
99
107
|
struct entry {
|
100
108
|
std::uint8_t opcode;
|
@@ -133,14 +133,47 @@ class mutate_in_request_body
|
|
133
133
|
insert,
|
134
134
|
};
|
135
135
|
|
136
|
-
|
136
|
+
/**
|
137
|
+
* Create the document if it does not exist. Implies `path_flag_create_parents`.
|
138
|
+
* and `upsert` mutation semantics. Not valid with `insert`.
|
139
|
+
*/
|
137
140
|
static const inline uint8_t doc_flag_mkdoc = 0b0000'0001;
|
141
|
+
|
142
|
+
/**
|
143
|
+
* Add the document only if it does not exist. Implies `path_flag_create_parents`.
|
144
|
+
* Not valid with `doc_flag_mkdoc`.
|
145
|
+
*/
|
138
146
|
static const inline uint8_t doc_flag_add = 0b0000'0010;
|
139
147
|
|
148
|
+
/**
|
149
|
+
* Allow access to XATTRs for deleted documents (instead of returning KEY_ENOENT).
|
150
|
+
*/
|
151
|
+
static const inline uint8_t doc_flag_access_deleted = 0b0000'0100;
|
152
|
+
|
153
|
+
/**
|
154
|
+
* Used with `doc_flag_mkdoc` / `doc_flag_add`; if the document does not exist then creat
|
155
|
+
* it in the "Deleted" state, instead of the normal "Alive" state.
|
156
|
+
* Not valid unless `doc_flag_mkdoc` or `doc_flag_add` specified.
|
157
|
+
*/
|
158
|
+
static const inline uint8_t doc_flag_create_as_deleted = 0b0000'1000;
|
159
|
+
|
140
160
|
struct mutate_in_specs {
|
141
|
-
|
142
|
-
|
143
|
-
|
161
|
+
/**
|
162
|
+
* Should non-existent intermediate paths be created
|
163
|
+
*/
|
164
|
+
static const inline uint8_t path_flag_create_parents = 0b0000'0001;
|
165
|
+
|
166
|
+
/**
|
167
|
+
* If set, the path refers to an Extended Attribute (XATTR).
|
168
|
+
* If clear, the path refers to a path inside the document body.
|
169
|
+
*/
|
170
|
+
static const inline uint8_t path_flag_xattr = 0b0000'0100;
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Expand macro values inside extended attributes. The request is
|
174
|
+
* invalid if this flag is set without `path_flag_create_parents` being set.
|
175
|
+
*/
|
176
|
+
static const inline uint8_t path_flag_expand_macros = 0b0001'0000;
|
144
177
|
|
145
178
|
struct entry {
|
146
179
|
std::uint8_t opcode;
|
@@ -237,6 +270,15 @@ class mutate_in_request_body
|
|
237
270
|
}
|
238
271
|
}
|
239
272
|
|
273
|
+
void create_as_deleted(bool value)
|
274
|
+
{
|
275
|
+
if (value) {
|
276
|
+
flags_ |= doc_flag_create_as_deleted;
|
277
|
+
} else {
|
278
|
+
flags_ &= static_cast<std::uint8_t>(~doc_flag_create_as_deleted);
|
279
|
+
}
|
280
|
+
}
|
281
|
+
|
240
282
|
void store_semantics(store_semantics_type semantics)
|
241
283
|
{
|
242
284
|
flags_ &= 0b1111'1100; /* reset first two bits */
|
@@ -0,0 +1,82 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2020 Couchbase, Inc.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
|
18
|
+
#pragma once
|
19
|
+
|
20
|
+
#include <protocol/unsigned_leb128.h>
|
21
|
+
|
22
|
+
#include <protocol/client_opcode.hxx>
|
23
|
+
#include <document_id.hxx>
|
24
|
+
|
25
|
+
namespace couchbase::protocol
|
26
|
+
{
|
27
|
+
|
28
|
+
class mcbp_noop_response_body
|
29
|
+
{
|
30
|
+
public:
|
31
|
+
static const inline client_opcode opcode = client_opcode::noop;
|
32
|
+
|
33
|
+
bool parse(protocol::status,
|
34
|
+
const header_buffer& header,
|
35
|
+
std::uint8_t,
|
36
|
+
std::uint16_t,
|
37
|
+
std::uint8_t,
|
38
|
+
const std::vector<uint8_t>&,
|
39
|
+
const cmd_info&)
|
40
|
+
{
|
41
|
+
Expects(header[1] == static_cast<uint8_t>(opcode));
|
42
|
+
return false;
|
43
|
+
}
|
44
|
+
};
|
45
|
+
|
46
|
+
class mcbp_noop_request_body
|
47
|
+
{
|
48
|
+
public:
|
49
|
+
using response_body_type = mcbp_noop_response_body;
|
50
|
+
static const inline client_opcode opcode = client_opcode::noop;
|
51
|
+
|
52
|
+
const std::string& key()
|
53
|
+
{
|
54
|
+
static std::string empty;
|
55
|
+
return empty;
|
56
|
+
}
|
57
|
+
|
58
|
+
const std::vector<std::uint8_t>& framing_extras()
|
59
|
+
{
|
60
|
+
static std::vector<std::uint8_t> empty;
|
61
|
+
return empty;
|
62
|
+
}
|
63
|
+
|
64
|
+
const std::vector<std::uint8_t>& extras()
|
65
|
+
{
|
66
|
+
static std::vector<std::uint8_t> empty;
|
67
|
+
return empty;
|
68
|
+
}
|
69
|
+
|
70
|
+
const std::vector<std::uint8_t>& value()
|
71
|
+
{
|
72
|
+
static std::vector<std::uint8_t> empty;
|
73
|
+
return empty;
|
74
|
+
}
|
75
|
+
|
76
|
+
std::size_t size()
|
77
|
+
{
|
78
|
+
return 0;
|
79
|
+
}
|
80
|
+
};
|
81
|
+
|
82
|
+
} // namespace couchbase::protocol
|
@@ -0,0 +1,145 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2020 Couchbase, Inc.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
|
18
|
+
#pragma once
|
19
|
+
|
20
|
+
#include <protocol/status.hxx>
|
21
|
+
#include <protocol/client_opcode.hxx>
|
22
|
+
#include <protocol/frame_info_id.hxx>
|
23
|
+
#include <protocol/unsigned_leb128.h>
|
24
|
+
#include <protocol/durability_level.hxx>
|
25
|
+
#include <protocol/cmd_info.hxx>
|
26
|
+
#include <document_id.hxx>
|
27
|
+
#include <mutation_token.hxx>
|
28
|
+
#include <utils/byteswap.hxx>
|
29
|
+
|
30
|
+
namespace couchbase::protocol
|
31
|
+
{
|
32
|
+
|
33
|
+
class prepend_response_body
|
34
|
+
{
|
35
|
+
public:
|
36
|
+
static const inline client_opcode opcode = client_opcode::prepend;
|
37
|
+
|
38
|
+
private:
|
39
|
+
mutation_token token_;
|
40
|
+
|
41
|
+
public:
|
42
|
+
mutation_token& token()
|
43
|
+
{
|
44
|
+
return token_;
|
45
|
+
}
|
46
|
+
|
47
|
+
bool parse(protocol::status status,
|
48
|
+
const header_buffer& header,
|
49
|
+
std::uint8_t framing_extras_size,
|
50
|
+
std::uint16_t,
|
51
|
+
std::uint8_t extras_size,
|
52
|
+
const std::vector<uint8_t>& body,
|
53
|
+
const cmd_info&)
|
54
|
+
{
|
55
|
+
Expects(header[1] == static_cast<uint8_t>(opcode));
|
56
|
+
if (status == protocol::status::success) {
|
57
|
+
std::vector<uint8_t>::difference_type offset = framing_extras_size;
|
58
|
+
if (extras_size == 16) {
|
59
|
+
memcpy(&token_.partition_uuid, body.data() + offset, sizeof(token_.partition_uuid));
|
60
|
+
token_.partition_uuid = utils::byte_swap_64(token_.partition_uuid);
|
61
|
+
offset += 8;
|
62
|
+
|
63
|
+
memcpy(&token_.sequence_number, body.data() + offset, sizeof(token_.sequence_number));
|
64
|
+
token_.sequence_number = utils::byte_swap_64(token_.sequence_number);
|
65
|
+
return true;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
return false;
|
69
|
+
}
|
70
|
+
};
|
71
|
+
|
72
|
+
class prepend_request_body
|
73
|
+
{
|
74
|
+
public:
|
75
|
+
using response_body_type = prepend_response_body;
|
76
|
+
static const inline client_opcode opcode = client_opcode::prepend;
|
77
|
+
|
78
|
+
private:
|
79
|
+
std::string key_{};
|
80
|
+
std::vector<std::uint8_t> extras_{};
|
81
|
+
std::vector<std::uint8_t> content_{};
|
82
|
+
std::vector<std::uint8_t> framing_extras_{};
|
83
|
+
|
84
|
+
public:
|
85
|
+
void id(const document_id& id)
|
86
|
+
{
|
87
|
+
key_ = id.key;
|
88
|
+
if (id.collection_uid) {
|
89
|
+
unsigned_leb128<uint32_t> encoded(*id.collection_uid);
|
90
|
+
key_.insert(0, encoded.get());
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
void durability(protocol::durability_level level, std::optional<std::uint16_t> timeout)
|
95
|
+
{
|
96
|
+
if (level == protocol::durability_level::none) {
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
auto frame_id = static_cast<uint8_t>(protocol::request_frame_info_id::durability_requirement);
|
100
|
+
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);
|
104
|
+
uint16_t val = htons(*timeout);
|
105
|
+
memcpy(framing_extras_.data() + 2, &val, sizeof(val));
|
106
|
+
} 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);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
void content(const std::string& content)
|
114
|
+
{
|
115
|
+
content_ = { content.begin(), content.end() };
|
116
|
+
}
|
117
|
+
|
118
|
+
const std::string& key()
|
119
|
+
{
|
120
|
+
return key_;
|
121
|
+
}
|
122
|
+
|
123
|
+
const std::vector<std::uint8_t>& framing_extras()
|
124
|
+
{
|
125
|
+
return framing_extras_;
|
126
|
+
}
|
127
|
+
|
128
|
+
const std::vector<std::uint8_t>& extras()
|
129
|
+
{
|
130
|
+
static std::vector<std::uint8_t> empty;
|
131
|
+
return empty;
|
132
|
+
}
|
133
|
+
|
134
|
+
const std::vector<std::uint8_t>& value()
|
135
|
+
{
|
136
|
+
return content_;
|
137
|
+
}
|
138
|
+
|
139
|
+
std::size_t size()
|
140
|
+
{
|
141
|
+
return framing_extras_.size() + key_.size() + content_.size();
|
142
|
+
}
|
143
|
+
};
|
144
|
+
|
145
|
+
} // namespace couchbase::protocol
|