libpqxx  7.7.1
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-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_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 
104  // TODO: Make constexpr inline (but breaks ABI).
106 
109  [[nodiscard]] static difference_type all() noexcept;
110 
112 
114  [[nodiscard]] static constexpr difference_type next() noexcept { return 1; }
115 
117 
119  [[nodiscard]] static constexpr difference_type prior() noexcept
120  {
121  return -1;
122  }
123 
124  // TODO: Make constexpr inline (but breaks ABI).
126 
128  [[nodiscard]] static difference_type backward_all() noexcept;
129 
131 
133 
138  [[nodiscard]] constexpr std::string const &name() const noexcept
139  {
140  return m_name;
141  }
142 
143 protected:
144  cursor_base(connection &, std::string_view Name, bool embellish_name = true);
145 
146  std::string const m_name;
147 };
148 } // namespace pqxx
149 
150 
151 #include <pqxx/internal/sql_cursor.hxx>
152 
153 
154 namespace pqxx
155 {
157 
163 template<cursor_base::update_policy up, cursor_base::ownership_policy op>
165 {
166 public:
169 
171 
180  transaction_base &tx, std::string_view query, std::string_view cname,
181  bool hold) :
182  m_cur{tx, query, cname, cursor_base::random_access, up, op, hold}
183  {}
184 
186 
192  stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) :
193  m_cur{tx, adopted_cursor, op}
194  {
195  // Put cursor in known position
196  m_cur.move(cursor_base::backward_all());
197  }
198 
200 
205  void close() noexcept { m_cur.close(); }
206 
208 
211  [[nodiscard]] size_type size()
212  {
213  return internal::obtain_stateless_cursor_size(m_cur);
214  }
215 
217 
229  {
230  return internal::stateless_cursor_retrieve(
231  m_cur, result::difference_type(size()), begin_pos, end_pos);
232  }
233 
235  [[nodiscard]] constexpr std::string const &name() const noexcept
236  {
237  return m_cur.name();
238  }
239 
240 private:
241  internal::sql_cursor m_cur;
242 };
243 
244 
245 class icursor_iterator;
246 } // namespace pqxx
247 
248 
249 namespace pqxx::internal::gate
250 {
251 class icursor_iterator_icursorstream;
252 class icursorstream_icursor_iterator;
253 } // namespace pqxx::internal::gate
254 
255 
256 namespace pqxx
257 {
259 
274 class PQXX_LIBEXPORT icursorstream
275 {
276 public:
279 
281 
293  transaction_base &context, std::string_view query,
294  std::string_view basename, difference_type sstride = 1);
295 
297 
322  transaction_base &context, field const &cname, difference_type sstride = 1,
324 
326  constexpr operator bool() const &noexcept { return not m_done; }
327 
329 
338  {
339  res = fetchblock();
340  return *this;
341  }
343 
351  icursorstream &operator>>(result &res) { return get(res); }
352 
354 
360  icursorstream &ignore(std::streamsize n = 1) &;
361 
363 
366  void set_stride(difference_type stride) &;
367  [[nodiscard]] constexpr difference_type stride() const noexcept
368  {
369  return m_stride;
370  }
371 
372 private:
373  result fetchblock();
374 
375  friend class internal::gate::icursorstream_icursor_iterator;
376  size_type forward(size_type n = 1);
377  void insert_iterator(icursor_iterator *) noexcept;
378  void remove_iterator(icursor_iterator *) const noexcept;
379 
380  void service_iterators(difference_type);
381 
382  internal::sql_cursor m_cur;
383 
384  difference_type m_stride;
385  difference_type m_realpos, m_reqpos;
386 
387  mutable icursor_iterator *m_iterators;
388 
389  bool m_done;
390 };
391 
392 
394 
420 class PQXX_LIBEXPORT icursor_iterator
421 {
422 public:
423  using iterator_category = std::input_iterator_tag;
425  using pointer = result const *;
426  using reference = result const &;
430 
431  icursor_iterator() noexcept;
432  explicit icursor_iterator(istream_type &) noexcept;
433  icursor_iterator(icursor_iterator const &) noexcept;
434  ~icursor_iterator() noexcept;
435 
436  result const &operator*() const
437  {
438  refresh();
439  return m_here;
440  }
441  result const *operator->() const
442  {
443  refresh();
444  return &m_here;
445  }
446  icursor_iterator &operator++();
447  icursor_iterator operator++(int);
448  icursor_iterator &operator+=(difference_type);
449  icursor_iterator &operator=(icursor_iterator const &) noexcept;
450 
451  [[nodiscard]] bool operator==(icursor_iterator const &rhs) const;
452  [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept
453  {
454  return not operator==(rhs);
455  }
456  [[nodiscard]] bool operator<(icursor_iterator const &rhs) const;
457  [[nodiscard]] bool operator>(icursor_iterator const &rhs) const
458  {
459  return rhs < *this;
460  }
461  [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const
462  {
463  return not(*this > rhs);
464  }
465  [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const
466  {
467  return not(*this < rhs);
468  }
469 
470 private:
471  void refresh() const;
472 
473  friend class internal::gate::icursor_iterator_icursorstream;
474  difference_type pos() const noexcept { return m_pos; }
475  void fill(result const &);
476 
477  icursorstream *m_stream{nullptr};
478  result m_here;
479  difference_type m_pos;
480  icursor_iterator *m_prev{nullptr}, *m_next{nullptr};
481 };
482 } // namespace pqxx
483 #endif
std::string const m_name
Definition: cursor.hxx:146
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:35
size_type size()
Number of rows in cursor&#39;s result set.
Definition: cursor.hxx:211
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:164
Connection to a database.
Definition: connection.hxx:185
access_policy
Cursor access-pattern policy.
Definition: cursor.hxx:51
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:420
result_size_type size_type
Definition: cursor.hxx:44
void close() noexcept
Close this cursor.
Definition: cursor.hxx:205
Reference to a field in a result set.
Definition: field.hxx:34
result const * operator->() const
Definition: cursor.hxx:441
stateless_cursor(transaction_base &tx, std::string_view adopted_cursor)
Adopt an existing scrolling SQL cursor.
Definition: cursor.hxx:192
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:228
Cursor can move back and forth.
Definition: cursor.hxx:56
bool operator<=(icursor_iterator const &rhs) const
Definition: cursor.hxx:461
bool operator>(icursor_iterator const &rhs) const
Definition: cursor.hxx:457
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:90
result_size_type size_type
Definition: cursor.hxx:167
constexpr std::string const & name() const noexcept
Return this cursor&#39;s name.
Definition: cursor.hxx:235
cursor_base::size_type size_type
Definition: cursor.hxx:277
result_difference_type difference_type
Definition: result.hxx:76
result const * pointer
Definition: cursor.hxx:425
Definition: connection.hxx:99
update_policy
Cursor update policy.
Definition: cursor.hxx:63
Cursor can move forward only.
Definition: cursor.hxx:54
istream_type::difference_type difference_type
Definition: cursor.hxx:429
Cursor can be used to read data but not to write.
Definition: cursor.hxx:66
istream_type::size_type size_type
Definition: cursor.hxx:428
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:76
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result&).
Definition: cursor.hxx:351
bool operator!=(icursor_iterator const &rhs) const noexcept
Definition: cursor.hxx:452
constexpr std::string const & name() const noexcept
Name of underlying SQL cursor.
Definition: cursor.hxx:138
static constexpr difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:119
Common definitions for cursor types.
Definition: cursor.hxx:41
constexpr difference_type stride() const noexcept
Definition: cursor.hxx:367
Result set containing data returned by a query or command.
Definition: result.hxx:72
cursor_base::difference_type difference_type
Definition: cursor.hxx:278
result_difference_type difference_type
Definition: cursor.hxx:168
result_difference_type difference_type
Definition: cursor.hxx:45
bool operator>=(icursor_iterator const &rhs) const
Definition: cursor.hxx:465
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:274
result const & reference
Definition: cursor.hxx:426
ownership_policy
Cursor destruction policy.
Definition: cursor.hxx:87
std::input_iterator_tag iterator_category
Definition: cursor.hxx:423
stateless_cursor(transaction_base &tx, std::string_view query, std::string_view cname, bool hold)
Create cursor.
Definition: cursor.hxx:179
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