3#include "data/cassandra/impl/ManagedObject.hpp"
4#include "data/cassandra/impl/Tuple.hpp"
5#include "util/UnsupportedType.hpp"
7#include <boost/uuid/string_generator.hpp>
8#include <boost/uuid/uuid.hpp>
10#include <xrpl/basics/base_uint.h>
11#include <xrpl/protocol/AccountID.h>
26namespace data::cassandra::impl {
28template <
typename Type>
30extractColumn(CassRow
const* row, std::size_t idx)
35 auto throwErrorIfNeeded = [](CassError rc, std::string_view label) {
37 auto const tag =
'[' + std::string{label} +
']';
38 throw std::logic_error(tag +
": " + cass_error_desc(rc));
42 using DecayedType = std::decay_t<Type>;
43 using UintTupleType = std::tuple<uint32_t, uint32_t>;
44 using UCharVectorType = std::vector<unsigned char>;
46 if constexpr (std::is_same_v<DecayedType, ripple::uint256>) {
47 cass_byte_t
const* buf =
nullptr;
48 std::size_t bufSize = 0;
49 auto const rc = cass_value_get_bytes(cass_row_get_column(row, idx), &buf, &bufSize);
50 throwErrorIfNeeded(rc,
"Extract ripple::uint256");
51 output = ripple::uint256::fromVoid(buf);
52 }
else if constexpr (std::is_same_v<DecayedType, ripple::AccountID>) {
53 cass_byte_t
const* buf =
nullptr;
54 std::size_t bufSize = 0;
55 auto const rc = cass_value_get_bytes(cass_row_get_column(row, idx), &buf, &bufSize);
56 throwErrorIfNeeded(rc,
"Extract ripple::AccountID");
57 output = ripple::AccountID::fromVoid(buf);
58 }
else if constexpr (std::is_same_v<DecayedType, UCharVectorType>) {
59 cass_byte_t
const* buf =
nullptr;
60 std::size_t bufSize = 0;
61 auto const rc = cass_value_get_bytes(cass_row_get_column(row, idx), &buf, &bufSize);
62 throwErrorIfNeeded(rc,
"Extract vector<unsigned char>");
63 output = UCharVectorType{buf, buf + bufSize};
64 }
else if constexpr (std::is_same_v<DecayedType, UintTupleType>) {
65 auto const* tuple = cass_row_get_column(row, idx);
66 output = TupleIterator::fromTuple(tuple).extract<uint32_t, uint32_t>();
67 }
else if constexpr (std::is_convertible_v<DecayedType, std::string>) {
68 char const* value =
nullptr;
70 auto const rc = cass_value_get_string(cass_row_get_column(row, idx), &value, &len);
71 throwErrorIfNeeded(rc,
"Extract string");
72 output = std::string{value, len};
73 }
else if constexpr (std::is_same_v<DecayedType, bool>) {
74 cass_bool_t flag = cass_bool_t::cass_false;
75 auto const rc = cass_value_get_bool(cass_row_get_column(row, idx), &flag);
76 throwErrorIfNeeded(rc,
"Extract bool");
77 output = flag != cass_bool_t::cass_false;
80 else if constexpr (std::is_convertible_v<DecayedType, int64_t>) {
82 auto const rc = cass_value_get_int64(cass_row_get_column(row, idx), &out);
83 throwErrorIfNeeded(rc,
"Extract int64");
84 output =
static_cast<DecayedType
>(out);
85 }
else if constexpr (std::is_convertible_v<DecayedType, boost::uuids::uuid>) {
87 auto const rc = cass_value_get_uuid(cass_row_get_column(row, idx), &uuid);
88 throwErrorIfNeeded(rc,
"Extract uuid");
89 std::string uuidStr(CASS_UUID_STRING_LENGTH,
'0');
90 cass_uuid_string(uuid, uuidStr.data());
92 output = boost::uuids::string_generator{}(uuidStr);
101struct Result :
public ManagedObject<CassResult const> {
102 Result(CassResult
const* ptr);
104 [[nodiscard]] std::size_t
110 template <
typename... RowTypes>
111 std::optional<std::tuple<RowTypes...>>
113 requires(std::tuple_size<std::tuple<RowTypes...>>{} > 1)
116 auto const* row = cass_result_first_row(*
this);
121 auto advanceId = [&idx]() {
return idx++; };
123 return std::make_optional<std::tuple<RowTypes...>>(
124 {extractColumn<RowTypes>(row, advanceId())...}
128 template <
typename RowType>
129 std::optional<RowType>
133 auto const* row = cass_result_first_row(*
this);
136 return std::make_optional<RowType>(extractColumn<RowType>(row, 0));
140class ResultIterator :
public ManagedObject<CassIterator> {
141 bool hasMore_ =
false;
144 ResultIterator(CassIterator* ptr);
146 [[nodiscard]]
static ResultIterator
147 fromResult(
Result const& result);
149 [[maybe_unused]]
bool
155 template <
typename... RowTypes>
156 std::tuple<RowTypes...>
157 extractCurrentRow()
const
161 auto const* row = cass_iterator_get_row(*
this);
164 auto advanceId = [&idx]() {
return idx++; };
166 return {extractColumn<RowTypes>(row, advanceId())...};
170template <
typename... Types>
171class ResultExtractor {
172 std::reference_wrapper<Result const> ref_;
178 using iterator_category = std::input_iterator_tag;
179 using difference_type = std::size_t;
180 using value_type = std::tuple<Types...>;
182 Iterator(
ResultIterator iterator) : iterator_{std::move(iterator)}
186 Iterator(Iterator
const&) =
delete;
188 operator=(Iterator
const&) =
delete;
193 return iterator_.extractCurrentRow<Types...>();
199 return iterator_.extractCurrentRow<Types...>();
205 iterator_.moveForward();
212 return not iterator_.hasMore();
219 ResultExtractor(
Result const& result) : ref_{std::cref(result)}
226 return ResultIterator::fromResult(ref_);
Definition Result.hpp:140
static constexpr bool Unsupported
used for compile time checking of unsupported types
Definition UnsupportedType.hpp:7
Definition Result.hpp:175
Definition Result.hpp:101