3#include <ydb-cpp-sdk/v2/client/query/fwd.h>
4#include <ydb-cpp-sdk/v2/client/result/result.h>
5#include <ydb-cpp-sdk/v2/client/table/table.h>
13#include <userver/utils/not_null.hpp>
14#include <userver/ydb/impl/cast.hpp>
15#include <userver/ydb/io/insert_row.hpp>
16#include <userver/ydb/io/list.hpp>
17#include <userver/ydb/io/primitives.hpp>
18#include <userver/ydb/io/traits.hpp>
19#include <userver/ydb/types.hpp>
21USERVER_NAMESPACE_BEGIN
28struct StructRowParser;
30struct ParseState
final {
31 explicit ParseState(
const NYdb::TResultSet& result_set);
33 NYdb::TResultSetParser parser;
34 const std::type_info* row_type_id{
nullptr};
35 std::unique_ptr<std::size_t[]> cpp_to_ydb_field_mapping{};
40using ValueType = NYdb::EPrimitiveType;
48 explicit Row(impl::ParseState& parse_state);
51 Row(
const Row&) =
delete;
52 Row(Row&&)
noexcept =
default;
53 Row& operator=(
const Row&) =
delete;
54 Row& operator=(Row&&) =
delete;
69 T
Get(std::string_view column_name);
75 T
Get(std::size_t column_index);
78 NYdb::TValueParser& GetColumn(std::size_t index);
79 NYdb::TValueParser& GetColumn(std::string_view name);
81 void ConsumedColumnsCheck(std::size_t column_index);
83 impl::ParseState& parse_state_;
84 std::vector<
bool> consumed_columns_;
87class CursorIterator
final {
89 using difference_type = std::ptrdiff_t;
90 using value_type = Row;
91 using reference = Row;
92 using iterator_category = std::input_iterator_tag;
94 CursorIterator() =
default;
96 CursorIterator(
const CursorIterator&) =
delete;
97 CursorIterator(CursorIterator&&)
noexcept =
default;
98 CursorIterator& operator=(
const CursorIterator&) =
delete;
99 CursorIterator& operator=(CursorIterator&&) =
default;
101 Row operator*()
const;
103 CursorIterator& operator++();
105 void operator++(
int);
107 bool operator==(
const std::default_sentinel_t& other)
const noexcept;
112 explicit CursorIterator(Cursor& cursor);
114 impl::ParseState* parse_state_{
nullptr};
120 explicit Cursor(
const NYdb::TResultSet& result_set);
123 Cursor(
const Cursor&) =
delete;
124 Cursor(Cursor&&)
noexcept =
default;
125 Cursor& operator=(
const Cursor&) =
delete;
126 Cursor& operator=(Cursor&&)
noexcept =
default;
128 size_t ColumnsCount()
const;
129 size_t RowsCount()
const;
139 std::size_t size()
const;
141 CursorIterator begin();
142 std::default_sentinel_t end();
146 friend class CursorIterator;
149 bool is_consumed_{
false};
151 utils::UniqueRef<impl::ParseState> parse_state_;
154class ExecuteResponse
final {
157 explicit ExecuteResponse(NYdb::NTable::TDataQueryResult&& query_result);
158 explicit ExecuteResponse(NYdb::NQuery::TExecuteQueryResult&& query_result);
161 ExecuteResponse(
const ExecuteResponse&) =
delete;
162 ExecuteResponse(ExecuteResponse&&)
noexcept =
default;
163 ExecuteResponse& operator=(
const ExecuteResponse&) =
delete;
164 ExecuteResponse& operator=(ExecuteResponse&&) =
delete;
166 std::size_t GetCursorCount()
const;
167 Cursor GetCursor(std::size_t index)
const;
168 Cursor GetSingleCursor()
const;
178 void EnsureResultSetsNotEmpty()
const;
180 std::optional<NYdb::NTable::TQueryStats> query_stats_;
181 std::vector<NYdb::TResultSet> result_sets_;
184class ReadTableResults
final {
187 explicit ReadTableResults(NYdb::NTable::TTablePartIterator iterator);
190 std::optional<Cursor> GetNextResult();
192 ReadTableResults(
const ReadTableResults&) =
delete;
193 ReadTableResults(ReadTableResults&&)
noexcept =
default;
194 ReadTableResults& operator=(
const ReadTableResults&) =
delete;
195 ReadTableResults& operator=(ReadTableResults&&) =
delete;
198 NYdb::NTable::TTablePartIterator iterator_;
201class ScanQueryResults
final {
202 using TScanQueryPartIterator = NYdb::NTable::TScanQueryPartIterator;
205 using TScanQueryPart = NYdb::NTable::TScanQueryPart;
208 explicit ScanQueryResults(TScanQueryPartIterator iterator);
211 std::optional<TScanQueryPart> GetNextResult();
213 std::optional<Cursor> GetNextCursor();
215 ScanQueryResults(
const ScanQueryResults&) =
delete;
216 ScanQueryResults(ScanQueryResults&&)
noexcept =
default;
217 ScanQueryResults& operator=(
const ScanQueryResults&) =
delete;
218 ScanQueryResults& operator=(ScanQueryResults&&) =
delete;
221 TScanQueryPartIterator iterator_;
226 if (&
typeid(T) != parse_state_.row_type_id) {
227 parse_state_.cpp_to_ydb_field_mapping = impl::StructRowParser<T>::MakeCppToYdbFieldMapping(parse_state_.parser);
228 parse_state_.row_type_id = &
typeid(T);
230 return impl::StructRowParser<T>::ParseRow(parse_state_.parser, parse_state_.cpp_to_ydb_field_mapping);
234T Row::
Get(std::string_view column_name) {
236 ConsumedColumnsCheck(parse_state_.parser.ColumnIndex(impl::ToString(column_name)));
238 auto& column = GetColumn(column_name);
239 return Parse<T>(column, ParseContext{column_name});
243T Row::
Get(std::size_t column_index) {
245 ConsumedColumnsCheck(column_index);
247 auto& column = GetColumn(column_index);
248 const auto column_name = std::to_string(column_index);
249 return Parse<T>(column, ParseContext{column_name});