libpqxx  5.0
cursor.hxx
1 /*-------------------------------------------------------------------------
2  *
3  * FILE
4  * pqxx/cursor.hxx
5  *
6  * DESCRIPTION
7  * definition of the iterator/container-style cursor classes
8  * C++-style wrappers for SQL cursors
9  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead.
10  *
11  * Copyright (c) 2004-2015, Jeroen T. Vermeulen <jtv@xs4all.nl>
12  *
13  * See COPYING for copyright license. If you did not receive a file called
14  * COPYING with this source code, please notify the distributor of this mistake,
15  * or contact the author.
16  *
17  *-------------------------------------------------------------------------
18  */
19 #ifndef PQXX_H_CURSOR
20 #define PQXX_H_CURSOR
21 
22 #include "pqxx/compiler-public.hxx"
23 #include "pqxx/compiler-internal-pre.hxx"
24 
25 #include <limits>
26 #include <stdexcept>
27 
28 #include "pqxx/result"
29 #include "pqxx/transaction_base"
30 
31 
32 namespace pqxx
33 {
34 class dbtransaction;
35 
36 
38 
49 class PQXX_LIBEXPORT cursor_base
50 {
51 public:
54 
56 
60  {
64  random_access
65  };
66 
68 
72  {
76  update
77  };
78 
80 
99  {
103  loose
104  };
105 
110 
114  static difference_type all() PQXX_NOEXCEPT; //[t81]
116 
118  static difference_type next() PQXX_NOEXCEPT { return 1; } //[t81]
120 
122  static difference_type prior() PQXX_NOEXCEPT { return -1; } //[t0]
124 
126  static difference_type backward_all() PQXX_NOEXCEPT; //[t0]
127 
129 
131 
136  const std::string &name() const PQXX_NOEXCEPT { return m_name; } //[t81]
137 
138 protected:
140  const std::string &Name,
141  bool embellish_name=true);
142 
143  const std::string m_name;
144 
145 private:
147  cursor_base();
149  cursor_base(const cursor_base &);
151  cursor_base &operator=(const cursor_base &);
152 };
153 
154 
156 {
157  return std::numeric_limits<int>::max()-1;
158 }
159 
161 {
162  return std::numeric_limits<int>::min()+1;
163 }
164 
165 
166 namespace internal
167 {
169 
183 class PQXX_LIBEXPORT sql_cursor : public cursor_base
184 {
185 public:
187  const std::string &query,
188  const std::string &cname,
192  bool hold);
193 
195  const std::string &cname,
197 
198  ~sql_cursor() PQXX_NOEXCEPT { close(); }
199 
200  result fetch(difference_type rows, difference_type &displacement);
202  { difference_type d=0; return fetch(rows, d); }
203  difference_type move(difference_type rows, difference_type &displacement);
205  { difference_type d=0; return move(rows, d); }
206 
208 
214  difference_type pos() const PQXX_NOEXCEPT { return m_pos; }
215 
217 
223  difference_type endpos() const PQXX_NOEXCEPT { return m_endpos; }
224 
226  const result &empty_result() const PQXX_NOEXCEPT { return m_empty_result; }
227 
228  void close() PQXX_NOEXCEPT;
229 
230 private:
231  difference_type adjust(difference_type hoped, difference_type actual);
232  static std::string stridestring(difference_type);
234  void init_empty_result(transaction_base &);
235 
237  connection_base &m_home;
238 
240  result m_empty_result;
241 
242  result m_cached_current_row;
243 
245  bool m_adopted;
246 
248  cursor_base::ownershippolicy m_ownership;
249 
251  int m_at_end;
252 
254  difference_type m_pos;
255 
257  difference_type m_endpos;
258 };
259 
260 
261 PQXX_LIBEXPORT result::size_type obtain_stateless_cursor_size(sql_cursor &);
262 PQXX_LIBEXPORT result stateless_cursor_retrieve(
263  sql_cursor &,
264  result::difference_type size,
265  result::difference_type begin_pos,
266  result::difference_type end_pos);
267 
268 } // namespace internal
269 
270 
272 
278 template<cursor_base::updatepolicy up, cursor_base::ownershippolicy op>
280 {
281 public:
284 
287  transaction_base &trans,
288  const std::string &query,
289  const std::string &cname,
290  bool hold) :
291  m_cur(trans, query, cname, cursor_base::random_access, up, op, hold)
292  {
293  }
294 
297  transaction_base &trans,
298  const std::string adopted_cursor) :
299  m_cur(trans, adopted_cursor, op)
300  {
301  // Put cursor in known position
302  m_cur.move(cursor_base::backward_all());
303  }
304 
305  void close() PQXX_NOEXCEPT { m_cur.close(); }
306 
308 
311  size_type size() { return internal::obtain_stateless_cursor_size(m_cur); }
312 
314 
325  result retrieve(difference_type begin_pos, difference_type end_pos)
326  {
328  m_cur,
329  result::difference_type(size()),
330  begin_pos,
331  end_pos);
332  }
333 
334  const std::string &name() const PQXX_NOEXCEPT { return m_cur.name(); }
335 
336 private:
337  internal::sql_cursor m_cur;
338 };
339 
340 
341 class icursor_iterator;
342 
343 
344 namespace internal
345 {
346 namespace gate
347 {
348 class icursor_iterator_icursorstream;
349 class icursorstream_icursor_iterator;
350 } // namespace internal::gate
351 } // namespace internal
352 
353 
355 
370 class PQXX_LIBEXPORT icursorstream
371 {
372 public:
375 
377 
389  const std::string &query,
390  const std::string &basename,
391  difference_type sstride=1); //[t81]
392 
394 
419  const field &cname,
420  difference_type sstride=1,
422 
423  operator bool() const PQXX_NOEXCEPT { return !m_done; }
424 
426 
432  icursorstream &get(result &res) { res = fetchblock(); return *this; } //[t81]
434 
440  icursorstream &operator>>(result &res) { return get(res); } //[t81]
441 
443 
447  icursorstream &ignore(std::streamsize n=1); //[t81]
448 
450 
453  void set_stride(difference_type stride); //[t81]
454  difference_type stride() const PQXX_NOEXCEPT { return m_stride; } //[t81]
455 
456 private:
457  result fetchblock();
458 
459  friend class internal::gate::icursorstream_icursor_iterator;
460  size_type forward(size_type n=1);
461  void insert_iterator(icursor_iterator *) PQXX_NOEXCEPT;
462  void remove_iterator(icursor_iterator *) const PQXX_NOEXCEPT;
463 
464  void service_iterators(difference_type);
465 
466  internal::sql_cursor m_cur;
467 
468  difference_type m_stride;
469  difference_type m_realpos, m_reqpos;
470 
471  mutable icursor_iterator *m_iterators;
472 
473  bool m_done;
474 };
475 
476 
478 
504 class PQXX_LIBEXPORT icursor_iterator :
505  public std::iterator<std::input_iterator_tag,
506  result,
508  const result *,
509  const result &>
510 {
511 public:
515 
516  icursor_iterator() PQXX_NOEXCEPT; //[t84]
517  explicit icursor_iterator(istream_type &) PQXX_NOEXCEPT; //[t84]
518  icursor_iterator(const icursor_iterator &) PQXX_NOEXCEPT; //[t84]
519  ~icursor_iterator() PQXX_NOEXCEPT;
520 
521  const result &operator*() const { refresh(); return m_here; } //[t84]
522  const result *operator->() const { refresh(); return &m_here; } //[t84]
523  icursor_iterator &operator++(); //[t84]
524  icursor_iterator operator++(int); //[t84]
525  icursor_iterator &operator+=(difference_type); //[t84]
526  icursor_iterator &operator=(const icursor_iterator &) PQXX_NOEXCEPT; //[t84]
527 
528  bool operator==(const icursor_iterator &rhs) const; //[t84]
529  bool operator!=(const icursor_iterator &rhs) const PQXX_NOEXCEPT //[t84]
530  { return !operator==(rhs); }
531  bool operator<(const icursor_iterator &rhs) const; //[t84]
532  bool operator>(const icursor_iterator &rhs) const //[t84]
533  { return rhs < *this; }
534  bool operator<=(const icursor_iterator &rhs) const //[t84]
535  { return !(*this > rhs); }
536  bool operator>=(const icursor_iterator &rhs) const //[t84]
537  { return !(*this < rhs); }
538 
539 private:
540  void refresh() const;
541 
542  friend class internal::gate::icursor_iterator_icursorstream;
543  difference_type pos() const PQXX_NOEXCEPT { return m_pos; }
544  void fill(const result &);
545 
546  icursorstream *m_stream;
547  result m_here;
548  difference_type m_pos;
549  icursor_iterator *m_prev, *m_next;
550 };
551 
552 
553 } // namespace pqxx
554 
555 #include "pqxx/compiler-internal-post.hxx"
556 
557 #endif
558 
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:149
void close() PQXX_NOEXCEPT
Definition: cursor.hxx:305
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:504
updatepolicy
Cursor update policy.
Definition: cursor.hxx:71
stateless_cursor(transaction_base &trans, const std::string adopted_cursor)
Adopt existing scrolling SQL cursor.
Definition: cursor.hxx:296
unsigned long size_type
Definition: result.hxx:85
bool operator<=(const icursor_iterator &rhs) const
Definition: cursor.hxx:534
Cursor can be used to read data but not to write.
Definition: cursor.hxx:74
cursor_base::size_type size_type
Definition: cursor.hxx:373
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:325
difference_type endpos() const PQXX_NOEXCEPT
End position, or -1 for unknown.
Definition: cursor.hxx:223
accesspolicy
Cursor access-pattern policy.
Definition: cursor.hxx:59
Reference to a field in a result set.
Definition: field.hxx:51
result fetch(difference_type rows)
Definition: cursor.hxx:201
result::size_type size_type
Definition: cursor.hxx:52
bool operator>(const icursor_iterator &rhs) const
Definition: cursor.hxx:532
difference_type pos() const PQXX_NOEXCEPT
Current position, or -1 for unknown.
Definition: cursor.hxx:214
const result & empty_result() const PQXX_NOEXCEPT
Return zero-row result for this cursor.
Definition: cursor.hxx:226
difference_type move(difference_type rows)
Definition: cursor.hxx:204
ownershippolicy
Cursor destruction policy.
Definition: cursor.hxx:98
istream_type::difference_type difference_type
Definition: cursor.hxx:514
signed long difference_type
Definition: result.hxx:86
difference_type stride() const PQXX_NOEXCEPT
Definition: cursor.hxx:454
result::size_type size_type
Definition: cursor.hxx:282
Cursor with SQL positioning semantics.
Definition: cursor.hxx:183
result::difference_type difference_type
Definition: cursor.hxx:53
Cursor can move forward only.
Definition: cursor.hxx:62
~sql_cursor() PQXX_NOEXCEPT
Definition: cursor.hxx:198
cursor_base::difference_type difference_type
Definition: cursor.hxx:374
size_type size()
Number of rows in cursor&#39;s result set.
Definition: cursor.hxx:311
const std::string m_name
Definition: cursor.hxx:143
bool operator>=(const icursor_iterator &rhs) const
Definition: cursor.hxx:536
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:101
const result * operator->() const
Definition: cursor.hxx:522
static difference_type backward_all() PQXX_NOEXCEPT
Special value: read backwards from current position back to origin.
Definition: cursor.hxx:160
result::size_type obtain_stateless_cursor_size(sql_cursor &)
Definition: cursor.cxx:278
result::difference_type difference_type
Definition: cursor.hxx:283
static difference_type all() PQXX_NOEXCEPT
Special value: read until end.
Definition: cursor.hxx:155
const std::string & name() const PQXX_NOEXCEPT
Definition: cursor.hxx:334
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:370
icursorstream istream_type
Definition: cursor.hxx:512
Common definitions for cursor types.
Definition: cursor.hxx:49
result stateless_cursor_retrieve(sql_cursor &, result::difference_type size, result::difference_type begin_pos, result::difference_type end_pos)
Definition: cursor.cxx:285
Result set containing data returned by a query or command.
Definition: result.hxx:78
stateless_cursor(transaction_base &trans, const std::string &query, const std::string &cname, bool hold)
Create cursor.
Definition: cursor.hxx:286
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result &amp;)
Definition: cursor.hxx:440
static difference_type prior() PQXX_NOEXCEPT
Special value: read backwards, one row only.
Definition: cursor.hxx:122
&quot;Stateless cursor&quot; class: easy API for retrieving parts of result sets
Definition: cursor.hxx:279
Definition: transaction_base.hxx:133
istream_type::size_type size_type
Definition: cursor.hxx:513