libpqxx  7.9.0
cursor.hxx
1 /* Definition of the iterator/container-style cursor classes.
2  *
3  * C++-style wrappers for SQL cursors.
4  *
5  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead.
6  *
7  * Copyright (c) 2000-2024, 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_CURSOR
14 #define PQXX_H_CURSOR
15 
16 #if !defined(PQXX_HEADER_PRE)
17 # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
18 #endif
19 
20 #include <limits>
21 #include <stdexcept>
22 
23 #include "pqxx/result.hxx"
24 #include "pqxx/transaction_base.hxx"
25 
26 
27 namespace pqxx
28 {
30 
41 class PQXX_LIBEXPORT cursor_base
42 {
43 public:
46 
48 
52  {
56  random_access
57  };
58 
60 
64  {
68  update
69  };
70 
72 
88  {
92  loose
93  };
94 
95  cursor_base() = delete;
96  cursor_base(cursor_base const &) = delete;
97  cursor_base &operator=(cursor_base const &) = delete;
98 
103 
105 
108  [[nodiscard]] static constexpr difference_type all() noexcept
109  {
110  return (std::numeric_limits<int>::max)() - 1;
111  }
112 
114 
116  [[nodiscard]] static constexpr difference_type next() noexcept { return 1; }
117 
119 
121  [[nodiscard]] static constexpr difference_type prior() noexcept
122  {
123  return -1;
124  }
125 
127 
129  [[nodiscard]] static constexpr difference_type backward_all() noexcept
130  {
131  return (std::numeric_limits<int>::min)() + 1;
132  }
133 
135 
137 
142  [[nodiscard]] constexpr std::string const &name() const noexcept
143  {
144  return m_name;
145  }
146 
147 protected:
148  cursor_base(connection &, std::string_view Name, bool embellish_name = true);
149 
150  std::string const m_name;
151 };
152 } // namespace pqxx
153 
154 
155 #include <pqxx/internal/sql_cursor.hxx>
156 
157 
158 namespace pqxx
159 {
161 
167 template<cursor_base::update_policy up, cursor_base::ownership_policy op>
169 {
170 public:
173 
175 
184  transaction_base &tx, std::string_view query, std::string_view cname,
185  bool hold) :
186  m_cur{tx, query, cname, cursor_base::random_access, up, op, hold}
187  {}
188 
190 
196  stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) :
197  m_cur{tx, adopted_cursor, op}
198  {
199  // Put cursor in known position
200  m_cur.move(cursor_base::backward_all());
201  }
202 
204 
209  void close() noexcept { m_cur.close(); }
210 
212 
215  [[nodiscard]] size_type size()
216  {
217  return internal::obtain_stateless_cursor_size(m_cur);
218  }
219 
221 
233  {
234  return internal::stateless_cursor_retrieve(
235  m_cur, result::difference_type(size()), begin_pos, end_pos);
236  }
237 
239  [[nodiscard]] constexpr std::string const &name() const noexcept
240  {
241  return m_cur.name();
242  }
243 
244 private:
245  internal::sql_cursor m_cur;
246 };
247 
248 
249 class icursor_iterator;
250 } // namespace pqxx
251 
252 
253 namespace pqxx::internal::gate
254 {
255 class icursor_iterator_icursorstream;
256 class icursorstream_icursor_iterator;
257 } // namespace pqxx::internal::gate
258 
259 
260 namespace pqxx
261 {
263 
278 class PQXX_LIBEXPORT icursorstream
279 {
280 public:
283 
285 
297  transaction_base &context, std::string_view query,
298  std::string_view basename, difference_type sstride = 1);
299 
301 
326  transaction_base &context, field const &cname, difference_type sstride = 1,
328 
330  constexpr operator bool() const & noexcept { return not m_done; }
331 
333 
342  {
343  res = fetchblock();
344  return *this;
345  }
347 
355  icursorstream &operator>>(result &res) { return get(res); }
356 
358 
364  icursorstream &ignore(std::streamsize n = 1) &;
365 
367 
370  void set_stride(difference_type stride) &;
371  [[nodiscard]] constexpr difference_type stride() const noexcept
372  {
373  return m_stride;
374  }
375 
376 private:
377  result fetchblock();
378 
379  friend class internal::gate::icursorstream_icursor_iterator;
380  size_type forward(size_type n = 1);
381  void insert_iterator(icursor_iterator *) noexcept;
382  void remove_iterator(icursor_iterator *) const noexcept;
383 
384  void service_iterators(difference_type);
385 
386  internal::sql_cursor m_cur;
387 
388  difference_type m_stride;
389  difference_type m_realpos, m_reqpos;
390 
391  mutable icursor_iterator *m_iterators;
392 
393  bool m_done;
394 };
395 
396 
398 
424 class PQXX_LIBEXPORT icursor_iterator
425 {
426 public:
427  using iterator_category = std::input_iterator_tag;
429  using pointer = result const *;
430  using reference = result const &;
434 
435  icursor_iterator() noexcept;
436  explicit icursor_iterator(istream_type &) noexcept;
437  icursor_iterator(icursor_iterator const &) noexcept;
438  ~icursor_iterator() noexcept;
439 
440  result const &operator*() const
441  {
442  refresh();
443  return m_here;
444  }
445  result const *operator->() const
446  {
447  refresh();
448  return &m_here;
449  }
450  icursor_iterator &operator++();
451  icursor_iterator operator++(int) &;
452  icursor_iterator &operator+=(difference_type);
453  icursor_iterator &operator=(icursor_iterator const &) noexcept;
454 
455  [[nodiscard]] bool operator==(icursor_iterator const &rhs) const;
456  [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept
457  {
458  return not operator==(rhs);
459  }
460  [[nodiscard]] bool operator<(icursor_iterator const &rhs) const;
461  [[nodiscard]] bool operator>(icursor_iterator const &rhs) const
462  {
463  return rhs < *this;
464  }
465  [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const
466  {
467  return not(*this > rhs);
468  }
469  [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const
470  {
471  return not(*this < rhs);
472  }
473 
474 private:
475  void refresh() const;
476 
477  friend class internal::gate::icursor_iterator_icursorstream;
478  difference_type pos() const noexcept { return m_pos; }
479  void fill(result const &);
480 
481  icursorstream *m_stream{nullptr};
482  result m_here;
483  difference_type m_pos;
484  icursor_iterator *m_prev{nullptr}, *m_next{nullptr};
485 };
486 } // namespace pqxx
487 #endif
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:33
int result_difference_type
Difference between result sizes.
Definition: types.hxx:31
int result_size_type
Number of rows in a result set.
Definition: types.hxx:28
Definition: connection.hxx:109
Connection to a database.
Definition: connection.hxx:233
Common definitions for cursor types.
Definition: cursor.hxx:42
cursor_base & operator=(cursor_base const &)=delete
result_size_type size_type
Definition: cursor.hxx:44
constexpr std::string const & name() const noexcept
Name of underlying SQL cursor.
Definition: cursor.hxx:142
static constexpr difference_type next() noexcept
Special value: read one row only.
Definition: cursor.hxx:116
cursor_base(cursor_base const &)=delete
static constexpr difference_type all() noexcept
Special value: read until end.
Definition: cursor.hxx:108
static constexpr difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:121
cursor_base()=delete
access_policy
Cursor access-pattern policy.
Definition: cursor.hxx:52
@ forward_only
Cursor can move forward only.
Definition: cursor.hxx:54
ownership_policy
Cursor destruction policy.
Definition: cursor.hxx:88
@ owned
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:90
update_policy
Cursor update policy.
Definition: cursor.hxx:64
@ read_only
Cursor can be used to read data but not to write.
Definition: cursor.hxx:66
result_difference_type difference_type
Definition: cursor.hxx:45
std::string const m_name
Definition: cursor.hxx:150
static constexpr difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.hxx:129
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:169
void close() noexcept
Close this cursor.
Definition: cursor.hxx:209
result_size_type size_type
Definition: cursor.hxx:171
result_difference_type difference_type
Definition: cursor.hxx:172
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:232
constexpr std::string const & name() const noexcept
Return this cursor's name.
Definition: cursor.hxx:239
stateless_cursor(transaction_base &tx, std::string_view query, std::string_view cname, bool hold)
Create cursor.
Definition: cursor.hxx:183
size_type size()
Number of rows in cursor's result set.
Definition: cursor.hxx:215
stateless_cursor(transaction_base &tx, std::string_view adopted_cursor)
Adopt an existing scrolling SQL cursor.
Definition: cursor.hxx:196
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:279
icursorstream & get(result &res)
Read new value into given result object; same as operator >>.
Definition: cursor.hxx:341
cursor_base::size_type size_type
Definition: cursor.hxx:281
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result&).
Definition: cursor.hxx:355
cursor_base::difference_type difference_type
Definition: cursor.hxx:282
constexpr difference_type stride() const noexcept
Definition: cursor.hxx:371
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:425
result const * operator->() const
Definition: cursor.hxx:445
bool operator!=(icursor_iterator const &rhs) const noexcept
Definition: cursor.hxx:456
result const * pointer
Definition: cursor.hxx:429
bool operator>=(icursor_iterator const &rhs) const
Definition: cursor.hxx:469
bool operator>(icursor_iterator const &rhs) const
Definition: cursor.hxx:461
result const & reference
Definition: cursor.hxx:430
istream_type::difference_type difference_type
Definition: cursor.hxx:433
std::input_iterator_tag iterator_category
Definition: cursor.hxx:427
bool operator<=(icursor_iterator const &rhs) const
Definition: cursor.hxx:465
istream_type::size_type size_type
Definition: cursor.hxx:432
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:73
result_difference_type difference_type
Definition: result.hxx:76
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:88