libpqxx  7.5.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-2021, 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 
163  transaction_base &trans, std::string_view query, std::string_view cname,
164  bool hold) :
165  m_cur{trans, query, cname, cursor_base::random_access, up, op, hold}
166  {}
167 
169  stateless_cursor(transaction_base &trans, std::string_view adopted_cursor) :
170  m_cur{trans, adopted_cursor, op}
171  {
172  // Put cursor in known position
173  m_cur.move(cursor_base::backward_all());
174  }
175 
177  void close() noexcept { m_cur.close(); }
178 
180 
183  [[nodiscard]] size_type size()
184  {
185  return internal::obtain_stateless_cursor_size(m_cur);
186  }
187 
189 
201  {
202  return internal::stateless_cursor_retrieve(
203  m_cur, result::difference_type(size()), begin_pos, end_pos);
204  }
205 
207  [[nodiscard]] std::string const &name() const noexcept
208  {
209  return m_cur.name();
210  }
211 
212 private:
213  internal::sql_cursor m_cur;
214 };
215 
216 
217 class icursor_iterator;
218 } // namespace pqxx
219 
220 
221 namespace pqxx::internal::gate
222 {
223 class icursor_iterator_icursorstream;
224 class icursorstream_icursor_iterator;
225 } // namespace pqxx::internal::gate
226 
227 
228 namespace pqxx
229 {
231 
246 class PQXX_LIBEXPORT icursorstream
247 {
248 public:
251 
253 
265  transaction_base &context, std::string_view query,
266  std::string_view basename, difference_type sstride = 1);
267 
269 
294  transaction_base &context, field const &cname, difference_type sstride = 1,
296 
298  operator bool() const noexcept { return not m_done; }
299 
301 
308  {
309  res = fetchblock();
310  return *this;
311  }
313 
319  icursorstream &operator>>(result &res) { return get(res); }
320 
322 
326  icursorstream &ignore(std::streamsize n = 1);
327 
329 
332  void set_stride(difference_type stride);
333  [[nodiscard]] difference_type stride() const noexcept { return m_stride; }
334 
335 private:
336  result fetchblock();
337 
338  friend class internal::gate::icursorstream_icursor_iterator;
339  size_type forward(size_type n = 1);
340  void insert_iterator(icursor_iterator *) noexcept;
341  void remove_iterator(icursor_iterator *) const noexcept;
342 
343  void service_iterators(difference_type);
344 
345  internal::sql_cursor m_cur;
346 
347  difference_type m_stride;
348  difference_type m_realpos, m_reqpos;
349 
350  mutable icursor_iterator *m_iterators;
351 
352  bool m_done;
353 };
354 
355 
357 
383 class PQXX_LIBEXPORT icursor_iterator
384 {
385 public:
386  using iterator_category = std::input_iterator_tag;
388  using pointer = result const *;
389  using reference = result const &;
393 
394  icursor_iterator() noexcept;
395  explicit icursor_iterator(istream_type &) noexcept;
396  icursor_iterator(icursor_iterator const &) noexcept;
397  ~icursor_iterator() noexcept;
398 
399  result const &operator*() const
400  {
401  refresh();
402  return m_here;
403  }
404  result const *operator->() const
405  {
406  refresh();
407  return &m_here;
408  }
409  icursor_iterator &operator++();
410  icursor_iterator operator++(int);
411  icursor_iterator &operator+=(difference_type);
412  icursor_iterator &operator=(icursor_iterator const &) noexcept;
413 
414  [[nodiscard]] bool operator==(icursor_iterator const &rhs) const;
415  [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept
416  {
417  return not operator==(rhs);
418  }
419  [[nodiscard]] bool operator<(icursor_iterator const &rhs) const;
420  [[nodiscard]] bool operator>(icursor_iterator const &rhs) const
421  {
422  return rhs < *this;
423  }
424  [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const
425  {
426  return not(*this > rhs);
427  }
428  [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const
429  {
430  return not(*this < rhs);
431  }
432 
433 private:
434  void refresh() const;
435 
436  friend class internal::gate::icursor_iterator_icursorstream;
437  difference_type pos() const noexcept { return m_pos; }
438  void fill(result const &);
439 
440  icursorstream *m_stream{nullptr};
441  result m_here;
442  difference_type m_pos;
443  icursor_iterator *m_prev{nullptr}, *m_next{nullptr};
444 };
445 } // namespace pqxx
446 
447 #include "pqxx/internal/compiler-internal-post.hxx"
448 #endif
access_policy
Cursor access-pattern policy.
Definition: cursor.hxx:50
cursor_base::difference_type difference_type
Definition: cursor.hxx:250
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:383
result_size_type size_type
Definition: cursor.hxx:43
void close() noexcept
Close this cursor. The destructor will do this automatically.
Definition: cursor.hxx:177
std::string const m_name
Definition: cursor.hxx:137
size_type size()
Number of rows in cursor&#39;s result set.
Definition: cursor.hxx:183
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:200
std::string const & name() const noexcept
Name of underlying SQL cursor.
Definition: cursor.hxx:132
Cursor can move back and forth.
Definition: cursor.hxx:55
istream_type::difference_type difference_type
Definition: cursor.hxx:392
Result set containing data returned by a query or command.
Definition: result.hxx:70
Definition: connection.hxx:97
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
result_size_type size_type
Definition: cursor.hxx:158
result_difference_type difference_type
Definition: result.hxx:74
bool operator<=(icursor_iterator const &rhs) const
Definition: cursor.hxx:424
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:89
int result_size_type
Number of rows in a result set.
Definition: types.hxx:18
bool operator>(icursor_iterator const &rhs) const
Definition: cursor.hxx:420
bool operator>=(icursor_iterator const &rhs) const
Definition: cursor.hxx:428
result const * operator->() const
Definition: cursor.hxx:404
Cursor can move forward only.
Definition: cursor.hxx:53
bool operator!=(icursor_iterator const &rhs) const noexcept
Definition: cursor.hxx:415
Common definitions for cursor types.
Definition: cursor.hxx:40
result const * pointer
Definition: cursor.hxx:388
Cursor can be used to read data but not to write.
Definition: cursor.hxx:65
update_policy
Cursor update policy.
Definition: cursor.hxx:62
result_difference_type difference_type
Definition: cursor.hxx:159
result_difference_type difference_type
Definition: cursor.hxx:44
stateless_cursor(transaction_base &trans, std::string_view adopted_cursor)
Adopt existing scrolling SQL cursor.
Definition: cursor.hxx:169
stateless_cursor(transaction_base &trans, std::string_view query, std::string_view cname, bool hold)
Create cursor.
Definition: cursor.hxx:162
difference_type stride() const noexcept
Definition: cursor.hxx:333
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:246
static difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:117
Reference to a field in a result set.
Definition: field.hxx:33
result const & reference
Definition: cursor.hxx:389
int result_difference_type
Difference between result sizes.
Definition: types.hxx:21
ownership_policy
Cursor destruction policy.
Definition: cursor.hxx:86
std::input_iterator_tag iterator_category
Definition: cursor.hxx:386
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:74
cursor_base::size_type size_type
Definition: cursor.hxx:249
Connection to a database.
Definition: connection.hxx:183
istream_type::size_type size_type
Definition: cursor.hxx:391
std::string const & name() const noexcept
Return this cursor&#39;s name.
Definition: cursor.hxx:207
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result &)
Definition: cursor.hxx:319
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:32
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:155