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 #ifdef PQXX_HAVE_LIMITS
00022 #include <limits>
00023 #endif
00024
00025 #include "pqxx/result"
00026
00027
00028 namespace pqxx
00029 {
00030 class transaction_base;
00031
00033 class PQXX_LIBEXPORT cursor_base
00034 {
00035 public:
00036 typedef result::size_type size_type;
00037 typedef result::difference_type difference_type;
00038
00040
00041 operator void *() const { return m_done ? 0 : &s_dummy; }
00043
00046 bool operator!() const { return m_done; }
00047
00049
00052 static difference_type all() throw ();
00054
00056 static difference_type next() throw () { return 1; }
00058
00060 static difference_type prior() throw () { return -1; }
00062
00064 static difference_type backward_all() throw ();
00065
00067
00072 const PGSTD::string &name() const throw () { return m_name; }
00073
00074 protected:
00075 cursor_base(transaction_base *,
00076 const PGSTD::string &cname,
00077 bool embellish_name = true);
00078
00079 static PGSTD::string stridestring(difference_type);
00080 transaction_base *m_context;
00081 bool m_done;
00082
00083 private:
00084 int PQXX_PRIVATE get_unique_cursor_num();
00085
00086 PGSTD::string m_name;
00087
00089 static unsigned char s_dummy;
00090
00092 cursor_base();
00094 cursor_base(const cursor_base &);
00096 cursor_base &operator=(const cursor_base &);
00097 };
00098
00099
00100 inline cursor_base::difference_type cursor_base::all() throw ()
00101 {
00102
00103
00104 #if defined(PQXX_HAVE_LIMITS) && !defined(_MSC_VER)
00105 return PGSTD::numeric_limits<difference_type>::max();
00106 #else
00107 return INT_MAX;
00108 #endif
00109 }
00110
00111 inline cursor_base::difference_type cursor_base::backward_all() throw ()
00112 {
00113 #if defined(PQXX_HAVE_LIMITS) && !defined(_MSC_VER)
00114 return PGSTD::numeric_limits<difference_type>::min() + 1;
00115 #else
00116 return INT_MIN + 1;
00117 #endif
00118 }
00119
00120 class icursor_iterator;
00121
00123
00130 class PQXX_LIBEXPORT icursorstream : public cursor_base
00131 {
00132 public:
00134
00145 icursorstream(transaction_base &Context,
00146 const PGSTD::string &Query,
00147 const PGSTD::string &Basename,
00148 difference_type Stride=1);
00149
00151
00173 icursorstream(transaction_base &Context,
00174 const result::field &Name,
00175 difference_type Stride=1);
00176
00178
00184 icursorstream &get(result &res) { res = fetch(); return *this; }
00186
00192 icursorstream &operator>>(result &res) { return get(res); }
00194
00198 icursorstream &ignore(PGSTD::streamsize n=1);
00199
00201
00204 void set_stride(difference_type stride);
00205 difference_type stride() const throw () { return m_stride; }
00206
00207 private:
00208 void declare(const PGSTD::string &query);
00209 result fetch();
00210
00211 friend class icursor_iterator;
00212 size_type forward(size_type n=1);
00213 void insert_iterator(icursor_iterator *) throw ();
00214 void remove_iterator(icursor_iterator *) const throw ();
00215
00216 void service_iterators(size_type);
00217
00218 difference_type m_stride;
00219 size_type m_realpos, m_reqpos;
00220
00221 mutable icursor_iterator *m_iterators;
00222 };
00223
00224
00226
00248 class PQXX_LIBEXPORT icursor_iterator :
00249 public PGSTD::iterator<PGSTD::input_iterator_tag,
00250 result,
00251 cursor_base::size_type,
00252 const result *,
00253 const result &>
00254 {
00255 public:
00256 typedef icursorstream istream_type;
00257 typedef istream_type::size_type size_type;
00258 typedef istream_type::difference_type difference_type;
00259
00260 icursor_iterator() throw ();
00261 explicit icursor_iterator(istream_type &) throw ();
00262 icursor_iterator(const icursor_iterator &) throw ();
00263 ~icursor_iterator() throw ();
00264
00265 const result &operator*() const { refresh(); return m_here; }
00266 const result *operator->() const { refresh(); return &m_here; }
00267 icursor_iterator &operator++();
00268 icursor_iterator operator++(int);
00269 icursor_iterator &operator+=(difference_type);
00270 icursor_iterator &operator=(const icursor_iterator &) throw ();
00271
00272 bool operator==(const icursor_iterator &rhs) const;
00273 bool operator!=(const icursor_iterator &rhs) const throw ()
00274 { return !operator==(rhs); }
00275 bool operator<(const icursor_iterator &rhs) const;
00276 bool operator>(const icursor_iterator &rhs) const
00277 { return rhs < *this; }
00278 bool operator<=(const icursor_iterator &rhs) const
00279 { return !(*this > rhs); }
00280 bool operator>=(const icursor_iterator &rhs) const
00281 { return !(*this < rhs); }
00282
00283 private:
00284 void refresh() const;
00285
00286 friend class icursorstream;
00287 size_type pos() const throw () { return m_pos; }
00288 void fill(const result &) const;
00289
00290 icursorstream *m_stream;
00291 mutable result m_here;
00292 size_type m_pos;
00293 icursor_iterator *m_prev, *m_next;
00294 };
00295
00296
00297 }
00298