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 bool operator==(
const std::default_sentinel_t& other)
const noexcept;
122 explicit CursorIterator(Cursor& cursor);
124 impl::ParseState* parse_state_{
nullptr};
130 explicit Cursor(
const NYdb::TResultSet& result_set);
133 Cursor(
const Cursor&) =
delete;
134 Cursor(Cursor&&)
noexcept =
default;
135 Cursor& operator=(
const Cursor&) =
delete;
136 Cursor& operator=(Cursor&&)
noexcept =
default;
138 size_t ColumnsCount()
const;
139 size_t RowsCount()
const;
149 std::size_t size()
const;
151 CursorIterator begin();
152 std::default_sentinel_t end();
156 friend class CursorIterator;
159 bool is_consumed_{
false};
161 utils::UniqueRef<impl::ParseState> parse_state_;
164class ExecuteResponse
final {
167 explicit ExecuteResponse(NYdb::NTable::TDataQueryResult&& query_result);
170 ExecuteResponse(
const ExecuteResponse&) =
delete;
171 ExecuteResponse(ExecuteResponse&&)
noexcept =
default;
172 ExecuteResponse& operator=(
const ExecuteResponse&) =
delete;
173 ExecuteResponse& operator=(ExecuteResponse&&) =
delete;
175 std::size_t GetCursorCount()
const;
176 Cursor GetCursor(std::size_t index)
const;
177 Cursor GetSingleCursor()
const;
187 void EnsureResultSetsNotEmpty()
const;
189 std::optional<NYdb::NTable::TQueryStats> query_stats_;
190 std::vector<NYdb::TResultSet> result_sets_;
193class ReadTableResults
final {
196 explicit ReadTableResults(NYdb::NTable::TTablePartIterator iterator);
199 std::optional<Cursor> GetNextResult();
201 ReadTableResults(
const ReadTableResults&) =
delete;
202 ReadTableResults(ReadTableResults&&)
noexcept =
default;
203 ReadTableResults& operator=(
const ReadTableResults&) =
delete;
204 ReadTableResults& operator=(ReadTableResults&&) =
delete;
207 NYdb::NTable::TTablePartIterator iterator_;
210class ScanQueryResults
final {
211 using TScanQueryPartIterator = NYdb::NTable::TScanQueryPartIterator;
214 using TScanQueryPart = NYdb::NTable::TScanQueryPart;
217 explicit ScanQueryResults(TScanQueryPartIterator iterator);
220 std::optional<TScanQueryPart> GetNextResult();
222 std::optional<Cursor> GetNextCursor();
224 ScanQueryResults(
const ScanQueryResults&) =
delete;
225 ScanQueryResults(ScanQueryResults&&)
noexcept =
default;
226 ScanQueryResults& operator=(
const ScanQueryResults&) =
delete;
227 ScanQueryResults& operator=(ScanQueryResults&&) =
delete;
230 TScanQueryPartIterator iterator_;
235 if (&
typeid(T) != parse_state_.row_type_id) {
236 parse_state_.cpp_to_ydb_field_mapping = impl::StructRowParser<T>::MakeCppToYdbFieldMapping(parse_state_.parser);
237 parse_state_.row_type_id = &
typeid(T);
239 return impl::StructRowParser<T>::ParseRow(parse_state_.parser, parse_state_.cpp_to_ydb_field_mapping);
243T Row::
Get(std::string_view column_name) {
245 ConsumedColumnsCheck(parse_state_.parser.ColumnIndex(impl::ToString(column_name)));
247 auto& column = GetColumn(column_name);
248 return Parse<T>(column, ParseContext{column_name});
252T Row::
Get(std::size_t column_index) {
254 ConsumedColumnsCheck(column_index);
256 auto& column = GetColumn(column_index);
257 const auto column_name = std::to_string(column_index);
258 return Parse<T>(column, ParseContext{column_name});