couchbase 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +73 -4
  3. data/ext/build_config.hxx.in +2 -0
  4. data/ext/build_version.hxx.in +11 -8
  5. data/ext/cmake/BuildTracing.cmake +1 -1
  6. data/ext/cmake/CompilerWarnings.cmake +5 -0
  7. data/ext/cmake/Testing.cmake +3 -6
  8. data/ext/couchbase/bucket.hxx +9 -1
  9. data/ext/couchbase/cbsasl/client.h +1 -1
  10. data/ext/couchbase/cluster.hxx +89 -6
  11. data/ext/couchbase/configuration.hxx +2 -0
  12. data/ext/couchbase/couchbase.cxx +1647 -507
  13. data/ext/couchbase/diagnostics.hxx +0 -3
  14. data/ext/couchbase/io/dns_client.hxx +2 -2
  15. data/ext/couchbase/io/http_command.hxx +6 -3
  16. data/ext/couchbase/io/http_session.hxx +14 -18
  17. data/ext/couchbase/io/http_session_manager.hxx +83 -2
  18. data/ext/couchbase/io/mcbp_command.hxx +4 -1
  19. data/ext/couchbase/io/mcbp_context.hxx +37 -0
  20. data/ext/couchbase/io/mcbp_session.hxx +91 -30
  21. data/ext/couchbase/operations.hxx +5 -0
  22. data/ext/couchbase/operations/analytics_dataset_create.hxx +3 -2
  23. data/ext/couchbase/operations/analytics_dataset_drop.hxx +3 -2
  24. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +3 -2
  25. data/ext/couchbase/operations/analytics_dataverse_create.hxx +3 -2
  26. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +3 -2
  27. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +3 -2
  28. data/ext/couchbase/operations/analytics_index_create.hxx +3 -2
  29. data/ext/couchbase/operations/analytics_index_drop.hxx +3 -2
  30. data/ext/couchbase/operations/analytics_index_get_all.hxx +5 -2
  31. data/ext/couchbase/operations/analytics_link_connect.hxx +3 -2
  32. data/ext/couchbase/operations/analytics_link_disconnect.hxx +3 -2
  33. data/ext/couchbase/operations/bucket_create.hxx +3 -2
  34. data/ext/couchbase/operations/bucket_drop.hxx +3 -2
  35. data/ext/couchbase/operations/bucket_flush.hxx +3 -2
  36. data/ext/couchbase/operations/bucket_get.hxx +3 -2
  37. data/ext/couchbase/operations/bucket_get_all.hxx +3 -2
  38. data/ext/couchbase/operations/bucket_update.hxx +3 -2
  39. data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +3 -2
  40. data/ext/couchbase/operations/collection_create.hxx +3 -2
  41. data/ext/couchbase/operations/collection_drop.hxx +3 -2
  42. data/ext/couchbase/operations/collections_manifest_get.hxx +3 -2
  43. data/ext/couchbase/operations/document_analytics.hxx +3 -2
  44. data/ext/couchbase/operations/document_append.hxx +77 -0
  45. data/ext/couchbase/operations/document_decrement.hxx +3 -2
  46. data/ext/couchbase/operations/document_exists.hxx +3 -2
  47. data/ext/couchbase/operations/document_get.hxx +3 -2
  48. data/ext/couchbase/operations/document_get_and_lock.hxx +3 -2
  49. data/ext/couchbase/operations/document_get_and_touch.hxx +3 -2
  50. data/ext/couchbase/operations/document_get_projected.hxx +3 -2
  51. data/ext/couchbase/operations/document_increment.hxx +3 -2
  52. data/ext/couchbase/operations/document_insert.hxx +3 -2
  53. data/ext/couchbase/operations/document_lookup_in.hxx +8 -2
  54. data/ext/couchbase/operations/document_mutate_in.hxx +13 -2
  55. data/ext/couchbase/operations/document_prepend.hxx +77 -0
  56. data/ext/couchbase/operations/document_query.hxx +3 -2
  57. data/ext/couchbase/operations/document_remove.hxx +5 -2
  58. data/ext/couchbase/operations/document_replace.hxx +3 -2
  59. data/ext/couchbase/operations/document_search.hxx +3 -2
  60. data/ext/couchbase/operations/document_touch.hxx +3 -2
  61. data/ext/couchbase/operations/document_unlock.hxx +3 -2
  62. data/ext/couchbase/operations/document_upsert.hxx +3 -2
  63. data/ext/couchbase/operations/document_view.hxx +3 -2
  64. data/ext/couchbase/operations/group_drop.hxx +3 -2
  65. data/ext/couchbase/operations/group_get.hxx +3 -2
  66. data/ext/couchbase/operations/group_get_all.hxx +3 -2
  67. data/ext/couchbase/operations/group_upsert.hxx +3 -2
  68. data/ext/couchbase/operations/http_noop.hxx +78 -0
  69. data/ext/couchbase/operations/mcbp_noop.hxx +61 -0
  70. data/ext/couchbase/operations/query_index_build_deferred.hxx +3 -2
  71. data/ext/couchbase/operations/query_index_create.hxx +3 -2
  72. data/ext/couchbase/operations/query_index_drop.hxx +3 -2
  73. data/ext/couchbase/operations/query_index_get_all.hxx +3 -2
  74. data/ext/couchbase/operations/role_get_all.hxx +3 -2
  75. data/ext/couchbase/operations/scope_create.hxx +3 -2
  76. data/ext/couchbase/operations/scope_drop.hxx +3 -2
  77. data/ext/couchbase/operations/scope_get_all.hxx +3 -2
  78. data/ext/couchbase/operations/search_get_stats.hxx +3 -2
  79. data/ext/couchbase/operations/search_index_analyze_document.hxx +3 -2
  80. data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -2
  81. data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +3 -2
  82. data/ext/couchbase/operations/search_index_control_query.hxx +3 -2
  83. data/ext/couchbase/operations/search_index_drop.hxx +3 -2
  84. data/ext/couchbase/operations/search_index_get.hxx +3 -2
  85. data/ext/couchbase/operations/search_index_get_all.hxx +3 -2
  86. data/ext/couchbase/operations/search_index_get_documents_count.hxx +3 -2
  87. data/ext/couchbase/operations/search_index_get_stats.hxx +3 -2
  88. data/ext/couchbase/operations/search_index_upsert.hxx +3 -2
  89. data/ext/couchbase/operations/user_drop.hxx +3 -2
  90. data/ext/couchbase/operations/user_get.hxx +3 -2
  91. data/ext/couchbase/operations/user_get_all.hxx +3 -2
  92. data/ext/couchbase/operations/user_upsert.hxx +3 -2
  93. data/ext/couchbase/operations/view_index_drop.hxx +3 -2
  94. data/ext/couchbase/operations/view_index_get.hxx +3 -2
  95. data/ext/couchbase/operations/view_index_get_all.hxx +3 -2
  96. data/ext/couchbase/operations/view_index_upsert.hxx +3 -2
  97. data/ext/couchbase/platform/terminate_handler.cc +5 -2
  98. data/ext/couchbase/protocol/client_opcode.hxx +368 -0
  99. data/ext/couchbase/protocol/cmd_append.hxx +145 -0
  100. data/ext/couchbase/protocol/cmd_hello.hxx +1 -0
  101. data/ext/couchbase/protocol/cmd_lookup_in.hxx +11 -3
  102. data/ext/couchbase/protocol/cmd_mutate_in.hxx +46 -4
  103. data/ext/couchbase/protocol/cmd_noop.hxx +82 -0
  104. data/ext/couchbase/protocol/cmd_prepend.hxx +145 -0
  105. data/ext/couchbase/protocol/durability_level.hxx +16 -0
  106. data/ext/couchbase/protocol/hello_feature.hxx +9 -0
  107. data/ext/couchbase/protocol/unsigned_leb128.h +2 -2
  108. data/ext/couchbase/service_type.hxx +1 -1
  109. data/ext/couchbase/version.hxx +18 -4
  110. data/ext/extconf.rb +9 -6
  111. data/ext/test/CMakeLists.txt +5 -0
  112. data/ext/test/test_helper.hxx +3 -3
  113. data/ext/test/test_helper_native.hxx +2 -5
  114. data/ext/test/test_native_binary_operations.cxx +186 -0
  115. data/ext/test/test_native_diagnostics.cxx +54 -3
  116. data/ext/test/test_ruby_trivial_crud.cxx +1 -1
  117. data/lib/couchbase.rb +1 -0
  118. data/lib/couchbase/analytics_options.rb +1 -71
  119. data/lib/couchbase/binary_collection.rb +60 -22
  120. data/lib/couchbase/binary_collection_options.rb +0 -76
  121. data/lib/couchbase/bucket.rb +40 -36
  122. data/lib/couchbase/cluster.rb +89 -156
  123. data/lib/couchbase/collection.rb +290 -72
  124. data/lib/couchbase/collection_options.rb +30 -243
  125. data/lib/couchbase/datastructures/couchbase_list.rb +5 -16
  126. data/lib/couchbase/datastructures/couchbase_map.rb +5 -16
  127. data/lib/couchbase/datastructures/couchbase_queue.rb +5 -16
  128. data/lib/couchbase/datastructures/couchbase_set.rb +5 -16
  129. data/lib/couchbase/diagnostics.rb +181 -0
  130. data/lib/couchbase/json_transcoder.rb +1 -1
  131. data/lib/couchbase/{common_options.rb → logger.rb} +24 -11
  132. data/lib/couchbase/management/query_index_manager.rb +1 -1
  133. data/lib/couchbase/management/user_manager.rb +3 -0
  134. data/lib/couchbase/options.rb +2094 -0
  135. data/lib/couchbase/query_options.rb +1 -144
  136. data/lib/couchbase/scope.rb +8 -25
  137. data/lib/couchbase/search_options.rb +0 -93
  138. data/lib/couchbase/version.rb +20 -1
  139. data/lib/couchbase/view_options.rb +1 -91
  140. metadata +19 -7
