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-2005, 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 #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; }             //[t81]
00043 
00046   bool operator!() const { return m_done; }                             //[t81]
00047 
00049 
00052   static difference_type all() throw ();                                //[t81]
00054 
00056   static difference_type next() throw () { return 1; }                  //[t81]
00058 
00060   static difference_type prior() throw () { return -1; }                //[t0]
00062 
00064   static difference_type backward_all() throw ();                       //[t0]
00065 
00067 
00072   const PGSTD::string &name() const throw () { return m_name; }         //[t81]
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   // Microsoft Visual C++ sabotages numeric limits by defining min() and max()
00103   // as preprocessor macros; some other compilers just don't have numeric_limits
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);                                        //[t81]
00149 
00151 
00173   icursorstream(transaction_base &Context,
00174       const result::field &Name,
00175       difference_type Stride=1);                                        //[t84]
00176 
00178 
00184   icursorstream &get(result &res) { res = fetch(); return *this; }      //[t81]
00186 
00192   icursorstream &operator>>(result &res) { return get(res); }           //[t81]
00194 
00198   icursorstream &ignore(PGSTD::streamsize n=1);                         //[t81]
00199 
00201 
00204   void set_stride(difference_type stride);                              //[t81]
00205   difference_type stride() const throw () { return m_stride; }          //[t81]
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 ();                                          //[t84]
00261   explicit icursor_iterator(istream_type &) throw ();                   //[t84]
00262   icursor_iterator(const icursor_iterator &) throw ();                  //[t84]
00263   ~icursor_iterator() throw ();
00264 
00265   const result &operator*() const { refresh(); return m_here; }         //[t84]
00266   const result *operator->() const { refresh(); return &m_here; }       //[t84]
00267   icursor_iterator &operator++();                                       //[t84]
00268   icursor_iterator operator++(int);                                     //[t84]
00269   icursor_iterator &operator+=(difference_type);                        //[t84]
00270   icursor_iterator &operator=(const icursor_iterator &) throw ();       //[t84]
00271 
00272   bool operator==(const icursor_iterator &rhs) const;                   //[t84]
00273   bool operator!=(const icursor_iterator &rhs) const throw ()           //[t84]
00274         { return !operator==(rhs); }
00275   bool operator<(const icursor_iterator &rhs) const;                    //[t84]
00276   bool operator>(const icursor_iterator &rhs) const                     //[t84]
00277         { return rhs < *this; }
00278   bool operator<=(const icursor_iterator &rhs) const                    //[t84]
00279         { return !(*this > rhs); }
00280   bool operator>=(const icursor_iterator &rhs) const                    //[t84]
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 } // namespace pqxx
00298 

Generated on Fri Jul 1 14:36:19 2005 for libpqxx by  doxygen 1.4.2