libpqxx  7.7.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-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 <limits>
17 #include <stdexcept>
18 
19 #include "pqxx/result.hxx"
20 #include "pqxx/transaction_base.hxx"
21 
22 
23 namespace pqxx
24 {
26 
37 class PQXX_LIBEXPORT cursor_base
38 {
39 public:
42 
44 
48  {
52  random_access
53  };
54 
56 
60  {
64  update
65  };
66 
68 
84  {
88  loose
89  };
90 
91  cursor_base() = delete;
92  cursor_base(cursor_base const &) = delete;
93  cursor_base &operator=(cursor_base const &) = delete;
94 
99 
101 
104  [[nodiscard]] static difference_type all() noexcept;
105 
107 
109  [[nodiscard]] static difference_type next() noexcept { return 1; }
110 
112 
114  [[nodiscard]] static difference_type prior() noexcept { return -1; }
115 
117 
119  [[nodiscard]] static difference_type backward_all() noexcept;
120 
122 
124 
129  [[nodiscard]] std::string const &name() const noexcept { return m_name; }
130 
131 protected:
132  cursor_base(connection &, std::string_view Name, bool embellish_name = true);
133 
134  std::string const m_name;
135 };
136 } // namespace pqxx
137 
138 
139 #include <pqxx/internal/sql_cursor.hxx>
140 
141 
142 namespace pqxx
143 {
145 
151 template<cursor_base::update_policy up, cursor_base::ownership_policy op>
153 {
154 public:
157 
159 
168  transaction_base &tx, std::string_view query, std::string_view cname,
169  bool hold) :
170  m_cur{tx, query, cname, cursor_base::random_access, up, op, hold}
171  {}
172 
174 
180  stateless_cursor(transaction_base &tx, std::string_view adopted_cursor) :
181  m_cur{tx, adopted_cursor, op}
182  {
183  // Put cursor in known position
184  m_cur.move(cursor_base::backward_all());
185  }
186 
188 
193  void close() noexcept { m_cur.close(); }
194 
196 
199  [[nodiscard]] size_type size()
200  {
201  return internal::obtain_stateless_cursor_size(m_cur);
202  }
203 
205 
217  {
218  return internal::stateless_cursor_retrieve(
219  m_cur, result::difference_type(size()), begin_pos, end_pos);
220  }
221 
223  [[nodiscard]] std::string const &name() const noexcept
224  {
225  return m_cur.name();
226  }
227 
228 private:
229  internal::sql_cursor m_cur;
230 };
231 
232 
233 class icursor_iterator;
234 } // namespace pqxx
235 
236 
237 namespace pqxx::internal::gate
238 {
239 class icursor_iterator_icursorstream;
240 class icursorstream_icursor_iterator;
241 } // namespace pqxx::internal::gate
242 
243 
244 namespace pqxx
245 {
247 
262 class PQXX_LIBEXPORT icursorstream
263 {
264 public:
267 
269 
281  transaction_base &context, std::string_view query,
282  std::string_view basename, difference_type sstride = 1);
283 
285 
310  transaction_base &context, field const &cname, difference_type sstride = 1,
312 
314  operator bool() const &noexcept { return not m_done; }
315 
317 
326  {
327  res = fetchblock();
328  return *this;
329  }
331 
339  icursorstream &operator>>(result &res) { return get(res); }
340 
342 
348  icursorstream &ignore(std::streamsize n = 1) &;
349 
351 
354  void set_stride(difference_type stride) &;
355  [[nodiscard]] difference_type stride() const noexcept { return m_stride; }
356 
357 private:
358  result fetchblock();
359 
360  friend class internal::gate::icursorstream_icursor_iterator;
361  size_type forward(size_type n = 1);
362  void insert_iterator(icursor_iterator *) noexcept;
363  void remove_iterator(icursor_iterator *) const noexcept;
364 
365  void service_iterators(difference_type);
366 
367  internal::sql_cursor m_cur;
368 
369  difference_type m_stride;
370  difference_type m_realpos, m_reqpos;
371 
372  mutable icursor_iterator *m_iterators;
373 
374  bool m_done;
375 };
376 
377 
379 
405 class PQXX_LIBEXPORT icursor_iterator
406 {
407 public:
408  using iterator_category = std::input_iterator_tag;
410  using pointer = result const *;
411  using reference = result const &;
415 
416  icursor_iterator() noexcept;
417  explicit icursor_iterator(istream_type &) noexcept;
418  icursor_iterator(icursor_iterator const &) noexcept;
419  ~icursor_iterator() noexcept;
420 
421  result const &operator*() const
422  {
423  refresh();
424  return m_here;
425  }
426  result const *operator->() const
427  {
428  refresh();
429  return &m_here;
430  }
431  icursor_iterator &operator++();
432  icursor_iterator operator++(int);
433  icursor_iterator &operator+=(difference_type);
434  icursor_iterator &operator=(icursor_iterator const &) noexcept;
435 
436  [[nodiscard]] bool operator==(icursor_iterator const &rhs) const;
437  [[nodiscard]] bool operator!=(icursor_iterator const &rhs) const noexcept
438  {
439  return not operator==(rhs);
440  }
441  [[nodiscard]] bool operator<(icursor_iterator const &rhs) const;
442  [[nodiscard]] bool operator>(icursor_iterator const &rhs) const
443  {
444  return rhs < *this;
445  }
446  [[nodiscard]] bool operator<=(icursor_iterator const &rhs) const
447  {
448  return not(*this > rhs);
449  }
450  [[nodiscard]] bool operator>=(icursor_iterator const &rhs) const
451  {
452  return not(*this < rhs);
453  }
454 
455 private:
456  void refresh() const;
457 
458  friend class internal::gate::icursor_iterator_icursorstream;
459  difference_type pos() const noexcept { return m_pos; }
460  void fill(result const &);
461 
462  icursorstream *m_stream{nullptr};
463  result m_here;
464  difference_type m_pos;
465  icursor_iterator *m_prev{nullptr}, *m_next{nullptr};
466 };
467 } // namespace pqxx
468 #endif
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:405
Common definitions for cursor types.
Definition: cursor.hxx:37
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:72
bool operator!=(icursor_iterator const &rhs) const noexcept
Definition: cursor.hxx:437
std::string const m_name
Definition: cursor.hxx:134
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:262
Reference to a field in a result set.
Definition: field.hxx:30
Cursor can move back and forth.
Definition: cursor.hxx:52
istream_type::difference_type difference_type
Definition: cursor.hxx:414
Result set containing data returned by a query or command.
Definition: result.hxx:67
result const * operator->() const
Definition: cursor.hxx:426
update_policy
Cursor update policy.
Definition: cursor.hxx:59
result_difference_type difference_type
Definition: cursor.hxx:41
int result_size_type
Number of rows in a result set.
Definition: types.hxx:24
std::string const & name() const noexcept
Return this cursor&#39;s name.
Definition: cursor.hxx:223
difference_type stride() const noexcept
Definition: cursor.hxx:355
result_size_type size_type
Definition: cursor.hxx:40
istream_type::size_type size_type
Definition: cursor.hxx:413
stateless_cursor(transaction_base &tx, std::string_view query, std::string_view cname, bool hold)
Create cursor.
Definition: cursor.hxx:167
Cursor can be used to read data but not to write.
Definition: cursor.hxx:62
Definition: connection.hxx:94
std::input_iterator_tag iterator_category
Definition: cursor.hxx:408
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:216
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:22
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:86
result_difference_type difference_type
Definition: result.hxx:71
void close() noexcept
Close this cursor.
Definition: cursor.hxx:193
Cursor can move forward only.
Definition: cursor.hxx:50
result_size_type size_type
Definition: cursor.hxx:155
bool operator>(icursor_iterator const &rhs) const
Definition: cursor.hxx:442
bool operator>=(icursor_iterator const &rhs) const
Definition: cursor.hxx:450
size_type size()
Number of rows in cursor&#39;s result set.
Definition: cursor.hxx:199
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:32
result_difference_type difference_type
Definition: cursor.hxx:156
ownership_policy
Cursor destruction policy.
Definition: cursor.hxx:83
STL namespace.
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:152
bool operator<=(icursor_iterator const &rhs) const
Definition: cursor.hxx:446
result const * pointer
Definition: cursor.hxx:410
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result&).
Definition: cursor.hxx:339
static difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:114
cursor_base::size_type size_type
Definition: cursor.hxx:265
access_policy
Cursor access-pattern policy.
Definition: cursor.hxx:47
int result_difference_type
Difference between result sizes.
Definition: types.hxx:27
stateless_cursor(transaction_base &tx, std::string_view adopted_cursor)
Adopt an existing scrolling SQL cursor.
Definition: cursor.hxx:180
result const & reference
Definition: cursor.hxx:411
Connection to a database.
Definition: connection.hxx:180
cursor_base::difference_type difference_type
Definition: cursor.hxx:266