@@ -45,15 +45,16 @@ struct collection_drop_request {
45
45
  std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
46
46
  std::string client_context_id{ uuid::to_string(uuid::random()) };
47
47
 
48
- void encode_to(encoded_request_type& encoded, http_context&)
48
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, http_context&)
49
49
  {
50
50
  encoded.method = "DELETE";
51
51
  encoded.path = fmt::format("/pools/default/buckets/{}/collections/{}/{}", bucket_name, scope_name, collection_name);
52
+ return {};
52
53
  }
53
54
  };
54
55
 
55
56
  collection_drop_response
56
- make_response(std::error_code ec, collection_drop_request& request, collection_drop_request::encoded_response_type encoded)
57
+ make_response(std::error_code ec, collection_drop_request& request, collection_drop_request::encoded_response_type&& encoded)
57
58
  {
58
59
  collection_drop_response response{ request.client_context_id, ec };
59
60
  if (!ec) {
@@ -47,16 +47,17 @@ struct collections_manifest_get_request {
47
47
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
48
48
  io::retry_context<io::retry_strategy::best_effort> retries{ true };
49
49
 
50
- void encode_to(encoded_request_type& encoded)
50
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
51
51
  {
52
52
  encoded.opaque(opaque);
53
+ return {};
53
54
  }
54
55
  };
55
56
 
56
57
  collections_manifest_get_response
57
58
  make_response(std::error_code ec,
58
59
  collections_manifest_get_request& request,
59
- collections_manifest_get_request::encoded_response_type encoded)
60
+ collections_manifest_get_request::encoded_response_type&& encoded)
60
61
  {
61
62
  collections_manifest_get_response response{ request.id, encoded.opaque(), ec };
62
63
  if (ec && response.opaque == 0) {
@@ -166,7 +166,7 @@ struct analytics_request {
166
166
  std::vector<tao::json::value> positional_parameters{};
167
167
  std::map<std::string, tao::json::value> named_parameters{};
168
168
 
169
- void encode_to(encoded_request_type& encoded, http_context& context)
169
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, http_context& context)
170
170
  {
171
171
  tao::json::value body{ { "statement", statement },
172
172
  { "client_context_id", client_context_id },
@@ -212,11 +212,12 @@ struct analytics_request {
212
212
  } else {
213
213
  spdlog::debug("ANALYTICS: {}", tao::json::to_string(body["statement"]));
214
214
  }
215
+ return {};
215
216
  }
216
217
  };
217
218
 
218
219
  analytics_response
219
- make_response(std::error_code ec, analytics_request& request, analytics_request::encoded_response_type encoded)
220
+ make_response(std::error_code ec, analytics_request& request, analytics_request::encoded_response_type&& encoded)
220
221
  {
221
222
  analytics_response response{ request.client_context_id, ec };
222
223
  if (!ec) {
@@ -0,0 +1,77 @@
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/cmd_append.hxx>
21
+ #include <protocol/durability_level.hxx>
22
+ #include <io/retry_context.hxx>
23
+
24
+ namespace couchbase::operations
25
+ {
26
+
27
+ struct append_response {
28
+ document_id id;
29
+ std::uint32_t opaque;
30
+ std::error_code ec{};
31
+ std::uint64_t cas{};
32
+ mutation_token token{};
33
+ };
34
+
35
+ struct append_request {
36
+ using encoded_request_type = protocol::client_request<protocol::append_request_body>;
37
+ using encoded_response_type = protocol::client_response<protocol::append_response_body>;
38
+
39
+ document_id id;
40
+ std::string value;
41
+ uint16_t partition{};
42
+ uint32_t opaque{};
43
+ protocol::durability_level durability_level{ protocol::durability_level::none };
44
+ std::optional<std::uint16_t> durability_timeout{};
45
+ std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
46
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
47
+
48
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
49
+ {
50
+ encoded.opaque(opaque);
51
+ encoded.partition(partition);
52
+ encoded.body().id(id);
53
+ encoded.body().content(value);
54
+ if (durability_level != protocol::durability_level::none) {
55
+ encoded.body().durability(durability_level, durability_timeout);
56
+ }
57
+ return {};
58
+ }
59
+ };
60
+
61
+ append_response
62
+ make_response(std::error_code ec, append_request& request, append_request::encoded_response_type&& encoded)
63
+ {
64
+ append_response response{ request.id, encoded.opaque(), ec };
65
+ if (ec && response.opaque == 0) {
66
+ response.opaque = request.opaque;
67
+ }
68
+ if (!ec) {
69
+ response.cas = encoded.cas();
70
+ response.token = encoded.body().token();
71
+ response.token.partition_id = request.partition;
72
+ response.token.bucket_name = response.id.bucket;
73
+ }
74
+ return response;
75
+ }
76
+
77
+ } // namespace couchbase::operations
@@ -48,7 +48,7 @@ struct decrement_request {
48
48
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
49
49
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
50
50
 
51
- void encode_to(encoded_request_type& encoded)
51
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
52
52
  {
53
53
  encoded.opaque(opaque);
54
54
  encoded.partition(partition);
@@ -64,11 +64,12 @@ struct decrement_request {
64
64
  if (durability_level != protocol::durability_level::none) {
65
65
  encoded.body().durability(durability_level, durability_timeout);
66
66
  }
67
+ return {};
67
68
  }
68
69
  };
69
70
 
70
71
  decrement_response
71
- make_response(std::error_code ec, decrement_request& request, decrement_request::encoded_response_type encoded)
72
+ make_response(std::error_code ec, decrement_request& request, decrement_request::encoded_response_type&& encoded)
72
73
  {
73
74
  decrement_response response{ request.id, encoded.opaque(), ec };
74
75
  if (ec && response.opaque == 0) {
@@ -45,15 +45,16 @@ struct exists_request {
45
45
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
46
46
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
47
47
 
48
- void encode_to(encoded_request_type& encoded)
48
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
49
49
  {
50
50
  encoded.opaque(opaque);
51
51
  encoded.body().id(partition, id);
52
+ return {};
52
53
  }
53
54
  };
54
55
 
55
56
  exists_response
56
- make_response(std::error_code ec, exists_request& request, exists_request::encoded_response_type encoded)
57
+ make_response(std::error_code ec, exists_request& request, exists_request::encoded_response_type&& encoded)
57
58
  {
58
59
  exists_response response{ request.id, encoded.opaque(), ec, request.partition };
59
60
  if (!ec) {
@@ -43,16 +43,17 @@ struct get_request {
43
43
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
44
44
  io::retry_context<io::retry_strategy::best_effort> retries{ true };
45
45
 
46
- void encode_to(encoded_request_type& encoded)
46
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
47
47
  {
48
48
  encoded.opaque(opaque);
49
49
  encoded.partition(partition);
50
50
  encoded.body().id(id);
51
+ return {};
51
52
  }
52
53
  };
53
54
 
54
55
  get_response
55
- make_response(std::error_code ec, get_request& request, get_request::encoded_response_type encoded)
56
+ make_response(std::error_code ec, get_request& request, get_request::encoded_response_type&& encoded)
56
57
  {
57
58
  get_response response{ request.id, encoded.opaque(), ec };
58
59
  if (ec && response.opaque == 0) {
@@ -44,17 +44,18 @@ struct get_and_lock_request {
44
44
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
45
45
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
46
46
 
47
- void encode_to(encoded_request_type& encoded)
47
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
48
48
  {
49
49
  encoded.opaque(opaque);
50
50
  encoded.partition(partition);
51
51
  encoded.body().id(id);
52
52
  encoded.body().lock_time(lock_time);
53
+ return {};
53
54
  }
54
55
  };
55
56
 
56
57
  get_and_lock_response
57
- make_response(std::error_code ec, get_and_lock_request& request, get_and_lock_request::encoded_response_type encoded)
58
+ make_response(std::error_code ec, get_and_lock_request& request, get_and_lock_request::encoded_response_type&& encoded)
58
59
  {
59
60
  get_and_lock_response response{ request.id, encoded.opaque(), ec };
60
61
  if (ec && response.opaque == 0) {
@@ -44,17 +44,18 @@ struct get_and_touch_request {
44
44
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
45
45
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
46
46
 
47
- void encode_to(encoded_request_type& encoded)
47
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
48
48
  {
49
49
  encoded.opaque(opaque);
50
50
  encoded.partition(partition);
51
51
  encoded.body().id(id);
52
52
  encoded.body().expiry(expiry);
53
+ return {};
53
54
  }
54
55
  };
55
56
 
56
57
  get_and_touch_response
57
- make_response(std::error_code ec, get_and_touch_request& request, get_and_touch_request::encoded_response_type encoded)
58
+ make_response(std::error_code ec, get_and_touch_request& request, get_and_touch_request::encoded_response_type&& encoded)
58
59
  {
59
60
  get_and_touch_response response{ request.id, encoded.opaque(), ec };
60
61
  if (ec && response.opaque == 0) {
@@ -48,7 +48,7 @@ struct get_projected_request {
48
48
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
49
49
  io::retry_context<io::retry_strategy::best_effort> retries{ true };
50
50
 
51
- void encode_to(encoded_request_type& encoded)
51
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
52
52
  {
53
53
  encoded.opaque(opaque);
54
54
  encoded.partition(partition);
@@ -76,6 +76,7 @@ struct get_projected_request {
76
76
  }
77
77
  }
78
78
  encoded.body().specs(specs);
79
+ return {};
79
80
  }
80
81
  };
81
82
 
@@ -197,7 +198,7 @@ subdoc_apply_projection(tao::json::value& root, const std::string& path, tao::js
197
198
  } // namespace priv
198
199
 
199
200
  get_projected_response
200
- make_response(std::error_code ec, get_projected_request& request, get_projected_request::encoded_response_type encoded)
201
+ make_response(std::error_code ec, get_projected_request& request, get_projected_request::encoded_response_type&& encoded)
201
202
  {
202
203
  get_projected_response response{ request.id, encoded.opaque(), ec };
203
204
  if (ec && response.opaque == 0) {
@@ -50,7 +50,7 @@ struct increment_request {
50
50
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
51
51
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
52
52
 
53
- void encode_to(encoded_request_type& encoded)
53
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
54
54
  {
55
55
  encoded.opaque(opaque);
56
56
  encoded.partition(partition);
@@ -66,11 +66,12 @@ struct increment_request {
66
66
  if (durability_level != protocol::durability_level::none) {
67
67
  encoded.body().durability(durability_level, durability_timeout);
68
68
  }
69
+ return {};
69
70
  }
70
71
  };
71
72
 
72
73
  increment_response
73
- make_response(std::error_code ec, increment_request& request, increment_request::encoded_response_type encoded)
74
+ make_response(std::error_code ec, increment_request& request, increment_request::encoded_response_type&& encoded)
74
75
  {
75
76
  increment_response response{ request.id, encoded.opaque(), ec };
76
77
  if (ec && response.opaque == 0) {
@@ -48,7 +48,7 @@ struct insert_request {
48
48
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
49
49
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
50
50
 
51
- void encode_to(encoded_request_type& encoded)
51
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
52
52
  {
53
53
  encoded.opaque(opaque);
54
54
  encoded.partition(partition);
@@ -59,11 +59,12 @@ struct insert_request {
59
59
  if (durability_level != protocol::durability_level::none) {
60
60
  encoded.body().durability(durability_level, durability_timeout);
61
61
  }
62
+ return {};
62
63
  }
63
64
  };
64
65
 
65
66
  insert_response
66
- make_response(std::error_code ec, insert_request& request, insert_request::encoded_response_type encoded)
67
+ make_response(std::error_code ec, insert_request& request, insert_request::encoded_response_type&& encoded)
67
68
  {
68
69
  insert_response response{ request.id, encoded.opaque(), ec };
69
70
  if (ec && response.opaque == 0) {
@@ -39,6 +39,7 @@ struct lookup_in_response {
39
39
  std::error_code ec{};
40
40
  std::uint64_t cas{};
41
41
  std::vector<field> fields{};
42
+ bool deleted{ false };
42
43
  };
43
44
 
44
45
  struct lookup_in_request {
@@ -53,7 +54,7 @@ struct lookup_in_request {
53
54
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
54
55
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
55
56
 
56
- void encode_to(encoded_request_type& encoded)
57
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
57
58
  {
58
59
  for (std::size_t i = 0; i < specs.entries.size(); ++i) {
59
60
  auto& entry = specs.entries[i];
@@ -72,16 +73,21 @@ struct lookup_in_request {
72
73
  encoded.body().id(id);
73
74
  encoded.body().access_deleted(access_deleted);
74
75
  encoded.body().specs(specs);
76
+ return {};
75
77
  }
76
78
  };
77
79
 
78
80
  lookup_in_response
79
- make_response(std::error_code ec, lookup_in_request& request, lookup_in_request::encoded_response_type encoded)
81
+ make_response(std::error_code ec, lookup_in_request& request, lookup_in_request::encoded_response_type&& encoded)
80
82
  {
81
83
  lookup_in_response response{ request.id, encoded.opaque(), ec };
82
84
  if (ec && response.opaque == 0) {
83
85
  response.opaque = request.opaque;
84
86
  }
87
+ if (encoded.status() == protocol::status::subdoc_success_deleted ||
88
+ encoded.status() == protocol::status::subdoc_multi_path_failure_deleted) {
89
+ response.deleted = true;
90
+ }
85
91
  if (!ec) {
86
92
  response.cas = encoded.cas();
87
93
  response.fields.resize(request.specs.entries.size());
@@ -50,6 +50,7 @@ struct mutate_in_response {
50
50
  mutation_token token{};
51
51
  std::vector<field> fields{};
52
52
  std::optional<std::size_t> first_error_index{};
53
+ bool deleted{ false };
53
54
  };
54
55
 
55
56
  struct mutate_in_request {
@@ -61,6 +62,7 @@ struct mutate_in_request {
61
62
  uint32_t opaque{};
62
63
  uint64_t cas{ 0 };
63
64
  bool access_deleted{ false };
65
+ bool create_as_deleted{ false };
64
66
  std::optional<std::uint32_t> expiry{};
65
67
  protocol::mutate_in_request_body::store_semantics_type store_semantics{
66
68
  protocol::mutate_in_request_body::store_semantics_type::replace
@@ -71,8 +73,11 @@ struct mutate_in_request {
71
73
  std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
72
74
  io::retry_context<io::retry_strategy::best_effort> retries{ false };
73
75
 
74
- void encode_to(encoded_request_type& encoded)
76
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&& ctx)
75
77
  {
78
+ if (create_as_deleted && !ctx.supports_feature(protocol::hello_feature::subdoc_create_as_deleted)) {
79
+ return std::make_error_code(error::common_errc::unsupported_operation);
80
+ }
76
81
  for (std::size_t i = 0; i < specs.entries.size(); ++i) {
77
82
  auto& entry = specs.entries[i];
78
83
  entry.original_index = i;
@@ -93,21 +98,27 @@ struct mutate_in_request {
93
98
  encoded.body().expiry(*expiry);
94
99
  }
95
100
  encoded.body().access_deleted(access_deleted);
101
+ encoded.body().create_as_deleted(create_as_deleted);
96
102
  encoded.body().store_semantics(store_semantics);
97
103
  encoded.body().specs(specs);
98
104
  if (durability_level != protocol::durability_level::none) {
99
105
  encoded.body().durability(durability_level, durability_timeout);
100
106
  }
107
+ return {};
101
108
  }
102
109
  };
103
110
 
104
111
  mutate_in_response
105
- make_response(std::error_code ec, mutate_in_request& request, mutate_in_request::encoded_response_type encoded)
112
+ make_response(std::error_code ec, mutate_in_request& request, mutate_in_request::encoded_response_type&& encoded)
106
113
  {
107
114
  mutate_in_response response{ request.id, encoded.opaque(), ec };
108
115
  if (ec && response.opaque == 0) {
109
116
  response.opaque = request.opaque;
110
117
  }
118
+ if (encoded.status() == protocol::status::subdoc_success_deleted ||
119
+ encoded.status() == protocol::status::subdoc_multi_path_failure_deleted) {
120
+ response.deleted = true;
121
+ }
111
122
  if (!ec) {
112
123
  response.cas = encoded.cas();
113
124
  response.token = encoded.body().token();
@@ -0,0 +1,77 @@
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/cmd_prepend.hxx>
21
+ #include <protocol/durability_level.hxx>
22
+ #include <io/retry_context.hxx>
23
+
24
+ namespace couchbase::operations
25
+ {
26
+
27
+ struct prepend_response {
28
+ document_id id;
29
+ std::uint32_t opaque;
30
+ std::error_code ec{};
31
+ std::uint64_t cas{};
32
+ mutation_token token{};
33
+ };
34
+
35
+ struct prepend_request {
36
+ using encoded_request_type = protocol::client_request<protocol::prepend_request_body>;
37
+ using encoded_response_type = protocol::client_response<protocol::prepend_response_body>;
38
+
39
+ document_id id;
40
+ std::string value;
41
+ uint16_t partition{};
42
+ uint32_t opaque{};
43
+ protocol::durability_level durability_level{ protocol::durability_level::none };
44
+ std::optional<std::uint16_t> durability_timeout{};
45
+ std::chrono::milliseconds timeout{ timeout_defaults::key_value_timeout };
46
+ io::retry_context<io::retry_strategy::best_effort> retries{ false };
47
+
48
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, mcbp_context&&)
49
+ {
50
+ encoded.opaque(opaque);
51
+ encoded.partition(partition);
52
+ encoded.body().id(id);
53
+ encoded.body().content(value);
54
+ if (durability_level != protocol::durability_level::none) {
55
+ encoded.body().durability(durability_level, durability_timeout);
56
+ }
57
+ return {};
58
+ }
59
+ };
60
+
61
+ prepend_response
62
+ make_response(std::error_code ec, prepend_request& request, prepend_request::encoded_response_type&& encoded)
63
+ {
64
+ prepend_response response{ request.id, encoded.opaque(), ec };
65
+ if (ec && response.opaque == 0) {
66
+ response.opaque = request.opaque;
67
+ }
68
+ if (!ec) {
69
+ response.cas = encoded.cas();
70
+ response.token = encoded.body().token();
71
+ response.token.partition_id = request.partition;
72
+ response.token.bucket_name = response.id.bucket;
73
+ }
74
+ return response;
75
+ }
76
+
77
+ } // namespace couchbase::operations