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 class PQXX_LIBEXPORT cursor_base
00033 {
00034 public:
00035 typedef result::size_type size_type;
00036 typedef result::difference_type difference_type;
00037
00038 operator void *() const { return m_done ? 0 : &s_dummy; }
00039 bool operator!() const { return m_done; }
00040
00041 static difference_type all() throw ();
00042 static difference_type next() throw () { return 1; }
00043 static difference_type prior() throw () { return -1; }
00044 static difference_type backward_all() throw ();
00045
00046 const PGSTD::string &name() const throw () { return m_name; }
00047
00048 protected:
00049 cursor_base(transaction_base *,
00050 const PGSTD::string &cname,
00051 bool embellish_name = true);
00052
00053 transaction_base *m_context;
00054 bool m_done;
00055
00056 private:
00057 int get_unique_cursor_num();
00058
00059 PGSTD::string m_name;
00060
00062 static unsigned char s_dummy;
00063
00065 cursor_base();
00067 cursor_base(const cursor_base &);
00069 cursor_base &operator=(const cursor_base &);
00070 };
00071
00072
00073 inline cursor_base::difference_type cursor_base::all() throw ()
00074 {
00075 #ifdef _MSC_VER
00076
00077 return INT_MAX;
00078 #else
00079 return PGSTD::numeric_limits<difference_type>::max();
00080 #endif
00081 }
00082
00083 inline cursor_base::difference_type cursor_base::backward_all() throw ()
00084 {
00085 #ifdef _MSC_VER
00086
00087 return INT_MIN + 1;
00088 #else
00089 return PGSTD::numeric_limits<difference_type>::min() + 1;
00090 #endif
00091 }
00092
00093 class icursor_iterator;
00094
00096
00103 class PQXX_LIBEXPORT icursorstream : public cursor_base
00104 {
00105 public:
00107
00118 icursorstream(transaction_base &Context,
00119 const PGSTD::string &Query,
00120 const PGSTD::string &Basename,
00121 difference_type Stride=1);
00122
00124
00146 icursorstream(transaction_base &Context,
00147 const result::field &Name,
00148 difference_type Stride=1);
00149
00151
00155 icursorstream &get(result &res) { res = fetch(); return *this; }
00157
00161 icursorstream &operator>>(result &res) { return get(res); }
00163 icursorstream &ignore(PGSTD::streamsize n=1);
00164
00166
00169 void set_stride(difference_type stride);
00170 difference_type stride() const throw () { return m_stride; }
00171
00172 private:
00173 void declare(const PGSTD::string &query);
00174 result fetch();
00175
00176 friend class icursor_iterator;
00177 size_type forward(size_type n=1);
00178 void insert_iterator(icursor_iterator *) throw ();
00179 void remove_iterator(icursor_iterator *) const throw ();
00180
00181 void service_iterators(size_type);
00182
00183 difference_type m_stride;
00184 size_type m_realpos, m_reqpos;
00185
00186 mutable icursor_iterator *m_iterators;
00187 };
00188
00189
00191
00213 class PQXX_LIBEXPORT icursor_iterator :
00214 public PGSTD::iterator<PGSTD::input_iterator_tag,
00215 result,
00216 cursor_base::size_type,
00217 const result *,
00218 const result &>
00219 {
00220 public:
00221 typedef icursorstream istream_type;
00222 typedef istream_type::size_type size_type;
00223 typedef istream_type::difference_type difference_type;
00224
00225 icursor_iterator() throw ();
00226 explicit icursor_iterator(istream_type &) throw ();
00227 icursor_iterator(const icursor_iterator &) throw ();
00228 ~icursor_iterator() throw ();
00229
00230 const result &operator*() const { refresh(); return m_here; }
00231 const result *operator->() const { refresh(); return &m_here; }
00232 icursor_iterator &operator++();
00233 icursor_iterator operator++(int);
00234 icursor_iterator &operator+=(difference_type);
00235 icursor_iterator &operator=(const icursor_iterator &) throw ();
00236
00237 bool operator==(const icursor_iterator &rhs) const;
00238 bool operator!=(const icursor_iterator &rhs) const throw ()
00239 { return !operator==(rhs); }
00240 bool operator<(const icursor_iterator &rhs) const;
00241 bool operator>(const icursor_iterator &rhs) const
00242 { return rhs < *this; }
00243 bool operator<=(const icursor_iterator &rhs) const
00244 { return !(*this > rhs); }
00245 bool operator>=(const icursor_iterator &rhs) const
00246 { return !(*this < rhs); }
00247
00248 private:
00249 void refresh() const;
00250
00251 friend class icursorstream;
00252 size_type pos() const throw () { return m_pos; }
00253 void fill(const result &) const;
00254
00255 icursorstream *m_stream;
00256 mutable result m_here;
00257 size_type m_pos;
00258 icursor_iterator *m_prev, *m_next;
00259 };
00260
00261
00262 }
00263