00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "pqxx/libcompiler.h"
00020
00021
#include <limits>
00022
#include <string>
00023
00024
#include "pqxx/result"
00025
00026
00027
namespace pqxx
00028 {
00029
class transaction_base;
00030
00032
00036 class PQXX_LIBEXPORT cursor_base
00037 {
00038
public:
00039 typedef result::size_type
size_type;
00040
00041 operator void *()
const {
return m_done ? 0 : &s_dummy; }
00042 bool operator!()
const {
return m_done; }
00043
00044
static size_type all() throw ();
00045 static size_type next() throw () {
return 1; }
00046 static size_type prior() throw () {
return -1; }
00047
static size_type backward_all() throw ();
00048
00049 const PGSTD::string &name() const throw () {
return m_name; }
00050
00051
protected:
00052 cursor_base(
transaction_base *context,
const PGSTD::string &cname) :
00053 m_context(context), m_done(false), m_name(cname)
00054 {
00055 m_name +=
"_";
00056 m_name +=
to_string(get_unique_cursor_num());
00057 }
00058
00059 transaction_base *m_context;
00060 bool m_done;
00061
00062
private:
00063
int get_unique_cursor_num();
00064
00065 PGSTD::string m_name;
00066
00068
static unsigned char s_dummy;
00069
00071 cursor_base();
00073 cursor_base(
const cursor_base &);
00075 cursor_base &operator=(
const cursor_base &);
00076 };
00077
00078
00079 inline cursor_base::size_type cursor_base::all() throw ()
00080 {
00081
#ifdef _MSC_VER
00082
00083
return INT_MAX;
00084
#else
00085
return PGSTD::numeric_limits<size_type>::max();
00086
#endif
00087
}
00088
00089 inline cursor_base::size_type cursor_base::backward_all() throw ()
00090 {
00091
#ifdef _MSC_VER
00092
00093
return INT_MIN + 1;
00094
#else
00095
return PGSTD::numeric_limits<size_type>::min() + 1;
00096
#endif
00097
}
00098
00100
00108 class PQXX_LIBEXPORT icursorstream :
public cursor_base
00109 {
00110
public:
00112
00123 icursorstream(
transaction_base &context,
00124
const PGSTD::string &query,
00125
const PGSTD::string &basename,
00126 size_type stride=1);
00127
00129
00133 icursorstream &get(
result &res) { res = fetch();
return *
this; }
00135
00139 icursorstream &operator>>(
result &res) {
return get(res); }
00141 icursorstream &ignore(PGSTD::streamsize n=1);
00142
00144
00147
void set_stride(size_type stride);
00148
00149
private:
00150
void declare(
const PGSTD::string &query);
00151
result fetch();
00152
00153 size_type m_stride;
00154 };
00155
00156
00158
00174 class PQXX_LIBEXPORT icursor_iterator :
00175
public PGSTD::iterator<PGSTD::input_iterator_tag,
00176 result,
00177 cursor_base::size_type,
00178 const result *,
00179 const result &>
00180 {
00181
public:
00182 typedef icursorstream
istream_type;
00183 typedef istream_type::size_type
size_type;
00184
00185 icursor_iterator() : m_stream(0), m_here(), m_fresh(true) {}
00186 icursor_iterator(
istream_type &s) :
00187 m_stream(&s), m_here(), m_fresh(false) {}
00188 icursor_iterator(
const icursor_iterator &rhs) :
00189 m_stream(rhs.m_stream), m_here(rhs.m_here), m_fresh(rhs.m_fresh) {}
00190
00191 const result &operator*()
const { refresh();
return m_here; }
00192 const result *operator->()
const { refresh();
return &m_here; }
00193
00194 icursor_iterator &operator++() { read();
return *
this; }
00195
00196 icursor_iterator operator++(
int)
00197 { icursor_iterator old(*
this); read();
return old; }
00198
00199 icursor_iterator &operator+=(size_type n)
00200 {
00201 m_stream->ignore(n);
00202 m_fresh =
false;
00203
return *
this;
00204 }
00205
00206 icursor_iterator &operator=(
const icursor_iterator &rhs)
00207 {
00208 m_here = rhs.
m_here;
00209 m_stream = rhs.
m_stream;
00210 m_fresh = rhs.
m_fresh;
00211
return *
this;
00212 }
00213
00214 bool operator==(
const icursor_iterator &rhs)
const throw ()
00215 {
return m_here.empty() && rhs.m_here.empty(); }
00216 bool operator!=(
const icursor_iterator &rhs)
const throw ()
00217 {
return !operator==(rhs); }
00218
00219
private:
00220
void read()
const
00221
{
00222 m_stream->get(m_here);
00223 m_fresh =
true;
00224 }
00225
void refresh()
const {
if (!m_fresh) read(); }
00226 icursorstream *m_stream;
00227
mutable result m_here;
00228
mutable bool m_fresh;
00229 };
00230
00231
00232 }
00233