userver: userver/storages/clickhouse/execution_result.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
execution_result.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/clickhouse/execution_result.hpp
4/// @brief Result accessor.
5
6#include <memory>
7#include <type_traits>
8
9#include <boost/pfr/core.hpp>
10
11#include <userver/storages/clickhouse/impl/block_wrapper_fwd.hpp>
12#include <userver/storages/clickhouse/io/impl/validate.hpp>
13
14#include <userver/storages/clickhouse/io/result_mapper.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace storages::clickhouse {
19
20// clang-format off
21
22/// Thin wrapper over underlying block of data, returned by
23/// storages::clickhouse::Cluster Execute methods
24///
25/// ## Usage example:
26///
27/// @snippet storages/tests/execute_chtest.cpp Sample CppToClickhouse specialization
28///
29/// @snippet storages/tests/execute_chtest.cpp Sample ExecutionResult usage
30
31// clang-format on
32class ExecutionResult final {
33 public:
34 explicit ExecutionResult(impl::BlockWrapperPtr);
35 ExecutionResult(ExecutionResult&&) noexcept;
36 ~ExecutionResult();
37
38 /// Returns number of columns in underlying block.
40
41 /// Returns number of rows in underlying block columns.
43
44 /// Converts underlying block to strongly-typed struct of vectors.
45 /// See @ref clickhouse_io for better understanding of `T`'s requirements.
46 template <typename T>
47 T As() &&;
48
49 /// Converts underlying block to iterable of strongly-typed struct.
50 /// See @ref clickhouse_io for better understanding of `T`'s requirements.
51 template <typename T>
52 auto AsRows() &&;
53
54 /// Converts underlying block to strongly-typed container.
55 /// See @ref clickhouse_io for better understanding
56 /// of `Container::value_type`'s requirements.
57 template <typename Container>
58 Container AsContainer() &&;
59
60 private:
61 impl::BlockWrapperPtr block_;
62};
63
64template <typename T>
65T ExecutionResult::As() && {
66 UASSERT(block_);
67 T result{};
68 io::impl::ValidateColumnsMapping(result);
69 io::impl::ValidateColumnsCount<T>(GetColumnsCount());
70
71 using MappedType = typename io::CppToClickhouse<T>::mapped_type;
72 io::ColumnsMapper<MappedType> mapper{*block_};
73
74 boost::pfr::for_each_field(result, mapper);
75
76 return result;
77}
78
79template <typename T>
80auto ExecutionResult::AsRows() && {
81 UASSERT(block_);
82 io::impl::ValidateRowsMapping<T>();
83 io::impl::ValidateColumnsCount<T>(GetColumnsCount());
84
85 return io::RowsMapper<T>{std::move(block_)};
86}
87
88template <typename Container>
89Container ExecutionResult::AsContainer() && {
90 UASSERT(block_);
91 using Row = typename Container::value_type;
92
93 Container result;
94 if constexpr (io::traits::kIsReservable<Container>) {
95 result.reserve(GetRowsCount());
96 }
97
98 auto rows = std::move(*this).AsRows<Row>();
99 std::move(rows.begin(), rows.end(), io::traits::Inserter(result));
100 return result;
101}
102
103} // namespace storages::clickhouse
104
105USERVER_NAMESPACE_END