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   transaction_base *m_context;
00080   bool m_done;
00081 
00082 private:
00083   int get_unique_cursor_num();
00084 
00085   PGSTD::string m_name;
00086 
00088   static unsigned char s_dummy;
00089 
00091   cursor_base();
00093   cursor_base(const cursor_base &);
00095   cursor_base &operator=(const cursor_base &);
00096 };
00097 
00098 
00099 inline cursor_base::difference_type cursor_base::all() throw ()
00100 {
00101   
00102   
00103 #if defined(PQXX_HAVE_LIMITS) && !defined(_MSC_VER)
00104   return PGSTD::numeric_limits<difference_type>::max();
00105 #else
00106   return INT_MAX;
00107 #endif
00108 }
00109 
00110 inline cursor_base::difference_type cursor_base::backward_all() throw ()
00111 {
00112 #if defined(PQXX_HAVE_LIMITS) && !defined(_MSC_VER)
00113   return PGSTD::numeric_limits<difference_type>::min() + 1;
00114 #else
00115   return INT_MIN + 1;
00116 #endif
00117 }
00118 
00119 class icursor_iterator;
00120 
00122 
00129 class PQXX_LIBEXPORT icursorstream : public cursor_base
00130 {
00131 public:
00133 
00144   icursorstream(transaction_base &Context,
00145       const PGSTD::string &Query,
00146       const PGSTD::string &Basename,
00147       difference_type Stride=1);                                        
00148 
00150 
00172   icursorstream(transaction_base &Context,
00173       const result::field &Name,
00174       difference_type Stride=1);                                        
00175 
00177 
00183   icursorstream &get(result &res) { res = fetch(); return *this; }      
00185 
00191   icursorstream &operator>>(result &res) { return get(res); }           
00193 
00197   icursorstream &ignore(PGSTD::streamsize n=1);                         
00198 
00200 
00203   void set_stride(difference_type stride);                              
00204   difference_type stride() const throw () { return m_stride; }          
00205 
00206 private:
00207   void declare(const PGSTD::string &query);
00208   result fetch();
00209 
00210   friend class icursor_iterator;
00211   size_type forward(size_type n=1);
00212   void insert_iterator(icursor_iterator *) throw ();
00213   void remove_iterator(icursor_iterator *) const throw ();
00214 
00215   void service_iterators(size_type);
00216 
00217   difference_type m_stride;
00218   size_type m_realpos, m_reqpos;
00219 
00220   mutable icursor_iterator *m_iterators;
00221 };
00222 
00223 
00225 
00247 class PQXX_LIBEXPORT icursor_iterator : 
00248   public PGSTD::iterator<PGSTD::input_iterator_tag, 
00249         result,
00250         cursor_base::size_type,
00251         const result *,
00252         const result &>
00253 {
00254 public:
00255   typedef icursorstream istream_type;
00256   typedef istream_type::size_type size_type;
00257   typedef istream_type::difference_type difference_type;
00258 
00259   icursor_iterator() throw ();                                          
00260   explicit icursor_iterator(istream_type &) throw ();                   
00261   icursor_iterator(const icursor_iterator &) throw ();                  
00262   ~icursor_iterator() throw ();
00263 
00264   const result &operator*() const { refresh(); return m_here; }         
00265   const result *operator->() const { refresh(); return &m_here; }       
00266   icursor_iterator &operator++();                                       
00267   icursor_iterator operator++(int);                                     
00268   icursor_iterator &operator+=(difference_type);                        
00269   icursor_iterator &operator=(const icursor_iterator &) throw ();       
00270 
00271   bool operator==(const icursor_iterator &rhs) const;                   
00272   bool operator!=(const icursor_iterator &rhs) const throw ()           
00273         { return !operator==(rhs); }
00274   bool operator<(const icursor_iterator &rhs) const;                    
00275   bool operator>(const icursor_iterator &rhs) const                     
00276         { return rhs < *this; }
00277   bool operator<=(const icursor_iterator &rhs) const                    
00278         { return !(*this > rhs); }
00279   bool operator>=(const icursor_iterator &rhs) const                    
00280         { return !(*this < rhs); }
00281 
00282 private:
00283   void refresh() const;
00284 
00285   friend class icursorstream;
00286   size_type pos() const throw () { return m_pos; }
00287   void fill(const result &) const;
00288 
00289   icursorstream *m_stream;
00290   mutable result m_here;
00291   size_type m_pos;
00292   icursor_iterator *m_prev, *m_next;
00293 };
00294 
00295 
00296 } 
00297