Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

cursor.hxx

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/cursor.hxx
00005  *
00006  *   DESCRIPTION
00007  *      definition of the iterator/container-style cursor classes
00008  *   C++-style wrappers for SQL cursors
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead.
00010  *
00011  * Copyright (c) 2004, Jeroen T. Vermeulen <jtv@xs4all.nl>
00012  *
00013  * See COPYING for copyright license.  If you did not receive a file called
00014  * COPYING with this source code, please notify the distributor of this mistake,
00015  * or contact the author.
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; }             //[t81]
00043   bool operator!() const { return m_done; }                             //[t81]
00044 
00045   static difference_type all() throw ();                                //[t81]
00046   static difference_type next() throw () { return 1; }                  //[t81]
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; }         //[t81]
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   // Microsoft's compiler defines max() and min() macros!  Others may as well
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   // Microsoft's compiler defines max() and min() macros!  Others may as well
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);                                        //[t81]
00128 
00130 
00134   icursorstream &get(result &res) { res = fetch(); return *this; }      //[t81]
00136 
00140   icursorstream &operator>>(result &res) { return get(res); }           //[t81]
00142   icursorstream &ignore(PGSTD::streamsize n=1);                         //[t81]
00143 
00145 
00148   void set_stride(difference_type stride);                              //[t81]
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;        // (Already protected against self-assignment)
00218     m_stream = rhs.m_stream;    // (Does not throw, so we're exception-safe)
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 } // namespace pqxx
00248 

Generated on Thu Oct 14 20:43:28 2004 for libpqxx by  doxygen 1.3.9