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
23namespace pqxx
24{
26
37class PQXX_LIBEXPORT cursor_base
38{
39public:
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
131protected:
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
142namespace pqxx
143{
145
151template<cursor_base::update_policy up, cursor_base::ownership_policy op>
153{
154public:
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
228private:
229 internal::sql_cursor m_cur;
230};
231
232
233class icursor_iterator;
234} // namespace pqxx
235
236
237namespace pqxx::internal::gate
238{
239class icursor_iterator_icursorstream;
240class icursorstream_icursor_iterator;
241} // namespace pqxx::internal::gate
242
243
244namespace pqxx
245{
247
262class PQXX_LIBEXPORT icursorstream
263{
264public:
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
357private:
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
405class PQXX_LIBEXPORT icursor_iterator
406{
407public:
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
455private:
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
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:23
int result_difference_type
Difference between result sizes.
Definition: types.hxx:27
int result_size_type
Number of rows in a result set.
Definition: types.hxx:24
Definition: connection.hxx:95
Connection to a database.
Definition: connection.hxx:181
Common definitions for cursor types.
Definition: cursor.hxx:38
static difference_type backward_all() noexcept
Special value: read backwards from current position back to origin.
Definition: cursor.cxx:32
static difference_type prior() noexcept
Special value: read backwards, one row only.
Definition: cursor.hxx:114
cursor_base & operator=(cursor_base const &)=delete
result_size_type size_type
Definition: cursor.hxx:40
cursor_base(cursor_base const &)=delete
cursor_base()=delete
access_policy
Cursor access-pattern policy.
Definition: cursor.hxx:48
@ forward_only
Cursor can move forward only.
Definition: cursor.hxx:50
ownership_policy
Cursor destruction policy.
Definition: cursor.hxx:84
@ owned
Destroy SQL cursor when cursor object is closed at end of transaction.
Definition: cursor.hxx:86
update_policy
Cursor update policy.
Definition: cursor.hxx:60
@ read_only
Cursor can be used to read data but not to write.
Definition: cursor.hxx:62
result_difference_type difference_type
Definition: cursor.hxx:41
std::string const m_name
Definition: cursor.hxx:134
"Stateless cursor" class: easy API for retrieving parts of result sets
Definition: cursor.hxx:153
void close() noexcept
Close this cursor.
Definition: cursor.hxx:193
std::string const & name() const noexcept
Return this cursor's name.
Definition: cursor.hxx:223
result_size_type size_type
Definition: cursor.hxx:155
result_difference_type difference_type
Definition: cursor.hxx:156
result retrieve(difference_type begin_pos, difference_type end_pos)
Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
Definition: cursor.hxx:216
stateless_cursor(transaction_base &tx, std::string_view query, std::string_view cname, bool hold)
Create cursor.
Definition: cursor.hxx:167
size_type size()
Number of rows in cursor's result set.
Definition: cursor.hxx:199
stateless_cursor(transaction_base &tx, std::string_view adopted_cursor)
Adopt an existing scrolling SQL cursor.
Definition: cursor.hxx:180
Simple read-only cursor represented as a stream of results.
Definition: cursor.hxx:263
cursor_base::size_type size_type
Definition: cursor.hxx:265
icursorstream & get(result &res)
Read new value into given result object; same as operator >>.
Definition: cursor.hxx:325
difference_type stride() const noexcept
Definition: cursor.hxx:355
cursor_base::difference_type difference_type
Definition: cursor.hxx:266
icursorstream & operator>>(result &res)
Read new value into given result object; same as get(result&).
Definition: cursor.hxx:339
Approximate istream_iterator for icursorstream.
Definition: cursor.hxx:406
bool operator!=(icursor_iterator const &rhs) const noexcept
Definition: cursor.hxx:437
result const * operator->() const
Definition: cursor.hxx:426
result const * pointer
Definition: cursor.hxx:410
bool operator>=(icursor_iterator const &rhs) const
Definition: cursor.hxx:450
bool operator>(icursor_iterator const &rhs) const
Definition: cursor.hxx:442
result const & reference
Definition: cursor.hxx:411
istream_type::difference_type difference_type
Definition: cursor.hxx:414
std::input_iterator_tag iterator_category
Definition: cursor.hxx:408
bool operator<=(icursor_iterator const &rhs) const
Definition: cursor.hxx:446
istream_type::size_type size_type
Definition: cursor.hxx:413
Reference to a field in a result set.
Definition: field.hxx:31
Result set containing data returned by a query or command.
Definition: result.hxx:68
result_difference_type difference_type
Definition: result.hxx:71
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:73