3#include <ydb-cpp-sdk/client/result/result.h>
4#include <ydb-cpp-sdk/client/table/table.h>
12#include <userver/utils/not_null.hpp>
13#include <userver/ydb/impl/cast.hpp>
14#include <userver/ydb/io/insert_row.hpp>
15#include <userver/ydb/io/list.hpp>
16#include <userver/ydb/io/primitives.hpp>
17#include <userver/ydb/io/traits.hpp>
18#include <userver/ydb/types.hpp>
21class TResultSetParser;
26class TDataQueryResult;
27class TTablePartIterator;
31USERVER_NAMESPACE_BEGIN
38struct StructRowParser;
40struct ParseState
final {
41 explicit ParseState(
const NYdb::TResultSet& result_set);
43 NYdb::TResultSetParser parser;
44 const std::type_info* row_type_id{
nullptr};
45 std::unique_ptr<std::size_t[]> cpp_to_ydb_field_mapping{};
50using ValueType = NYdb::EPrimitiveType;
58 explicit Row(impl::ParseState& parse_state);
61 Row(
const Row&) =
delete;
62 Row(Row&&)
noexcept =
default;
63 Row& operator=(
const Row&) =
delete;
64 Row& operator=(Row&&) =
delete;
79 T
Get(std::string_view column_name);
85 T
Get(std::size_t column_index);
88 NYdb::TValueParser& GetColumn(std::size_t index);
89 NYdb::TValueParser& GetColumn(std::string_view name);
91 void ConsumedColumnsCheck(std::size_t column_index);
93 impl::ParseState& parse_state_;
94 std::vector<
bool> consumed_columns_;
97class CursorIterator
final {
99 using difference_type = std::ptrdiff_t;
100 using value_type = Row;
101 using reference = Row;
102 using iterator_category = std::input_iterator_tag;
104 CursorIterator() =
default;
106 CursorIterator(
const CursorIterator&) =
delete;
107 CursorIterator(CursorIterator&&)
noexcept =
default;
108 CursorIterator& operator=(
const CursorIterator&) =
delete;
109 CursorIterator& operator=(CursorIterator&&) =
default;
111 Row operator*()
const;
113 CursorIterator& operator++();
115 void operator++(
int);
117#if __cpp_lib_ranges >= 201911L
118 bool operator==(
const std::default_sentinel_t& other)
const noexcept;
120 bool operator==(
const CursorIterator& other)
const noexcept;
126 explicit CursorIterator(Cursor& cursor);
128 impl::ParseState* parse_state_{
nullptr};
134 explicit Cursor(
const NYdb::TResultSet& result_set);
137 Cursor(
const Cursor&) =
delete;
138 Cursor(Cursor&&)
noexcept =
default;
139 Cursor& operator=(
const Cursor&) =
delete;
140 Cursor& operator=(Cursor&&)
noexcept =
default;
142 size_t ColumnsCount()
const;
143 size_t RowsCount()
const;
153 std::size_t size()
const;
155 CursorIterator begin();
157#if __cpp_lib_ranges >= 201911L
158 std::default_sentinel_t end();
160 CursorIterator end();
165 friend class CursorIterator;
168 bool is_consumed_{
false};
170 utils::UniqueRef<impl::ParseState> parse_state_;
173class ExecuteResponse
final {
176 explicit ExecuteResponse(NYdb::NTable::TDataQueryResult&& query_result);
179 ExecuteResponse(
const ExecuteResponse&) =
delete;
180 ExecuteResponse(ExecuteResponse&&)
noexcept =
default;
181 ExecuteResponse& operator=(
const ExecuteResponse&) =
delete;
182 ExecuteResponse& operator=(ExecuteResponse&&) =
delete;
184 std::size_t GetCursorCount()
const;
185 Cursor GetCursor(std::size_t index)
const;
186 Cursor GetSingleCursor()
const;
196 void EnsureResultSetsNotEmpty()
const;
198 std::optional<NYdb::NTable::TQueryStats> query_stats_;
199 std::vector<NYdb::TResultSet> result_sets_;
202class ReadTableResults
final {
205 explicit ReadTableResults(NYdb::NTable::TTablePartIterator iterator);
208 std::optional<Cursor> GetNextResult();
210 ReadTableResults(
const ReadTableResults&) =
delete;
211 ReadTableResults(ReadTableResults&&)
noexcept =
default;
212 ReadTableResults& operator=(
const ReadTableResults&) =
delete;
213 ReadTableResults& operator=(ReadTableResults&&) =
delete;
216 NYdb::NTable::TTablePartIterator iterator_;
219class ScanQueryResults
final {
220 using TScanQueryPartIterator = NYdb::NTable::TScanQueryPartIterator;
223 using TScanQueryPart = NYdb::NTable::TScanQueryPart;
226 explicit ScanQueryResults(TScanQueryPartIterator iterator);
229 std::optional<TScanQueryPart> GetNextResult();
231 std::optional<Cursor> GetNextCursor();
233 ScanQueryResults(
const ScanQueryResults&) =
delete;
234 ScanQueryResults(ScanQueryResults&&)
noexcept =
default;
235 ScanQueryResults& operator=(
const ScanQueryResults&) =
delete;
236 ScanQueryResults& operator=(ScanQueryResults&&) =
delete;
239 TScanQueryPartIterator iterator_;
244 if (&
typeid(T) != parse_state_.row_type_id) {
245 parse_state_.cpp_to_ydb_field_mapping =
246 impl::StructRowParser<T>::MakeCppToYdbFieldMapping(parse_state_.parser);
247 parse_state_.row_type_id = &
typeid(T);
249 return impl::StructRowParser<T>::ParseRow(
250 parse_state_.parser, parse_state_.cpp_to_ydb_field_mapping);
254T Row::
Get(std::string_view column_name) {
256 ConsumedColumnsCheck(
257 parse_state_.parser.ColumnIndex(impl::ToString(column_name)));
259 auto& column = GetColumn(column_name);
260 return Parse<T>(column, ParseContext{column_name});
264T Row::
Get(std::size_t column_index) {
266 ConsumedColumnsCheck(column_index);
268 auto& column = GetColumn(column_index);
269 const auto column_name = std::to_string(column_index);
270 return Parse<T>(column, ParseContext{column_name});