Couchbase Transactions C++ Client  1.0.0
Transactions client for couchbase
transaction_get_result.hxx
1 /*
2  * Copyright 2021 Couchbase, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <ostream>
20 
21 #include <boost/algorithm/string/split.hpp>
22 
23 #include <couchbase/internal/nlohmann/json.hpp>
24 
26 #include <couchbase/transactions/document_metadata.hxx>
27 #include <couchbase/transactions/transaction_links.hxx>
28 #include <utility>
29 
30 namespace couchbase
31 {
32 namespace transactions
33 {
39  {
40  private:
41  collection& collection_;
42  nlohmann::json value_;
43  std::string id_;
44  uint64_t cas_;
45  transaction_links links_;
46 
48  const boost::optional<document_metadata> metadata_;
49 
50  public:
53  : collection_(doc.collection_)
54  , value_(doc.value_)
55  , id_(doc.id_)
56  , links_(doc.links_)
57  , metadata_(doc.metadata_)
58  , cas_(doc.cas_)
59  {
60  }
61 
63  template<typename Content>
64  transaction_get_result(std::string id,
65  Content content,
66  uint64_t cas,
69  boost::optional<document_metadata> metadata)
70  : id_(std::move(id))
71  , cas_(cas)
72  , collection_(collection)
73  , links_(std::move(links))
74  , metadata_(std::move(metadata))
75  , value_(std::move(content))
76  {
77  }
78 
80  template<typename Content>
82  {
83  transaction_links links(document.links().atr_id(),
84  document.links().atr_bucket_name(),
85  document.links().atr_scope_name(),
86  document.links().atr_collection_name(),
87  document.links().staged_transaction_id(),
88  document.links().staged_attempt_id(),
89  document.links().staged_content<Content>(),
90  document.links().cas_pre_txn(),
91  document.links().revid_pre_txn(),
92  document.links().exptime_pre_txn(),
93  document.links().crc32_of_staging(),
94  document.links().op(),
95  document.links().forward_compat(),
96  document.links().is_deleted());
97 
98  return transaction_get_result(document.id(), content, document.cas(), document.collection_ref(), links, document.metadata());
99  }
100 
102  static transaction_get_result create_from(collection& collection, std::string id, result res)
103  {
104  boost::optional<std::string> atr_id;
105  boost::optional<std::string> transaction_id;
106  boost::optional<std::string> attempt_id;
107  boost::optional<nlohmann::json> staged_content;
108  boost::optional<std::string> atr_bucket_name;
109  boost::optional<std::string> atr_scope_name;
110  boost::optional<std::string> atr_collection_name;
111  boost::optional<nlohmann::json> forward_compat;
112 
113  // read from xattrs.txn.restore
114  boost::optional<std::string> cas_pre_txn;
115  boost::optional<std::string> revid_pre_txn;
116  boost::optional<uint32_t> exptime_pre_txn;
117  boost::optional<std::string> crc32_of_staging;
118 
119  // read from $document
120  boost::optional<std::string> cas_from_doc;
121  boost::optional<std::string> revid_from_doc;
122  boost::optional<uint32_t> exptime_from_doc;
123  boost::optional<std::string> crc32_from_doc;
124 
125  boost::optional<std::string> op;
126  nlohmann::json content;
127 
128  if (res.values[0].value) {
129  atr_id = res.values[0].value->get<std::string>();
130  }
131  if (res.values[1].value) {
132  transaction_id = res.values[1].value->get<std::string>();
133  }
134  if (res.values[2].value) {
135  attempt_id = res.values[2].value->get<std::string>();
136  }
137  if (res.values[3].value) {
138  staged_content = res.values[3].value->get<nlohmann::json>();
139  }
140  if (res.values[4].value) {
141  atr_bucket_name = res.values[4].value->get<std::string>();
142  }
143  if (res.values[5].value) {
144  std::string name = res.values[5].value->get<std::string>();
145  std::vector<std::string> splits;
146  boost::split(splits, name, [](char c) { return c == '.'; });
147  atr_scope_name = splits[0];
148  atr_collection_name = splits[1];
149  }
150  if (res.values[6].value) {
151  nlohmann::json restore = *res.values[6].value;
152  cas_pre_txn = restore["CAS"].get<std::string>();
153  // only present in 6.5+
154  revid_pre_txn = restore["revid"].get<std::string>();
155  exptime_pre_txn = restore["exptime"].get<uint32_t>();
156  }
157  if (res.values[7].value) {
158  op = res.values[7].value->get<std::string>();
159  }
160  if (res.values[8].value) {
161  nlohmann::json doc = *res.values[8].value;
162  cas_from_doc = doc["CAS"].get<std::string>();
163  // only present in 6.5+
164  revid_from_doc = doc["revid"].get<std::string>();
165  exptime_from_doc = doc["exptime"].get<uint32_t>();
166  crc32_from_doc = doc["value_crc32c"].get<std::string>();
167  }
168  if (res.values[9].value) {
169  crc32_of_staging = res.values[9].value.get();
170  }
171  if (res.values[10].value) {
172  forward_compat = res.values[10].value.get();
173  } else {
174  forward_compat = nlohmann::json::object();
175  }
176  if (res.values[11].value) {
177  content = res.values[11].value.get();
178  } else {
179  content = nlohmann::json::object();
180  }
181 
182  transaction_links links(atr_id,
183  atr_bucket_name,
184  atr_scope_name,
185  atr_collection_name,
186  transaction_id,
187  attempt_id,
188  staged_content,
189  cas_pre_txn,
190  revid_pre_txn,
191  exptime_pre_txn,
192  crc32_of_staging,
193  op,
194  forward_compat,
195  res.is_deleted);
196  document_metadata md(cas_from_doc, revid_from_doc, exptime_from_doc, crc32_from_doc);
197  return transaction_get_result(id, content, res.cas, collection, links, boost::make_optional(md));
198  }
199 
201  template<typename Content>
203  {
204  if (this != &other) {
205  this->collection_ = other.collection_;
206  this->value_ = other.value_;
207  this->id_ = other.id_;
208  this->links_ = other.links_;
209  }
210  return *this;
211  }
212 
218  CB_NODISCARD collection& collection_ref()
219  {
220  return collection_;
221  }
222 
262  template<typename Content>
263  CB_NODISCARD Content content() const
264  {
265  return value_.get<Content>();
266  }
267 
273  CB_NODISCARD const std::string& id() const
274  {
275  return id_;
276  }
277 
283  CB_NODISCARD uint64_t cas() const
284  {
285  return cas_;
286  }
287 
289  CB_NODISCARD transaction_links links() const
290  {
291  return links_;
292  }
293 
300  template<typename Content>
301  void content(const Content& content)
302  {
303  value_ = content;
304  }
305 
311  void cas(uint64_t cas)
312  {
313  cas_ = cas;
314  }
315 
321  CB_NODISCARD const boost::optional<document_metadata>& metadata() const
322  {
323  return metadata_;
324  }
325 
327  template<typename OStream>
328  friend OStream& operator<<(OStream& os, const transaction_get_result document)
329  {
330  os << "transaction_get_result{id: " << document.id_ << ", cas: " << document.cas_
331  << ", bucket: " << document.collection_.bucket_name() << ", coll: " << document.collection_.name()
332  << ", links_: " << document.links_ << "}";
333  return os;
334  }
335  };
336 } // namespace transactions
337 } // namespace couchbase
Definition: bucket.hxx:33
transaction_get_result(const transaction_get_result &doc)
Definition: transaction_get_result.hxx:53
CB_NODISCARD const boost::optional< document_metadata > & metadata() const
Get document metadata.
Definition: transaction_get_result.hxx:327
STL namespace.
The result of an operation on a cluster.
Definition: result.hxx:113
Encapsulates results of an individual transaction operation.
Definition: transaction_get_result.hxx:38
friend OStream & operator<<(OStream &os, const transaction_get_result document)
Definition: transaction_get_result.hxx:335
CB_NODISCARD const std::string & name() const
Get name of collection.
Definition: collection.hxx:230
CB_NODISCARD uint64_t cas() const
Get document CAS.
Definition: transaction_get_result.hxx:288
CB_NODISCARD const std::string & bucket_name() const
Get name of bucket for this collection.
Definition: collection.hxx:250
transaction_get_result & operator=(const transaction_get_result &other)
Definition: transaction_get_result.hxx:207
CB_NODISCARD Content content() const
Content of the document.
Definition: transaction_get_result.hxx:268
static transaction_get_result create_from(transaction_get_result &document, Content content)
Definition: transaction_get_result.hxx:84
uint64_t cas
CAS for document, if any.
Definition: result.hxx:117
CB_NODISCARD transaction_links links() const
Definition: transaction_get_result.hxx:295
std::vector< subdoc_result > values
results of subdoc spec operations
Definition: result.hxx:126
Exposes collection-level kv operations.
Definition: collection.hxx:46
CB_NODISCARD collection & collection_ref()
Collection that contains this document.
Definition: transaction_get_result.hxx:223
CB_NODISCARD const std::string & id() const
Get document id.
Definition: transaction_get_result.hxx:278