libpqxx 7.7.4
row.hxx
1/* Definitions for the pqxx::result class and support classes.
2 *
3 * pqxx::result represents the set of result rows from a database query.
4 *
5 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
6 *
7 * Copyright (c) 2000-2022, Jeroen T. Vermeulen.
8 *
9 * See COPYING for copyright license. If you did not receive a file called
10 * COPYING with this source code, please notify the distributor of this
11 * mistake, or contact the author.
12 */
13#ifndef PQXX_H_ROW
14#define PQXX_H_ROW
15
16#if !defined(PQXX_HEADER_PRE)
17# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
18#endif
19
20#include "pqxx/except.hxx"
21#include "pqxx/field.hxx"
22#include "pqxx/result.hxx"
23
24#include "pqxx/internal/concat.hxx"
25
26namespace pqxx::internal
27{
28template<typename... T> class result_iter;
29} // namespace pqxx::internal
30
31
32namespace pqxx
33{
35
46class PQXX_LIBEXPORT row
47{
48public:
57
58 row() noexcept = default;
59 row(row &&) noexcept = default;
60 row(row const &) noexcept = default;
61 row &operator=(row const &) noexcept = default;
62 row &operator=(row &&) noexcept = default;
63
68 [[nodiscard]] PQXX_PURE bool operator==(row const &) const noexcept;
69 [[nodiscard]] bool operator!=(row const &rhs) const noexcept
70 {
71 return not operator==(rhs);
72 }
74
75 [[nodiscard]] const_iterator begin() const noexcept;
76 [[nodiscard]] const_iterator cbegin() const noexcept;
77 [[nodiscard]] const_iterator end() const noexcept;
78 [[nodiscard]] const_iterator cend() const noexcept;
79
84 [[nodiscard]] reference front() const noexcept;
85 [[nodiscard]] reference back() const noexcept;
86
87 // TODO: noexcept. Breaks ABI.
88 [[nodiscard]] const_reverse_row_iterator rbegin() const;
89 // TODO: noexcept. Breaks ABI.
90 [[nodiscard]] const_reverse_row_iterator crbegin() const;
91 // TODO: noexcept. Breaks ABI.
92 [[nodiscard]] const_reverse_row_iterator rend() const;
93 // TODO: noexcept. Breaks ABI.
94 [[nodiscard]] const_reverse_row_iterator crend() const;
95
96 [[nodiscard]] reference operator[](size_type) const noexcept;
100 [[nodiscard]] reference operator[](zview col_name) const;
101
102 reference at(size_type) const;
106 reference at(zview col_name) const;
107
108 [[nodiscard]] constexpr size_type size() const noexcept
109 {
110 return m_end - m_begin;
111 }
112
113 [[deprecated("Swap iterators, not rows.")]] void swap(row &) noexcept;
114
116 [[nodiscard]] constexpr result::size_type rownumber() const noexcept
117 {
118 return m_index;
119 }
120
126 [[nodiscard]] size_type column_number(zview col_name) const;
127
129 [[nodiscard]] oid column_type(size_type) const;
130
132 [[nodiscard]] oid column_type(zview col_name) const
133 {
134 return column_type(column_number(col_name));
135 }
136
138 [[nodiscard]] oid column_table(size_type col_num) const;
139
141 [[nodiscard]] oid column_table(zview col_name) const
142 {
143 return column_table(column_number(col_name));
144 }
145
147
154 [[nodiscard]] size_type table_column(size_type) const;
155
157 [[nodiscard]] size_type table_column(zview col_name) const
158 {
159 return table_column(column_number(col_name));
160 }
162
163 [[nodiscard]] constexpr result::size_type num() const noexcept
164 {
165 return rownumber();
166 }
167
179 [[deprecated("Row slicing is going away. File a bug if you need it.")]] row
180 slice(size_type sbegin, size_type send) const;
181
183 [[nodiscard, deprecated("Row slicing is going away.")]] PQXX_PURE bool
184 empty() const noexcept;
185
187
192 template<typename Tuple> void to(Tuple &t) const
193 {
194 check_size(std::tuple_size_v<Tuple>);
195 convert(t);
196 }
197
199
204 template<typename... TYPE> std::tuple<TYPE...> as() const
205 {
206 check_size(sizeof...(TYPE));
207 using seq = std::make_index_sequence<sizeof...(TYPE)>;
208 return get_tuple<std::tuple<TYPE...>>(seq{});
209 }
210
211protected:
212 friend class const_row_iterator;
213 friend class result;
214 row(result const &r, result_size_type index, size_type cols) noexcept;
215
217 void check_size(size_type expected) const
218 {
219 if (size() != expected)
220 throw usage_error{internal::concat(
221 "Tried to extract ", expected, " field(s) from a row of ", size(),
222 ".")};
223 }
224
226
229 template<typename TUPLE> TUPLE as_tuple() const
230 {
231 using seq = std::make_index_sequence<std::tuple_size_v<TUPLE>>;
232 return get_tuple<TUPLE>(seq{});
233 }
234
235 template<typename... T> friend class pqxx::internal::result_iter;
237 template<typename Tuple> void convert(Tuple &t) const
238 {
239 extract_fields(t, std::make_index_sequence<std::tuple_size_v<Tuple>>{});
240 }
241
242 friend class field;
243
246
248
252 result::size_type m_index = 0;
253
254 // TODO: Remove m_begin and (if possible) m_end when we remove slice().
256 size_type m_begin = 0;
258 size_type m_end = 0;
259
260private:
261 template<typename Tuple, std::size_t... indexes>
262 void extract_fields(Tuple &t, std::index_sequence<indexes...>) const
263 {
264 (extract_value<Tuple, indexes>(t), ...);
265 }
266
267 template<typename Tuple, std::size_t index>
268 void extract_value(Tuple &t) const;
269
271 template<typename TUPLE, std::size_t... indexes>
272 auto get_tuple(std::index_sequence<indexes...>) const
273 {
274 return std::make_tuple(get_field<TUPLE, indexes>()...);
275 }
276
278 template<typename TUPLE, std::size_t index> auto get_field() const
279 {
280 return (*this)[index].as<std::tuple_element_t<index, TUPLE>>();
281 }
282};
283
284
286class PQXX_LIBEXPORT const_row_iterator : public field
287{
288public:
289 using iterator_category = std::random_access_iterator_tag;
290 using value_type = field const;
291 using pointer = field const *;
295
296#include "pqxx/internal/ignore-deprecated-pre.hxx"
298#include "pqxx/internal/ignore-deprecated-post.hxx"
299 const_row_iterator(row const &t, row_size_type c) noexcept :
300 field{t.m_result, t.m_index, c}
301 {}
302 const_row_iterator(field const &F) noexcept : field{F} {}
303 const_row_iterator(const_row_iterator const &) noexcept = default;
305
310 [[nodiscard]] constexpr pointer operator->() const noexcept
311 {
312 return this;
313 }
314 [[nodiscard]] reference operator*() const noexcept
315 {
316 return {*this};
317 }
319
324 const_row_iterator &operator=(const_row_iterator const &) noexcept = default;
326
327 // TODO: noexcept. Breaks ABI.
328 const_row_iterator operator++(int);
329 const_row_iterator &operator++() noexcept
330 {
331 ++m_col;
332 return *this;
333 }
334 // TODO: noexcept. Breaks ABI.
335 const_row_iterator operator--(int);
337 {
338 --m_col;
339 return *this;
340 }
341
343 {
344 m_col = size_type(difference_type(m_col) + i);
345 return *this;
346 }
348 {
349 m_col = size_type(difference_type(m_col) - i);
350 return *this;
351 }
353
358 [[nodiscard]] constexpr bool
359 operator==(const_row_iterator const &i) const noexcept
360 {
361 return col() == i.col();
362 }
363 [[nodiscard]] constexpr bool
364 operator!=(const_row_iterator const &i) const noexcept
365 {
366 return col() != i.col();
367 }
368 [[nodiscard]] constexpr bool
369 operator<(const_row_iterator const &i) const noexcept
370 {
371 return col() < i.col();
372 }
373 [[nodiscard]] constexpr bool
374 operator<=(const_row_iterator const &i) const noexcept
375 {
376 return col() <= i.col();
377 }
378 [[nodiscard]] constexpr bool
379 operator>(const_row_iterator const &i) const noexcept
380 {
381 return col() > i.col();
382 }
383 [[nodiscard]] constexpr bool
384 operator>=(const_row_iterator const &i) const noexcept
385 {
386 return col() >= i.col();
387 }
389
394 [[nodiscard]] inline const_row_iterator
395 operator+(difference_type) const noexcept;
396
397 friend const_row_iterator
398 operator+(difference_type, const_row_iterator const &) noexcept;
399
400 [[nodiscard]] inline const_row_iterator
401 operator-(difference_type) const noexcept;
402 [[nodiscard]] inline difference_type
403 operator-(const_row_iterator const &) const noexcept;
405};
406
407
409class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator
410{
411public:
419
420 const_reverse_row_iterator() noexcept = default;
422 default;
424
425 explicit const_reverse_row_iterator(super const &rhs) noexcept :
427 {
428 super::operator--();
429 }
430
431 [[nodiscard]] PQXX_PURE iterator_type base() const noexcept;
432
437 using iterator_type::operator->;
438 using iterator_type::operator*;
440
445 const_reverse_row_iterator &
446 operator=(const_reverse_row_iterator const &r) noexcept
447 {
448 iterator_type::operator=(r);
449 return *this;
450 }
452 {
453 iterator_type::operator--();
454 return *this;
455 }
456 // TODO: noexcept. Breaks ABI.
457 const_reverse_row_iterator operator++(int);
459 {
460 iterator_type::operator++();
461 return *this;
462 }
463 const_reverse_row_iterator operator--(int);
464 // TODO: noexcept. Breaks ABI.
466 {
467 iterator_type::operator-=(i);
468 return *this;
469 }
471 {
472 iterator_type::operator+=(i);
473 return *this;
474 }
476
481 [[nodiscard]] const_reverse_row_iterator
482 operator+(difference_type i) const noexcept
483 {
484 return const_reverse_row_iterator{base() - i};
485 }
486 [[nodiscard]] const_reverse_row_iterator
488 {
489 return const_reverse_row_iterator{base() + i};
490 }
491 [[nodiscard]] difference_type
492 operator-(const_reverse_row_iterator const &rhs) const noexcept
493 {
494 return rhs.const_row_iterator::operator-(*this);
495 }
497
502 [[nodiscard]] bool
503 operator==(const_reverse_row_iterator const &rhs) const noexcept
504 {
505 return iterator_type::operator==(rhs);
506 }
507 [[nodiscard]] bool
508 operator!=(const_reverse_row_iterator const &rhs) const noexcept
509 {
510 return !operator==(rhs);
511 }
512
513 [[nodiscard]] constexpr bool
514 operator<(const_reverse_row_iterator const &rhs) const noexcept
515 {
516 return iterator_type::operator>(rhs);
517 }
518 [[nodiscard]] constexpr bool
519 operator<=(const_reverse_row_iterator const &rhs) const noexcept
520 {
521 return iterator_type::operator>=(rhs);
522 }
523 [[nodiscard]] constexpr bool
524 operator>(const_reverse_row_iterator const &rhs) const noexcept
525 {
526 return iterator_type::operator<(rhs);
527 }
528 [[nodiscard]] constexpr bool
529 operator>=(const_reverse_row_iterator const &rhs) const noexcept
530 {
531 return iterator_type::operator<=(rhs);
532 }
534};
535
536
537const_row_iterator
539{
540 // TODO:: More direct route to home().columns()?
541 return {
542 row{home(), idx(), home().columns()},
543 size_type(difference_type(col()) + o)};
544}
545
548{
549 return i + o;
550}
551
554{
555 // TODO:: More direct route to home().columns()?
556 return {
557 row{home(), idx(), home().columns()},
558 size_type(difference_type(col()) - o)};
559}
560
563{
564 return difference_type(num() - i.num());
565}
566
567
568template<typename Tuple, std::size_t index>
569inline void row::extract_value(Tuple &t) const
570{
571 using field_type = strip_t<decltype(std::get<index>(t))>;
572 field const f{m_result, m_index, index};
573 std::get<index>(t) = from_string<field_type>(f);
574}
575} // namespace pqxx
576#endif
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:27
int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:34
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition: types.hxx:91
int row_difference_type
Difference between row sizes.
Definition: types.hxx:37
const_row_iterator operator+(const_row_iterator::difference_type o, const_row_iterator const &i) noexcept
Definition: row.hxx:546
int result_size_type
Number of rows in a result set.
Definition: types.hxx:28
Internal items for libpqxx' own use. Do not use these yourself.
Definition: composite.hxx:83
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:174
Reference to a field in a result set.
Definition: field.hxx:35
Result set containing data returned by a query or command.
Definition: result.hxx:74
result_size_type size_type
Definition: result.hxx:76
Definition: row.hxx:28
Reference to one row in a result.
Definition: row.hxx:47
std::tuple< TYPE... > as() const
Extract entire row's values into a tuple.
Definition: row.hxx:204
row_size_type size_type
Definition: row.hxx:49
oid column_type(zview col_name) const
Return a column's type.
Definition: row.hxx:132
row_difference_type difference_type
Definition: row.hxx:50
result m_result
Result set of which this is one row.
Definition: row.hxx:245
result::size_type m_index
Row number.
Definition: row.hxx:252
constexpr result::size_type num() const noexcept
Definition: row.hxx:163
row() noexcept=default
constexpr result::size_type rownumber() const noexcept
Row number, assuming this is a real row and not end()/rend().
Definition: row.hxx:116
TUPLE as_tuple() const
Convert to a given tuple of values, don't check sizes.
Definition: row.hxx:229
void check_size(size_type expected) const
Throw usage_error if row size is not expected.
Definition: row.hxx:217
size_type table_column(zview col_name) const
What column number in its table did this result column come from?
Definition: row.hxx:157
void convert(Tuple &t) const
Convert entire row to tuple fields, without checking row size.
Definition: row.hxx:237
oid column_table(zview col_name) const
What table did this column come from?
Definition: row.hxx:141
Iterator for fields in a row. Use as row::const_iterator.
Definition: row.hxx:287
const_row_iterator operator-(difference_type) const noexcept
Definition: row.hxx:553
const_row_iterator & operator=(const_row_iterator &&) noexcept=default
reference operator*() const noexcept
Definition: row.hxx:314
const_row_iterator(field const &F) noexcept
Definition: row.hxx:302
friend const_row_iterator operator+(difference_type, const_row_iterator const &) noexcept
Definition: row.hxx:546
constexpr bool operator>=(const_row_iterator const &i) const noexcept
Definition: row.hxx:384
const_row_iterator(const_row_iterator const &) noexcept=default
const_row_iterator & operator=(const_row_iterator const &) noexcept=default
std::random_access_iterator_tag iterator_category
Definition: row.hxx:289
constexpr bool operator==(const_row_iterator const &i) const noexcept
Definition: row.hxx:359
field const * pointer
Definition: row.hxx:291
field const value_type
Definition: row.hxx:290
constexpr bool operator!=(const_row_iterator const &i) const noexcept
Definition: row.hxx:364
const_row_iterator(const_row_iterator &&) noexcept=default
row_size_type size_type
Definition: row.hxx:292
const_row_iterator & operator--() noexcept
Definition: row.hxx:336
row_difference_type difference_type
Definition: row.hxx:293
const_row_iterator & operator-=(difference_type i) noexcept
Definition: row.hxx:347
const_row_iterator & operator+=(difference_type i) noexcept
Definition: row.hxx:342
const_row_iterator(row const &t, row_size_type c) noexcept
Definition: row.hxx:299
constexpr bool operator>(const_row_iterator const &i) const noexcept
Definition: row.hxx:379
Reverse iterator for a row. Use as row::const_reverse_iterator.
Definition: row.hxx:410
const_reverse_row_iterator operator++() noexcept
Definition: row.hxx:451
bool operator!=(const_reverse_row_iterator const &rhs) const noexcept
Definition: row.hxx:508
constexpr bool operator>=(const_reverse_row_iterator const &rhs) const noexcept
Definition: row.hxx:529
constexpr bool operator>(const_reverse_row_iterator const &rhs) const noexcept
Definition: row.hxx:524
difference_type operator-(const_reverse_row_iterator const &rhs) const noexcept
Definition: row.hxx:492
const_reverse_row_iterator & operator+=(difference_type i) noexcept
Definition: row.hxx:465
const_reverse_row_iterator operator+(difference_type i) const noexcept
Definition: row.hxx:482
const_reverse_row_iterator & operator-=(difference_type i) noexcept
Definition: row.hxx:470
const_reverse_row_iterator & operator--() noexcept
Definition: row.hxx:458
row_difference_type difference_type
Definition: row.hxx:293
bool operator==(const_reverse_row_iterator const &rhs) const noexcept
Definition: row.hxx:503
const_reverse_row_iterator() noexcept=default
const_reverse_row_iterator operator-(difference_type i) noexcept
Definition: row.hxx:487
iterator_type::value_type value_type
Definition: row.hxx:417
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:38