libpqxx
The C++ client library for PostgreSQL
Loading...
Searching...
No Matches
result_iter.hxx
1
9#ifndef PQXX_H_RESULT_ITER
10#define PQXX_H_RESULT_ITER
11
12#include <memory>
13
14#include "pqxx/strconv.hxx"
15
16namespace pqxx
17{
18class result;
19} // namespace pqxx
20
21
22namespace pqxx::internal
23{
24// C++20: Replace with generator?
26template<typename... TYPE> class result_iter
27{
28public:
29 using value_type = std::tuple<TYPE...>;
30
32 result_iter() = default;
33
34 explicit result_iter(result const &home) :
35 m_home{&home}, m_size{std::size(home)}
36 {
37 if (not std::empty(home))
38 read();
39 }
40 result_iter(result_iter const &) = default;
41
42 result_iter &operator++()
43 {
44 m_index++;
45 if (m_index >= m_size)
46 m_home = nullptr;
47 else
48 read();
49 return *this;
50 }
51
53 bool operator==(result_iter const &rhs) const
54 {
55 return m_home == rhs.m_home;
56 }
57 bool operator!=(result_iter const &rhs) const { return not(*this == rhs); }
58
59 value_type const &operator*() const { return m_value; }
60
61private:
62 void read() { (*m_home)[m_index].convert(m_value); }
63
64 result const *m_home{nullptr};
65 result::size_type m_index{0};
66 result::size_type m_size;
67 value_type m_value;
68};
69
70
71template<typename... TYPE> class result_iteration
72{
73public:
74 using iterator = result_iter<TYPE...>;
75
76 explicit result_iteration(result const &home) : m_home{home}
77 {
78 m_home.expect_columns(sizeof...(TYPE));
79 }
80
81 iterator begin() const
82 {
83 if (std::size(m_home) == 0)
84 return end();
85 else
86 return iterator{m_home};
87 }
88 iterator end() const { return {}; }
89
90private:
91 pqxx::result const m_home;
92};
93} // namespace pqxx::internal
94
95
96template<typename... TYPE> inline auto pqxx::result::iter() const
97{
98 return pqxx::internal::result_iteration<TYPE...>{*this};
99}
100
101
102template<typename CALLABLE>
103inline void pqxx::result::for_each(CALLABLE &&func) const
104{
105 using args_tuple = internal::args_t<decltype(func)>;
106 constexpr auto sz{std::tuple_size_v<args_tuple>};
107 static_assert(
108 sz > 0,
109 "Callback for for_each must take parameters, one for each column in the "
110 "result.");
111
112 auto const cols{this->columns()};
113 if (sz != cols)
115 "Callback to for_each takes ", sz, "parameter", (sz == 1) ? "" : "s",
116 ", but result set has ", cols, "field", (cols == 1) ? "" : "s", ".")};
117
119 for (auto const r : *this) std::apply(func, r.as_tuple<pass_tuple>());
120}
121#endif
Iterator for looped unpacking of a result.
Definition result_iter.hxx:27
result_iter()=default
Construct an "end" iterator.
bool operator==(result_iter const &rhs) const
Comparison only works for comparing to end().
Definition result_iter.hxx:53
Definition result_iter.hxx:72
Result set containing data returned by a query or command.
Definition result.hxx:92
void for_each(CALLABLE &&func) const
Run func on each row, passing the row's fields as parameters.
Definition result_iter.hxx:103
result expect_columns(row_size_type cols) const
Expect that result consists of exactly cols columns.
Definition result.hxx:363
auto iter() const
Iterate rows, reading them directly into a tuple of "TYPE...".
Definition result_iter.hxx:96
Error in usage of libpqxx library, similar to std::logic_error.
Definition except.hxx:249
Internal items for libpqxx' own use. Do not use these yourself.
Definition encodings.cxx:33
std::string concat(TYPE... item)
Efficiently combine a bunch of items into one big string.
Definition concat.hxx:31
decltype(args_f(std::declval< CALLABLE >())) args_t
A callable's parameter types, as a tuple.
Definition util.hxx:616
decltype(strip_types(std::declval< TYPES... >())) strip_types_t
Take a tuple type and apply strip_t to its component types.
Definition util.hxx:629
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx:27
strip_t< decltype(*std::begin(std::declval< CONTAINER >()))> value_type
The type of a container's elements.
Definition types.hxx:96