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 
00036 class PQXX_LIBEXPORT cursor_base
00037 {
00038 
public:
00039   typedef result::size_type 
size_type;
00040 
00041   operator void *()
 const { 
return m_done ? 0 : &s_dummy; }             
00042   bool operator!()
 const { 
return m_done; }                             
00043 
00044   
static size_type all() throw ();                                      
00045   static 
size_type next() throw () { 
return 1; }                        
00046   static size_type prior() throw () { 
return -1; }                      
00047   
static size_type backward_all() throw ();                             
00048 
00049   const PGSTD::string &name() const throw () { 
return m_name; }         
00050 
00051 
protected:
00052   cursor_base(
transaction_base *context, 
const PGSTD::string &cname) :
00053         m_context(context), m_done(false), m_name(cname)
00054   {
00055     m_name += 
"_";
00056     m_name += 
to_string(get_unique_cursor_num());
00057   }
00058 
00059   transaction_base *m_context;
00060   bool m_done;
00061 
00062 
private:
00063   
int get_unique_cursor_num();
00064 
00065   PGSTD::string m_name;
00066 
00068   
static unsigned char s_dummy;
00069 
00071   cursor_base();
00073   cursor_base(
const cursor_base &);
00075   cursor_base &operator=(
const cursor_base &);
00076 };
00077 
00078 
00079 inline cursor_base::size_type cursor_base::all() throw ()
00080 {
00081 
#ifdef _MSC_VER
00082 
  
00083   
return INT_MAX;
00084 
#else
00085 
  return PGSTD::numeric_limits<size_type>::max();
00086 
#endif
00087 
}
00088 
00089 inline cursor_base::size_type cursor_base::backward_all() throw ()
00090 {
00091 
#ifdef _MSC_VER
00092 
  
00093   
return INT_MIN + 1;
00094 
#else
00095 
  return PGSTD::numeric_limits<size_type>::min() + 1;
00096 
#endif
00097 
}
00098 
00100 
00108 class PQXX_LIBEXPORT icursorstream : 
public cursor_base
00109 {
00110 
public:
00112 
00123   icursorstream(
transaction_base &context,
00124       
const PGSTD::string &query,
00125       
const PGSTD::string &basename,
00126       size_type stride=1);                                              
00127 
00129 
00133   icursorstream &get(
result &res) { res = fetch(); 
return *
this; }      
00135 
00139   icursorstream &operator>>(
result &res) { 
return get(res); }           
00141   icursorstream &ignore(PGSTD::streamsize n=1);                         
00142 
00144 
00147   
void set_stride(size_type stride);                                    
00148 
00149 
private:
00150   
void declare(
const PGSTD::string &query);
00151   
result fetch();
00152 
00153   size_type m_stride;
00154 };
00155 
00156 
00158 
00175 class PQXX_LIBEXPORT icursor_iterator : 
00176   
public PGSTD::iterator<PGSTD::input_iterator_tag, 
00177         result,
00178         cursor_base::size_type,
00179         const result *,
00180         const result &>
00181 {
00182 
public:
00183   typedef icursorstream 
istream_type;
00184   typedef istream_type::size_type 
size_type;
00185 
00186   icursor_iterator() : m_stream(0), m_here(), m_fresh(true), m_pos(0){} 
00187   icursor_iterator(
istream_type &s) :                                   
00188     m_stream(&s), m_here(), m_fresh(false), m_pos(0) {}
00189   icursor_iterator(
const icursor_iterator &rhs) :                       
00190     m_stream(rhs.m_stream),
00191     m_here(rhs.m_here),
00192     m_fresh(rhs.m_fresh),
00193     m_pos(rhs.m_pos)
00194   {}
00195 
00196   const result &operator*()
 const { refresh(); 
return m_here; }         
00197   const result *operator->()
 const { refresh(); 
return &m_here; }       
00198 
00199   icursor_iterator &operator++() { read(); 
return *
this; }              
00200 
00201   icursor_iterator operator++(
int)                                      
00202         { icursor_iterator old(*
this); read(); 
return old; }
00203 
00204   icursor_iterator &operator+=(
size_type n)                             
00205   {
00206     m_stream->ignore(n);
00207     m_fresh = 
false;
00208     m_pos += n;
00209     
return *
this;
00210   }
00211 
00212   icursor_iterator &operator=(
const icursor_iterator &rhs)              
00213   {
00214     m_here = rhs.
m_here;        
00215     m_stream = rhs.
m_stream;    
00216     m_fresh = rhs.
m_fresh;
00217     m_pos = rhs.
m_pos;
00218     
return *
this;
00219   }
00220 
00221   bool operator==(
const icursor_iterator &rhs) 
const throw ()           
00222   {
00223     
return (m_stream==rhs.m_stream && m_pos==rhs.m_pos) ||
00224       (m_here.empty() && rhs.m_here.empty());
00225   }
00226   bool operator!=(
const icursor_iterator &rhs) 
const throw ()           
00227         { 
return !operator==(rhs); }
00228 
00229 
private:
00230   
void read()
 const
00231 
  {
00232     m_stream->get(m_here);
00233     m_fresh = 
true;
00234     ++m_pos;
00235   }
00236   
void refresh()
 const { 
if (!m_fresh) read(); }
00237   icursorstream *m_stream;
00238   
mutable result m_here;
00239   
mutable bool m_fresh;
00240   
mutable result::size_type m_pos;
00241 };
00242 
00243 
00244 } 
00245