libpqxx
cursor.hxx
1 
13 #ifndef PQXX_H_CURSOR
14 #define PQXX_H_CURSOR
15 
16 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/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 
90  {
94  loose
95  };
96 
97  cursor_base() =delete;
98  cursor_base(const cursor_base &) =delete;
99  cursor_base &operator=(const cursor_base &) =delete;
100 
105 
107 
110  static difference_type all() noexcept; //[t81]
111 
113 
115  static difference_type next() noexcept { return 1; } //[t81]
116 
118 
120  static difference_type prior() noexcept { return -1; } //[t00]
121 
123 
125  static difference_type backward_all() noexcept; //[t00]
126 
128 
130 
135  const std::string &name() const noexcept { return m_name; } //[t81]
136 
137 protected:
138  cursor_base(
139  connection_base &,
140  const std::string &Name,
141  bool embellish_name=true);
142 
143  const std::string m_name;
144 };
145 } // namespace pqxx
146 
147 
148 #include <pqxx/internal/sql_cursor.hxx>
149 
150 
151 namespace pqxx
152 {
154 
160 template<cursor_base::updatepolicy up, cursor_base::ownershippolicy op>
162 {
163 public:
166 
169  transaction_base &trans,
170  const std::string &query,
171  const std::string &cname,
172  bool hold) :
173  m_cur{trans, query, cname, cursor_base::random_access, up, op, hold}
174  {
175  }
176 
179  transaction_base &trans,
180  const std::string adopted_cursor) :
181  m_cur{trans, adopted_cursor, op}
182  {
183  // Put cursor in known position
184  m_cur.move(cursor_base::backward_all());
185  }
186 
187  void close() noexcept { m_cur.close(); }
188 
190 
193  size_type size() { return internal::obtain_stateless_cursor_size(m_cur); }
194 
196 
208  {
209  return internal::stateless_cursor_retrieve(
210  m_cur,
211  result::difference_type(size()),
212  begin_pos,
213  end_pos);
214  }
215 
216  const std::string &name() const noexcept { return m_cur.name(); }
217 
218 private:
219  internal::sql_cursor m_cur;
220 };
221 
222 
223 class icursor_iterator;
224 
225 
226 namespace internal
227 {
228 namespace gate
229 {
230 class icursor_iterator_icursorstream;
231 class icursorstream_icursor_iterator;
232 } // namespace internal::gate
233 } // namespace internal
234 
235 
237 
252 class PQXX_LIBEXPORT icursorstream
253 {
254 public:
257 
259 
271  transaction_base &context,
272  const std::string &query,
273  const std::string &basename,
274  difference_type sstride=1); //[t81]
275 
277 
302  transaction_base &context,
303  const field &cname,
304  difference_type sstride=1,
306 
307  operator bool() const noexcept { return not m_done; }
308 
310 
316  icursorstream &get(result &res) { res = fetchblock(); return *this; } //[t81]
318 
324  icursorstream &operator>>(result &res) { return get(res); } //[t81]
325 
327 
331  icursorstream &ignore(std::streamsize n=1); //[t81]
332 
334 
337  void set_stride(difference_type stride); //[t81]
338  difference_type stride() const noexcept { return m_stride; } //[t81]
339 
340 private:
341  result fetchblock();
342 
343  friend class internal::gate::icursorstream_icursor_iterator;
344  size_type forward(size_type n=1);
345  void insert_iterator(icursor_iterator *) noexcept;
346  void remove_iterator(icursor_iterator *) const noexcept;
347 
348  void service_iterators(difference_type);
349 
350  internal::sql_cursor m_cur;
351 
352  difference_type m_stride;
353  difference_type m_realpos, m_reqpos;
354 
355  mutable icursor_iterator *m_iterators;
356 
357  bool m_done;
358 };
359 
360 
362 
388 class PQXX_LIBEXPORT icursor_iterator
389 {
390 public:
391  using iterator_category = std::input_iterator_tag;
393  using pointer = const result *;
394  using reference = const result &;
398 
399  icursor_iterator() noexcept; //[t84]
400  explicit icursor_iterator(istream_type &) noexcept; //[t84]
401  icursor_iterator(const icursor_iterator &) noexcept; //[t84]
402  ~icursor_iterator() noexcept;
403 
404  const result &operator*() const { refresh(); return m_here; } //[t84]
405  const result *operator->() const { refresh(); return &m_here; } //[t84]
406  icursor_iterator &operator++(); //[t84]
407  icursor_iterator operator++(int); //[t84]
408  icursor_iterator &operator+=(difference_type); //[t84]
409  icursor_iterator &operator=(const icursor_iterator &) noexcept; //[t84]
410 
411  bool operator==(const icursor_iterator &rhs) const; //[t84]
412  bool operator!=(const icursor_iterator &rhs) const noexcept //[t84]
413  { return not operator==(rhs); }
414  bool operator<(const icursor_iterator &rhs) const; //[t84]
415  bool operator>(const icursor_iterator &rhs) const //[t84]
416  { return rhs < *this; }
417  bool operator<=(const icursor_iterator &rhs) const //[t84]
418  { return not (*this > rhs); }
419  bool operator>=(const icursor_iterator &rhs) const //[t84]
420  { return not (*this < rhs); }
421 
422 private:
423  void refresh() const;
424 
425  friend class internal::gate::icursor_iterator_icursorstream;
426  difference_type pos() const noexcept { return m_pos; }
427  void fill(const result &);
428 
429  icursorstream *m_stream = nullptr;
430  result m_here;
431  difference_type m_pos;
432  icursor_iterator *m_prev = nullptr, *m_next = nullptr;
433 };
434 } // namespace pqxx
435 
436 #include "pqxx/compiler-internal-post.hxx"
437 #endif
bool operator!=(const icursor_iterator &rhs) const noexcept
Definition: cursor.hxx:412
size_type size()
Number of rows in cursor&#39;s result set.
Definition: cursor.hxx:193
const std::string & name() const noexcept
Name of underlying SQL cursor.
Definition: cursor.hxx:135
istream_type::difference_type difference_type
Definition: cursor.hxx:397
void close() noexcept
Definition: cursor.hxx:187
cursor_base::difference_type difference_type
Definition: cursor.hxx:256
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:388
istream_type::size_type size_type
Definition: cursor.hxx:396
signed long result_difference_type
Difference between result sizes.
Definition: types.hxx:21
unsigned long result_size_type
Number of rows in a result set.
Definition: types.hxx:18
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:35
stateless_cursor(transaction_base &trans, const std::string adopted_cursor)
Adopt existing scrolling SQL cursor.
Definition: cursor.hxx:178
Result set containing data returned by a query or command.
Definition: result.hxx:69
Common definitions for cursor types.
Definition: cursor.hxx:40
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:139
const std::string & name() const noexcept
Definition: cursor.hxx:216
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:136
stateless_cursor(transaction_base &trans, const std::string &query, const std::string &cname, bool hold)
Create cursor.
Definition: cursor.hxx:168
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:252
bool operator>=(const icursor_iterator &rhs) const
Definition: cursor.hxx:419
const std::string m_name
Definition: cursor.hxx:143
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:207
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result &)
Definition: cursor.hxx:324
Cursor can move back and forth.
Definition: cursor.hxx:55
result_size_type size_type
Definition: cursor.hxx:43
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:161
bool operator>(const icursor_iterator &rhs) const
Definition: cursor.hxx:415
Reference to a field in a result set.
Definition: field.hxx:49
result_difference_type difference_type
Definition: result.hxx:73
std::input_iterator_tag iterator_category
Definition: cursor.hxx:391
result_size_type size_type
Definition: cursor.hxx:164
ownershippolicy
Cursor destruction policy.
Definition: cursor.hxx:89
accesspolicy
Cursor access-pattern policy.
Definition: cursor.hxx:50
Cursor can move forward only.
Definition: cursor.hxx:53
result_difference_type difference_type
Definition: cursor.hxx:44
cursor_base::size_type size_type
Definition: cursor.hxx:255
result_difference_type difference_type
Definition: cursor.hxx:165
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:92
Cursor can be used to read data but not to write.
Definition: cursor.hxx:65
difference_type stride() const noexcept
Definition: cursor.hxx:338
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
updatepolicy
Cursor update policy.
Definition: cursor.hxx:62
static difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:120
bool operator<=(const icursor_iterator &rhs) const
Definition: cursor.hxx:417
const result * operator->() const
Definition: cursor.hxx:405