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
00175 class PQXX_LIBEXPORT icursor_iterator :
00176
public PGSTD::iterator<PGSTD::input_iterator_tag,
00177 result,
00178 cursor_base::size_type,
00179 const result *,
00180 const result &>
00181 {
00182
public:
00183 typedef icursorstream
istream_type;
00184 typedef istream_type::size_type
size_type;
00185
00186 icursor_iterator() : m_stream(0), m_here(), m_fresh(true), m_pos(0){}
00187 icursor_iterator(
istream_type &s) :
00188 m_stream(&s), m_here(), m_fresh(false), m_pos(0) {}
00189 icursor_iterator(
const icursor_iterator &rhs) :
00190 m_stream(rhs.m_stream),
00191 m_here(rhs.m_here),
00192 m_fresh(rhs.m_fresh),
00193 m_pos(rhs.m_pos)
00194 {}
00195
00196 const result &operator*()
const { refresh();
return m_here; }
00197 const result *operator->()
const { refresh();
return &m_here; }
00198
00199 icursor_iterator &operator++() { read();
return *
this; }
00200
00201 icursor_iterator operator++(
int)
00202 { icursor_iterator old(*
this); read();
return old; }
00203
00204 icursor_iterator &operator+=(
size_type n)
00205 {
00206 m_stream->ignore(n);
00207 m_fresh =
false;
00208 m_pos += n;
00209
return *
this;
00210 }
00211
00212 icursor_iterator &operator=(
const icursor_iterator &rhs)
00213 {
00214 m_here = rhs.
m_here;
00215 m_stream = rhs.
m_stream;
00216 m_fresh = rhs.
m_fresh;
00217 m_pos = rhs.
m_pos;
00218
return *
this;
00219 }
00220
00221 bool operator==(
const icursor_iterator &rhs)
const throw ()
00222 {
00223
return (m_stream==rhs.m_stream && m_pos==rhs.m_pos) ||
00224 (m_here.empty() && rhs.m_here.empty());
00225 }
00226 bool operator!=(
const icursor_iterator &rhs)
const throw ()
00227 {
return !operator==(rhs); }
00228
00229
private:
00230
void read()
const
00231
{
00232 m_stream->get(m_here);
00233 m_fresh =
true;
00234 ++m_pos;
00235 }
00236
void refresh()
const {
if (!m_fresh) read(); }
00237 icursorstream *m_stream;
00238
mutable result m_here;
00239
mutable bool m_fresh;
00240
mutable result::size_type m_pos;
00241 };
00242
00243
00244 }
00245