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 
146 
147 namespace internal
148 {
150 
164 class PQXX_LIBEXPORT sql_cursor : public cursor_base
165 {
166 public:
167  sql_cursor(
168  transaction_base &t,
169  const std::string &query,
170  const std::string &cname,
174  bool hold);
175 
176  sql_cursor(
177  transaction_base &t,
178  const std::string &cname,
180 
181  ~sql_cursor() noexcept { close(); }
182 
183  result fetch(difference_type rows, difference_type &displacement);
184  result fetch(difference_type rows)
185  { difference_type d=0; return fetch(rows, d); }
186  difference_type move(difference_type rows, difference_type &displacement);
187  difference_type move(difference_type rows)
188  { difference_type d=0; return move(rows, d); }
189 
191 
197  difference_type pos() const noexcept { return m_pos; }
198 
200 
206  difference_type endpos() const noexcept { return m_endpos; }
207 
209  const result &empty_result() const noexcept { return m_empty_result; }
210 
211  void close() noexcept;
212 
213 private:
214  difference_type adjust(difference_type hoped, difference_type actual);
215  static std::string stridestring(difference_type);
217  void init_empty_result(transaction_base &);
218 
220  connection_base &m_home;
221 
223  result m_empty_result;
224 
225  result m_cached_current_row;
226 
228  bool m_adopted;
229 
231  cursor_base::ownershippolicy m_ownership;
232 
234  int m_at_end;
235 
237  difference_type m_pos;
238 
240  difference_type m_endpos = -1;
241 };
242 
243 
245 PQXX_LIBEXPORT result stateless_cursor_retrieve(
246  sql_cursor &,
248  result::difference_type begin_pos,
249  result::difference_type end_pos);
250 
251 } // namespace internal
252 
253 
255 
261 template<cursor_base::updatepolicy up, cursor_base::ownershippolicy op>
263 {
264 public:
267 
270  transaction_base &trans,
271  const std::string &query,
272  const std::string &cname,
273  bool hold) :
274  m_cur(trans, query, cname, cursor_base::random_access, up, op, hold)
275  {
276  }
277 
280  transaction_base &trans,
281  const std::string adopted_cursor) :
282  m_cur(trans, adopted_cursor, op)
283  {
284  // Put cursor in known position
285  m_cur.move(cursor_base::backward_all());
286  }
287 
288  void close() noexcept { m_cur.close(); }
289 
291 
295 
297 
309  {
311  m_cur,
312  result::difference_type(size()),
313  begin_pos,
314  end_pos);
315  }
316 
317  const std::string &name() const noexcept { return m_cur.name(); }
318 
319 private:
320  internal::sql_cursor m_cur;
321 };
322 
323 
324 class icursor_iterator;
325 
326 
327 namespace internal
328 {
329 namespace gate
330 {
331 class icursor_iterator_icursorstream;
332 class icursorstream_icursor_iterator;
333 } // namespace internal::gate
334 } // namespace internal
335 
336 
338 
353 class PQXX_LIBEXPORT icursorstream
354 {
355 public:
358 
360 
372  transaction_base &context,
373  const std::string &query,
374  const std::string &basename,
375  difference_type sstride=1); //[t81]
376 
378 
403  transaction_base &context,
404  const field &cname,
405  difference_type sstride=1,
407 
408  operator bool() const noexcept { return !m_done; }
409 
411 
417  icursorstream &get(result &res) { res = fetchblock(); return *this; } //[t81]
419 
425  icursorstream &operator>>(result &res) { return get(res); } //[t81]
426 
428 
432  icursorstream &ignore(std::streamsize n=1); //[t81]
433 
435 
438  void set_stride(difference_type stride); //[t81]
439  difference_type stride() const noexcept { return m_stride; } //[t81]
440 
441 private:
442  result fetchblock();
443 
444  friend class internal::gate::icursorstream_icursor_iterator;
445  size_type forward(size_type n=1);
446  void insert_iterator(icursor_iterator *) noexcept;
447  void remove_iterator(icursor_iterator *) const noexcept;
448 
449  void service_iterators(difference_type);
450 
451  internal::sql_cursor m_cur;
452 
453  difference_type m_stride;
454  difference_type m_realpos, m_reqpos;
455 
456  mutable icursor_iterator *m_iterators;
457 
458  bool m_done;
459 };
460 
461 
463 
489 class PQXX_LIBEXPORT icursor_iterator :
490  public std::iterator<std::input_iterator_tag,
491  result,
492  cursor_base::size_type,
493  const result *,
494  const result &>
495 {
496 public:
500 
501  icursor_iterator() noexcept; //[t84]
502  explicit icursor_iterator(istream_type &) noexcept; //[t84]
503  icursor_iterator(const icursor_iterator &) noexcept; //[t84]
504  ~icursor_iterator() noexcept;
505 
506  const result &operator*() const { refresh(); return m_here; } //[t84]
507  const result *operator->() const { refresh(); return &m_here; } //[t84]
508  icursor_iterator &operator++(); //[t84]
509  icursor_iterator operator++(int); //[t84]
510  icursor_iterator &operator+=(difference_type); //[t84]
511  icursor_iterator &operator=(const icursor_iterator &) noexcept; //[t84]
512 
513  bool operator==(const icursor_iterator &rhs) const; //[t84]
514  bool operator!=(const icursor_iterator &rhs) const noexcept //[t84]
515  { return !operator==(rhs); }
516  bool operator<(const icursor_iterator &rhs) const; //[t84]
517  bool operator>(const icursor_iterator &rhs) const //[t84]
518  { return rhs < *this; }
519  bool operator<=(const icursor_iterator &rhs) const //[t84]
520  { return !(*this > rhs); }
521  bool operator>=(const icursor_iterator &rhs) const //[t84]
522  { return !(*this < rhs); }
523 
524 private:
525  void refresh() const;
526 
527  friend class internal::gate::icursor_iterator_icursorstream;
528  difference_type pos() const noexcept { return m_pos; }
529  void fill(const result &);
530 
531  icursorstream *m_stream = nullptr;
532  result m_here;
533  difference_type m_pos;
534  icursor_iterator *m_prev = nullptr, *m_next = nullptr;
535 };
536 
537 } // namespace pqxx
538 
539 #include "pqxx/compiler-internal-post.hxx"
540 
541 #endif
const result & empty_result() const noexcept
Return zero-row result for this cursor.
Definition: cursor.hxx:209
bool operator>(const icursor_iterator &rhs) const
Definition: cursor.hxx:517
const std::string & name() const noexcept
Definition: cursor.hxx:317
result_size_type obtain_stateless_cursor_size(sql_cursor &)
Definition: cursor.cxx:288
result fetch(difference_type rows)
Definition: cursor.hxx:184
cursor_base::difference_type difference_type
Definition: cursor.hxx:357
bool operator!=(const icursor_iterator &rhs) const noexcept
Definition: cursor.hxx:514
const std::string m_name
Definition: cursor.hxx:143
Cursor can be used to read data but not to write.
Definition: cursor.hxx:65
result_difference_type difference_type
Definition: cursor.hxx:44
istream_type::difference_type difference_type
Definition: cursor.hxx:499
result_difference_type difference_type
Definition: result.hxx:71
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:489
Cursor with SQL positioning semantics.
Definition: cursor.hxx:164
result stateless_cursor_retrieve(sql_cursor &, result::difference_type size, result::difference_type begin_pos, result::difference_type end_pos)
Definition: cursor.cxx:295
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:22
result_size_type size_type
Definition: cursor.hxx:43
stateless_cursor(transaction_base &trans, const std::string adopted_cursor)
Adopt existing scrolling SQL cursor.
Definition: cursor.hxx:279
updatepolicy
Cursor update policy.
Definition: cursor.hxx:62
const std::string & name() const noexcept
Name of underlying SQL cursor.
Definition: cursor.hxx:135
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:353
bool operator>=(const icursor_iterator &rhs) const
Definition: cursor.hxx:521
Common definitions for cursor types.
Definition: cursor.hxx:40
Cursor can move forward only.
Definition: cursor.hxx:53
bool operator<=(const icursor_iterator &rhs) const
Definition: cursor.hxx:519
accesspolicy
Cursor access-pattern policy.
Definition: cursor.hxx:50
Result set containing data returned by a query or command.
Definition: result.hxx:67
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:130
difference_type move(difference_type rows)
Definition: cursor.hxx:187
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:92
stateless_cursor(transaction_base &trans, const std::string &query, const std::string &cname, bool hold)
Create cursor.
Definition: cursor.hxx:269
difference_type stride() const noexcept
Definition: cursor.hxx:439
istream_type::size_type size_type
Definition: cursor.hxx:498
difference_type pos() const noexcept
Current position, or -1 for unknown.
Definition: cursor.hxx:197
static difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:120
size_type size()
Number of rows in cursor&#39;s result set.
Definition: cursor.hxx:294
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:308
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:51
void close() noexcept
Definition: cursor.hxx:288
signed long result_difference_type
Difference between result sizes.
Definition: types.hxx:19
unsigned long result_size_type
Number of rows in a result set.
Definition: types.hxx:16
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result &)
Definition: cursor.hxx:425
result_size_type size_type
Definition: cursor.hxx:265
ownershippolicy
Cursor destruction policy.
Definition: cursor.hxx:89
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:138
cursor_base::size_type size_type
Definition: cursor.hxx:356
const result * operator->() const
Definition: cursor.hxx:507
result_difference_type difference_type
Definition: cursor.hxx:266
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:262
Reference to a field in a result set.
Definition: field.hxx:41
difference_type endpos() const noexcept
End position, or -1 for unknown.
Definition: cursor.hxx:206
~sql_cursor() noexcept
Definition: cursor.hxx:181