libpqxx  7.6.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 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/internal/compiler-internal-pre.hxx"
18 
19 #include <limits>
20 #include <stdexcept>
21 
22 #include "pqxx/result.hxx"
23 #include "pqxx/transaction_base.hxx"
24 
25 
26 namespace pqxx
27 {
29 
40 class PQXX_LIBEXPORT cursor_base
41 {
42 public:
45 
47 
51  {
55  random_access
56  };
57 
59 
63  {
67  update
68  };
69 
71 
87  {
91  loose
92  };
93 
94  cursor_base() = delete;
95  cursor_base(cursor_base const &) = delete;
96  cursor_base &operator=(cursor_base const &) = delete;
97 
102 
104 
107  [[nodiscard]] static difference_type all() noexcept;
108 
110 
112  [[nodiscard]] static difference_type next() noexcept { return 1; }
113 
115 
117  [[nodiscard]] static difference_type prior() noexcept { return -1; }
118 
120 
122  [[nodiscard]] static difference_type backward_all() noexcept;
123 
125 
127 
132  [[nodiscard]] std::string const &name() const noexcept { return m_name; }
133 
134 protected:
135  cursor_base(connection &, std::string_view Name, bool embellish_name = true);
136 
137  std::string const m_name;
138 };
139 } // namespace pqxx
140 
141 
142 #include <pqxx/internal/sql_cursor.hxx>
143 
144 
145 namespace pqxx
146 {
148 
154 template<cursor_base::update_policy up, cursor_base::ownership_policy op>
156 {
157 public:
160 
162 
169  transaction_base &trans, std::string_view query, std::string_view cname,
170  bool hold) :
171  m_cur{trans, query, cname, cursor_base::random_access, up, op, hold}
172  {}
173 
175 
181  stateless_cursor(transaction_base &trans, std::string_view adopted_cursor) :
182  m_cur{trans, adopted_cursor, op}
183  {
184  // Put cursor in known position
185  m_cur.move(cursor_base::backward_all());
186  }
187 
189 
194  void close() noexcept { m_cur.close(); }
195 
197 
200  [[nodiscard]] size_type size()
201  {
202  return internal::obtain_stateless_cursor_size(m_cur);
203  }
204 
206 
218  {
219  return internal::stateless_cursor_retrieve(
220  m_cur, result::difference_type(size()), begin_pos, end_pos);
221  }
222 
224  [[nodiscard]] std::string const &name() const noexcept
225  {
226  return m_cur.name();
227  }
228 
229 private:
230  internal::sql_cursor m_cur;
231 };
232 
233 
234 class icursor_iterator;
235 } // namespace pqxx
236 
237 
238 namespace pqxx::internal::gate
239 {
240 class icursor_iterator_icursorstream;
241 class icursorstream_icursor_iterator;
242 } // namespace pqxx::internal::gate
243 
244 
245 namespace pqxx
246 {
248 
263 class PQXX_LIBEXPORT icursorstream
264 {
265 public:
268 
270 
282  transaction_base &context, std::string_view query,
283  std::string_view basename, difference_type sstride = 1);
284 
286 
311  transaction_base &context, field const &cname, difference_type sstride = 1,
313 
315  operator bool() const noexcept { return not m_done; }
316 
318 
327  {
328  res = fetchblock();
329  return *this;
330  }
332 
340  icursorstream &operator>>(result &res) { return get(res); }
341 
343 
349  icursorstream &ignore(std::streamsize n = 1);
350 
352 
355  void set_stride(difference_type stride);
356  [[nodiscard]] difference_type stride() const noexcept { return m_stride; }
357 
358 private:
359  result fetchblock();
360 
361  friend class internal::gate::icursorstream_icursor_iterator;
362  size_type forward(size_type n = 1);
363  void insert_iterator(icursor_iterator *) noexcept;
364  void remove_iterator(icursor_iterator *) const noexcept;
365 
366  void service_iterators(difference_type);
367 
368  internal::sql_cursor m_cur;
369 
370  difference_type m_stride;
371  difference_type m_realpos, m_reqpos;
372 
373  mutable icursor_iterator *m_iterators;
374 
375  bool m_done;
376 };
377 
378 
380 
406 class PQXX_LIBEXPORT icursor_iterator
407 {
408 public:
409  using iterator_category = std::input_iterator_tag;
411  using pointer = result const *;
412  using reference = result const &;
416 
417  icursor_iterator() noexcept;
418  explicit icursor_iterator(istream_type &) noexcept;
419  icursor_iterator(icursor_iterator const &) noexcept;
420  ~icursor_iterator() noexcept;
421 
422  result const &operator*() const
423  {
424  refresh();
425  return m_here;
426  }
427  result const *operator->() const
428  {
429  refresh();
430  return &m_here;
431  }
432  icursor_iterator &operator++();
433  icursor_iterator operator++(int);
434  icursor_iterator &operator+=(difference_type);
435  icursor_iterator &operator=(icursor_iterator const &) noexcept;
436 
437  [[nodiscard]] bool operator==(icursor_iterator const &rhs) const;
438  [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept
439  {
440  return not operator==(rhs);
441  }
442  [[nodiscard]] bool operator<(icursor_iterator const &rhs) const;
443  [[nodiscard]] bool operator>(icursor_iterator const &rhs) const
444  {
445  return rhs < *this;
446  }
447  [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const
448  {
449  return not(*this > rhs);
450  }
451  [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const
452  {
453  return not(*this < rhs);
454  }
455 
456 private:
457  void refresh() const;
458 
459  friend class internal::gate::icursor_iterator_icursorstream;
460  difference_type pos() const noexcept { return m_pos; }
461  void fill(result const &);
462 
463  icursorstream *m_stream{nullptr};
464  result m_here;
465  difference_type m_pos;
466  icursor_iterator *m_prev{nullptr}, *m_next{nullptr};
467 };
468 } // namespace pqxx
469 
470 #include "pqxx/internal/compiler-internal-post.hxx"
471 #endif
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
int result_difference_type
Difference between result sizes.
Definition: types.hxx:27
int result_size_type
Number of rows in a result set.
Definition: types.hxx:24
Definition: connection.hxx:95
Connection to a database.
Definition: connection.hxx:181
Common definitions for cursor types.
Definition: cursor.hxx:41
cursor_base & operator=(cursor_base const &)=delete
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:32
static difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:117
result_size_type size_type
Definition: cursor.hxx:43
cursor_base(cursor_base const &)=delete
cursor_base()=delete
access_policy
Cursor access-pattern policy.
Definition: cursor.hxx:51
@ forward_only
Cursor can move forward only.
Definition: cursor.hxx:53
ownership_policy
Cursor destruction policy.
Definition: cursor.hxx:87
@ owned
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:89
update_policy
Cursor update policy.
Definition: cursor.hxx:63
@ read_only
Cursor can be used to read data but not to write.
Definition: cursor.hxx:65
result_difference_type difference_type
Definition: cursor.hxx:44
std::string const m_name
Definition: cursor.hxx:137
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:156
std::string const & name() const noexcept
Return this cursor's name.
Definition: cursor.hxx:224
void close() noexcept
Close this cursor.
Definition: cursor.hxx:194
stateless_cursor(transaction_base &trans, std::string_view adopted_cursor)
Adopt an existing scrolling SQL cursor.
Definition: cursor.hxx:181
result_size_type size_type
Definition: cursor.hxx:158
result_difference_type difference_type
Definition: cursor.hxx:159
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:217
stateless_cursor(transaction_base &trans, std::string_view query, std::string_view cname, bool hold)
Create cursor.
Definition: cursor.hxx:168
size_type size()
Number of rows in cursor's result set.
Definition: cursor.hxx:200
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:264
icursorstream & get(result &res)
Read new value into given result object; same as operator >>.
Definition: cursor.hxx:326
cursor_base::size_type size_type
Definition: cursor.hxx:266
difference_type stride() const noexcept
Definition: cursor.hxx:356
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result&).
Definition: cursor.hxx:340
cursor_base::difference_type difference_type
Definition: cursor.hxx:267
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:407
result const * operator->() const
Definition: cursor.hxx:427
bool operator!=(icursor_iterator const &rhs) const noexcept
Definition: cursor.hxx:438
result const * pointer
Definition: cursor.hxx:411
bool operator>=(icursor_iterator const &rhs) const
Definition: cursor.hxx:451
bool operator>(icursor_iterator const &rhs) const
Definition: cursor.hxx:443
result const & reference
Definition: cursor.hxx:412
istream_type::difference_type difference_type
Definition: cursor.hxx:415
std::input_iterator_tag iterator_category
Definition: cursor.hxx:409
bool operator<=(icursor_iterator const &rhs) const
Definition: cursor.hxx:447
istream_type::size_type size_type
Definition: cursor.hxx:414
Reference to a field in a result set.
Definition: field.hxx:34
Result set containing data returned by a query or command.
Definition: result.hxx:71
result_difference_type difference_type
Definition: result.hxx:74
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:76