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 typedef result::difference_type difference_type;
00041
00042 operator void *() const { return m_done ? 0 : &s_dummy; }
00043 bool operator!() const { return m_done; }
00044
00045 static difference_type all() throw ();
00046 static difference_type next() throw () { return 1; }
00047 static difference_type prior() throw () { return -1; }
00048 static difference_type backward_all() throw ();
00049
00050 const PGSTD::string &name() const throw () { return m_name; }
00051
00052 protected:
00053 cursor_base(transaction_base *context, const PGSTD::string &cname) :
00054 m_context(context), m_done(false), m_name(cname)
00055 {
00056 m_name += "_";
00057 m_name += to_string(get_unique_cursor_num());
00058 }
00059
00060 transaction_base *m_context;
00061 bool m_done;
00062
00063 private:
00064 int get_unique_cursor_num();
00065
00066 PGSTD::string m_name;
00067
00069 static unsigned char s_dummy;
00070
00072 cursor_base();
00074 cursor_base(const cursor_base &);
00076 cursor_base &operator=(const cursor_base &);
00077 };
00078
00079
00080 inline cursor_base::difference_type cursor_base::all() throw ()
00081 {
00082 #ifdef _MSC_VER
00083
00084 return INT_MAX;
00085 #else
00086 return PGSTD::numeric_limits<difference_type>::max();
00087 #endif
00088 }
00089
00090 inline cursor_base::difference_type cursor_base::backward_all() throw ()
00091 {
00092 #ifdef _MSC_VER
00093
00094 return INT_MIN + 1;
00095 #else
00096 return PGSTD::numeric_limits<difference_type>::min() + 1;
00097 #endif
00098 }
00099
00101
00109 class PQXX_LIBEXPORT icursorstream : public cursor_base
00110 {
00111 public:
00113
00124 icursorstream(transaction_base &context,
00125 const PGSTD::string &query,
00126 const PGSTD::string &basename,
00127 difference_type stride=1);
00128
00130
00134 icursorstream &get(result &res) { res = fetch(); return *this; }
00136
00140 icursorstream &operator>>(result &res) { return get(res); }
00142 icursorstream &ignore(PGSTD::streamsize n=1);
00143
00145
00148 void set_stride(difference_type stride);
00149
00150 private:
00151 void declare(const PGSTD::string &query);
00152 result fetch();
00153
00154 difference_type m_stride;
00155 };
00156
00157
00159
00176 class PQXX_LIBEXPORT icursor_iterator :
00177 public PGSTD::iterator<PGSTD::input_iterator_tag,
00178 result,
00179 cursor_base::size_type,
00180 const result *,
00181 const result &>
00182 {
00183 public:
00184 typedef icursorstream istream_type;
00185 typedef istream_type::size_type size_type;
00186 typedef istream_type::difference_type difference_type;
00187
00188 icursor_iterator() throw () :
00189 m_stream(0), m_here(), m_fresh(true), m_pos(0) {}
00190 icursor_iterator(istream_type &s) throw () :
00191 m_stream(&s), m_here(), m_fresh(false), m_pos(0) {}
00192 icursor_iterator(const icursor_iterator &rhs) throw () :
00193 m_stream(rhs.m_stream),
00194 m_here(rhs.m_here),
00195 m_fresh(rhs.m_fresh),
00196 m_pos(rhs.m_pos)
00197 {}
00198
00199 const result &operator*() const { refresh(); return m_here; }
00200 const result *operator->() const { refresh(); return &m_here; }
00201
00202 icursor_iterator &operator++() { read(); return *this; }
00203
00204 icursor_iterator operator++(int)
00205 { icursor_iterator old(*this); read(); return old; }
00206
00207 icursor_iterator &operator+=(difference_type n)
00208 {
00209 m_stream->ignore(n);
00210 m_fresh = false;
00211 m_pos += n;
00212 return *this;
00213 }
00214
00215 icursor_iterator &operator=(const icursor_iterator &rhs) throw ()
00216 {
00217 m_here = rhs.m_here;
00218 m_stream = rhs.m_stream;
00219 m_fresh = rhs.m_fresh;
00220 m_pos = rhs.m_pos;
00221 return *this;
00222 }
00223
00224 bool operator==(const icursor_iterator &rhs) const throw ()
00225 {
00226 return (m_stream==rhs.m_stream && m_pos==rhs.m_pos) ||
00227 (m_here.empty() && rhs.m_here.empty());
00228 }
00229 bool operator!=(const icursor_iterator &rhs) const throw ()
00230 { return !operator==(rhs); }
00231
00232 private:
00233 void read() const
00234 {
00235 m_stream->get(m_here);
00236 m_fresh = true;
00237 ++m_pos;
00238 }
00239 void refresh() const { if (!m_fresh) read(); }
00240 icursorstream *m_stream;
00241 mutable result m_here;
00242 mutable bool m_fresh;
00243 mutable result::size_type m_pos;
00244 };
00245
00246
00247 }
00248