libpqxx  7.1.0
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-2020, 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 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/internal/compiler-internal-pre.hxx"
18 
19 #include "pqxx/except.hxx"
20 #include "pqxx/field.hxx"
21 #include "pqxx/result.hxx"
22 
23 namespace pqxx::internal
24 {
25 template<typename... T> class result_iter;
26 } // namespace pqxx::internal
27 
28 
29 namespace pqxx
30 {
32 
43 class PQXX_LIBEXPORT row
44 {
45 public:
50  using reference = field;
54 
55  row() = default;
56  row(row &&) = default;
57  row(row const &) = default;
58  row &operator=(row const &) = default;
59  row &operator=(row &&) = default;
60 
65  [[nodiscard]] PQXX_PURE bool operator==(row const &) const noexcept;
66  [[nodiscard]] bool operator!=(row const &rhs) const noexcept
67  {
68  return not operator==(rhs);
69  }
71 
72  [[nodiscard]] const_iterator begin() const noexcept;
73  [[nodiscard]] const_iterator cbegin() const noexcept;
74  [[nodiscard]] const_iterator end() const noexcept;
75  [[nodiscard]] const_iterator cend() const noexcept;
76 
81  [[nodiscard]] reference front() const noexcept;
82  [[nodiscard]] reference back() const noexcept;
83 
84  [[nodiscard]] const_reverse_row_iterator rbegin() const;
85  [[nodiscard]] const_reverse_row_iterator crbegin() const;
86  [[nodiscard]] const_reverse_row_iterator rend() const;
87  [[nodiscard]] const_reverse_row_iterator crend() const;
88 
89  [[nodiscard]] reference operator[](size_type) const noexcept;
93  [[nodiscard]] reference operator[](char const[]) const;
97  [[nodiscard]] reference operator[](std::string const &s) const
98  {
99  return (*this)[s.c_str()];
100  }
101 
102  reference at(size_type) const;
106  reference at(char const[]) const;
110  reference at(std::string const &s) const { return at(s.c_str()); }
112 
113  [[nodiscard]] size_type size() const noexcept { return m_end - m_begin; }
114 
116  void swap(row &) noexcept;
117 
119  [[nodiscard]] result::size_type rownumber() const noexcept
120  {
121  return m_index;
122  }
123 
128  [[nodiscard]] size_type column_number(std::string const &col_name) const
130  {
131  return column_number(col_name.c_str());
132  }
133 
135  size_type column_number(char const[]) const;
136 
138  [[nodiscard]] oid column_type(size_type) const;
139 
141  template<typename STRING> oid column_type(STRING col_name) const
142  {
143  return column_type(column_number(col_name));
144  }
145 
147  [[nodiscard]] oid column_table(size_type col_num) const;
148 
150  template<typename STRING> oid column_table(STRING col_name) const
151  {
152  return column_table(column_number(col_name));
153  }
154 
156 
163  [[nodiscard]] size_type table_column(size_type) const;
164 
166  template<typename STRING> size_type table_column(STRING col_name) const
167  {
168  return table_column(column_number(col_name));
169  }
171 
172  [[nodiscard]] result::size_type num() const { return rownumber(); }
173 
186  [[nodiscard]] row slice(size_type sbegin, size_type send) const;
187 
188  // Is this an empty slice?
189  [[nodiscard]] PQXX_PURE bool empty() const noexcept;
190 
192 
194  template<typename Tuple> void to(Tuple &t) const
195  {
196  check_size(std::tuple_size_v<Tuple>);
197  convert(t);
198  }
199 
200 protected:
201  friend class const_row_iterator;
202  friend class result;
203  row(result const &r, result_size_type i) noexcept;
204 
206  void check_size(size_type expected) const
207  {
208  if (size() != expected)
209  throw usage_error{"Tried to extract " + to_string(expected) +
210  " field(s) from a row of " + to_string(size()) + "."};
211  }
212 
213  template<typename... T> friend class pqxx::internal::result_iter;
215  template<typename Tuple> void convert(Tuple &t) const
216  {
217  constexpr auto tup_size{std::tuple_size_v<Tuple>};
218  extract_fields(t, std::make_index_sequence<tup_size>{});
219  }
220 
221  friend class field;
225 
229  result::size_type m_index = 0;
231  size_type m_begin = 0;
233  size_type m_end = 0;
234 
235 private:
236  template<typename Tuple, std::size_t... indexes>
237  void extract_fields(Tuple &t, std::index_sequence<indexes...>) const
238  {
239  (extract_value<Tuple, indexes>(t), ...);
240  }
241 
242  template<typename Tuple, std::size_t index>
243  void extract_value(Tuple &t) const;
244 };
245 
246 
248 class PQXX_LIBEXPORT const_row_iterator : public field
249 {
250 public:
251  using iterator_category = std::random_access_iterator_tag;
252  using value_type = field const;
253  using pointer = field const *;
256  using reference = field;
257 
258  const_row_iterator() = default;
259  const_row_iterator(row const &T, row_size_type C) noexcept : field{T, C} {}
260  const_row_iterator(field const &F) noexcept : field{F} {}
261  const_row_iterator(const_row_iterator const &) = default;
263 
268  [[nodiscard]] pointer operator->() const { return this; }
269  [[nodiscard]] reference operator*() const { return field{*this}; }
271 
276  const_row_iterator &operator=(const_row_iterator const &) = default;
277  const_row_iterator &operator=(const_row_iterator &&) = default;
278 
279  const_row_iterator operator++(int);
281  {
282  ++m_col;
283  return *this;
284  }
285  const_row_iterator operator--(int);
287  {
288  --m_col;
289  return *this;
290  }
291 
293  {
294  m_col = size_type(difference_type(m_col) + i);
295  return *this;
296  }
298  {
299  m_col = size_type(difference_type(m_col) - i);
300  return *this;
301  }
303 
308  [[nodiscard]] bool operator==(const_row_iterator const &i) const
309  {
310  return col() == i.col();
311  }
312  [[nodiscard]] bool operator!=(const_row_iterator const &i) const
313  {
314  return col() != i.col();
315  }
316  [[nodiscard]] bool operator<(const_row_iterator const &i) const
317  {
318  return col() < i.col();
319  }
320  [[nodiscard]] bool operator<=(const_row_iterator const &i) const
321  {
322  return col() <= i.col();
323  }
324  [[nodiscard]] bool operator>(const_row_iterator const &i) const
325  {
326  return col() > i.col();
327  }
328  [[nodiscard]] bool operator>=(const_row_iterator const &i) const
329  {
330  return col() >= i.col();
331  }
333 
338  [[nodiscard]] inline const_row_iterator operator+(difference_type) const;
339 
340  friend const_row_iterator
342 
343  [[nodiscard]] inline const_row_iterator operator-(difference_type) const;
344  [[nodiscard]] inline difference_type
345  operator-(const_row_iterator const &) const;
347 };
348 
349 
351 class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator
352 {
353 public:
361 
362  const_reverse_row_iterator() = default;
365 
366  explicit const_reverse_row_iterator(super const &rhs) noexcept :
367  const_row_iterator{rhs}
368  {
369  super::operator--();
370  }
371 
372  [[nodiscard]] PQXX_PURE iterator_type base() const noexcept;
373 
378  using iterator_type::operator->;
379  using iterator_type::operator*;
381 
387  {
388  iterator_type::operator=(r);
389  return *this;
390  }
392  {
393  iterator_type::operator--();
394  return *this;
395  }
396  const_reverse_row_iterator operator++(int);
398  {
399  iterator_type::operator++();
400  return *this;
401  }
402  const_reverse_row_iterator operator--(int);
404  {
405  iterator_type::operator-=(i);
406  return *this;
407  }
409  {
410  iterator_type::operator+=(i);
411  return *this;
412  }
414 
420  {
421  return const_reverse_row_iterator{base() - i};
422  }
424  {
425  return const_reverse_row_iterator{base() + i};
426  }
427  [[nodiscard]] difference_type
429  {
430  return rhs.const_row_iterator::operator-(*this);
431  }
433 
438  [[nodiscard]] bool operator==(const_reverse_row_iterator const &rhs) const
439  noexcept
440  {
441  return iterator_type::operator==(rhs);
442  }
443  [[nodiscard]] bool operator!=(const_reverse_row_iterator const &rhs) const
444  noexcept
445  {
446  return !operator==(rhs);
447  }
448 
449  [[nodiscard]] bool operator<(const_reverse_row_iterator const &rhs) const
450  {
451  return iterator_type::operator>(rhs);
452  }
453  [[nodiscard]] bool operator<=(const_reverse_row_iterator const &rhs) const
454  {
455  return iterator_type::operator>=(rhs);
456  }
457  [[nodiscard]] bool operator>(const_reverse_row_iterator const &rhs) const
458  {
459  return iterator_type::operator<(rhs);
460  }
461  [[nodiscard]] bool operator>=(const_reverse_row_iterator const &rhs) const
462  {
463  return iterator_type::operator<=(rhs);
464  }
466 };
467 
468 
470 {
471  return const_row_iterator{row(home(), idx()),
472  size_type(difference_type(col()) + o)};
473 }
474 
475 inline const_row_iterator
477 {
478  return i + o;
479 }
480 
483 {
484  return const_row_iterator{row(home(), idx()),
485  size_type(difference_type(col()) - o)};
486 }
487 
490 {
491  return difference_type(num() - i.num());
492 }
493 
494 
495 template<typename Tuple, std::size_t index>
496 inline void row::extract_value(Tuple &t) const
497 {
498  using field_type = strip_t<decltype(std::get<index>(t))>;
499  field const f{*this, index};
500  std::get<index>(t) = from_string<field_type>(f);
501 }
502 } // namespace pqxx
503 
504 #include "pqxx/internal/compiler-internal-post.hxx"
505 #endif
result::size_type rownumber() const noexcept
Row number, assuming this is a real row and not end()/rend().
Definition: row.hxx:119
const_row_iterator(row const &T, row_size_type C) noexcept
Definition: row.hxx:259
const_row_iterator & operator-=(difference_type i)
Definition: row.hxx:297
bool operator<(const_row_iterator const &i) const
Definition: row.hxx:316
row_size_type col() const noexcept
Definition: field.hxx:215
oid column_table(STRING col_name) const
What table did this column come from?
Definition: row.hxx:150
Private namespace for libpqxx&#39;s internal use; do not access.
Definition: connection.hxx:60
const_reverse_row_iterator & operator-=(difference_type i)
Definition: row.hxx:408
Reference to one row in a result.
Definition: row.hxx:43
field const * pointer
Definition: row.hxx:253
const_reverse_row_iterator & operator+=(difference_type i)
Definition: row.hxx:403
bool operator>=(const_reverse_row_iterator const &rhs) const
Definition: row.hxx:461
difference_type operator-(const_reverse_row_iterator const &rhs) const
Definition: row.hxx:428
result::size_type num() const
Definition: row.hxx:172
reference operator[](std::string const &s) const
Definition: row.hxx:97
std::random_access_iterator_tag iterator_category
Definition: row.hxx:251
int row_difference_type
Difference between row sizes.
Definition: types.hxx:27
const_row_iterator & operator+=(difference_type i)
Definition: row.hxx:292
field const value_type
Definition: row.hxx:252
oid column_type(STRING col_name) const
Return a column&#39;s type.
Definition: row.hxx:141
bool operator==(const_reverse_row_iterator const &rhs) const noexcept
Definition: row.hxx:438
void check_size(size_type expected) const
Throw usage_error if row size is not expected.
Definition: row.hxx:206
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:477
void convert(Tuple &t) const
Convert entire row to tuple fields, without checking row size.
Definition: row.hxx:215
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition: util.hxx:117
const_row_iterator & operator--()
Definition: row.hxx:286
const_reverse_row_iterator(super const &rhs) noexcept
Definition: row.hxx:366
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
const_result_iterator operator+(result::difference_type o, const_result_iterator const &i)
Definition: result_iterator.hxx:329
bool operator<=(const_row_iterator const &i) const
Definition: row.hxx:320
const_row_iterator operator+(difference_type) const
Definition: row.hxx:469
bool operator!=(const_reverse_row_iterator const &rhs) const noexcept
Definition: row.hxx:443
bool operator==(const_row_iterator const &i) const
Definition: row.hxx:308
reference at(std::string const &s) const
Definition: row.hxx:110
void to(Tuple &t) const
Extract entire row&#39;s values into a tuple.
Definition: row.hxx:194
const_row_iterator & operator++()
Definition: row.hxx:280
size_type size() const noexcept
Definition: row.hxx:113
int row_size_type
Number of fields in a row of database data.
Definition: types.hxx:24
const_reverse_row_iterator & operator=(const_reverse_row_iterator const &r)
Definition: row.hxx:386
const_row_iterator(field const &F) noexcept
Definition: row.hxx:260
pointer operator->() const
Definition: row.hxx:268
reference operator*() const
Definition: row.hxx:269
size_type table_column(STRING col_name) const
What column number in its table did this result column come from?
Definition: row.hxx:166
bool operator!=(const_row_iterator const &i) const
Definition: row.hxx:312
Reverse iterator for a row. Use as row::const_reverse_iterator.
Definition: row.hxx:351
const_reverse_row_iterator & operator--()
Definition: row.hxx:397
bool operator<=(const_reverse_row_iterator const &rhs) const
Definition: row.hxx:453
Result set containing data returned by a query or command.
Definition: result.hxx:70
row_size_type num() const
Definition: field.hxx:91
row_difference_type difference_type
Definition: row.hxx:47
result_size_type size_type
Definition: result.hxx:73
row_size_type size_type
Definition: row.hxx:46
field_size_type size_type
Definition: field.hxx:35
row_difference_type difference_type
Definition: row.hxx:255
Definition: row.hxx:25
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:164
bool operator!=(row const &rhs) const noexcept
Definition: row.hxx:66
result m_result
Result set of which this is one row.
Definition: row.hxx:223
int result_size_type
Number of rows in a result set.
Definition: types.hxx:18
bool operator>(const_reverse_row_iterator const &rhs) const
Definition: row.hxx:457
const_row_iterator operator-(difference_type) const
Definition: row.hxx:482
bool operator<(const_reverse_row_iterator const &rhs) const
Definition: row.hxx:449
const_reverse_row_iterator operator+(difference_type i) const
Definition: row.hxx:419
Reference to a field in a result set.
Definition: field.hxx:32
bool operator>(const_row_iterator const &i) const
Definition: row.hxx:324
Iterator for fields in a row. Use as row::const_iterator.
Definition: row.hxx:248
const_reverse_row_iterator operator-(difference_type i)
Definition: row.hxx:423
const_reverse_row_iterator operator++()
Definition: row.hxx:391
bool operator>=(const_row_iterator const &i) const
Definition: row.hxx:328