userver: userver/storages/mysql/cursor_result_set.hpp Source File
Loading...
Searching...
No Matches
cursor_result_set.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/mysql/cursor_result_set.hpp
4
5#include <userver/storages/mysql/statement_result_set.hpp>
6
7USERVER_NAMESPACE_BEGIN
8
9namespace storages::mysql {
10
11/// @brief A wrapper for read-only cursor.
12///
13/// Although this class can be constructed from StatementResultSet, you should
14/// always retrieve it from `storages::mysql::Cluster` for correct behavior.
15template <typename T>
16class CursorResultSet final {
17 public:
18 explicit CursorResultSet(StatementResultSet&& result_set);
19 ~CursorResultSet();
20
21 CursorResultSet(const CursorResultSet& other) = delete;
22 CursorResultSet(CursorResultSet&& other) noexcept;
23
24 /// @brief Fetches all the rows from cursor and for each new row executes
25 /// row_callback.
26 ///
27 /// Usable when the result set is expected to be big enough to put too
28 /// much memory pressure if fetched as a whole.
29 // TODO : deadline?
30 template <typename RowCallback>
31 void ForEach(RowCallback&& row_callback, engine::Deadline deadline) &&;
32
33 private:
34 StatementResultSet result_set_;
35};
36
37template <typename T>
38CursorResultSet<T>::CursorResultSet(StatementResultSet&& result_set)
39 : result_set_{std::move(result_set)} {}
40
41template <typename T>
42CursorResultSet<T>::~CursorResultSet() = default;
43
44template <typename T>
45CursorResultSet<T>::CursorResultSet(CursorResultSet<T>&& other) noexcept =
46 default;
47
48template <typename T>
49template <typename RowCallback>
50void CursorResultSet<T>::ForEach(
51 RowCallback&& row_callback,
52 // TODO : think about separate deadline here
53 [[maybe_unused]] engine::Deadline deadline) && {
54 using IntermediateStorage = std::vector<T>;
55
56 bool keep_going = true;
57 auto extractor = impl::io::TypedExtractor<IntermediateStorage, T, RowTag>{};
58
59 while (keep_going) {
60 tracing::ScopeTime fetch{impl::tracing::kFetchScope};
61 keep_going = result_set_.FetchResult(extractor);
62
63 fetch.Reset(impl::tracing::kForEachScope);
64 IntermediateStorage data{extractor.ExtractData()};
65 for (auto&& row : data) {
66 row_callback(std::move(row));
67 }
68 }
69}
70
71} // namespace storages::mysql
72
73USERVER_NAMESPACE_END