result.hxx

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/result.hxx
00005  *
00006  *   DESCRIPTION
00007  *      definitions for the pqxx::result class and support classes.
00008  *   pqxx::result represents the set of result tuples from a database query
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
00010  *
00011  * Copyright (c) 2001-2006, 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/compiler-public.hxx"
00020 #include "pqxx/compiler-internal-pre.hxx"
00021 
00022 #ifdef PQXX_HAVE_IOS
00023 #include <ios>
00024 #endif
00025 
00026 #include <stdexcept>
00027 
00028 #include "pqxx/util"
00029 
00030 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
00031  */
00032 
00033 // TODO: Support SQL arrays
00034 
00035 namespace pqxx
00036 {
00038 
00058 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::pq::PGresult>
00059 {
00060   typedef internal::PQAlloc<internal::pq::PGresult> super;
00061 public:
00062   class const_iterator;
00063   class const_fielditerator;
00064   class const_reverse_fielditerator;
00065   class tuple;
00066   class field;
00067   typedef unsigned long size_type;
00068   typedef signed long difference_type;
00069   typedef tuple reference;
00070   typedef const_iterator pointer;
00071 
00073 
00084   class PQXX_LIBEXPORT tuple
00085   {
00086   public:
00087     typedef unsigned int size_type;
00088     typedef signed int difference_type;
00089     typedef const_fielditerator const_iterator;
00090     typedef field reference;
00091     typedef const_fielditerator pointer;
00092     typedef const_reverse_fielditerator const_reverse_iterator;
00093 
00094     tuple(const result *r, result::size_type i) throw () :
00095       m_Home(r), m_Index(i) {}
00096     ~tuple() throw () {} // Yes Scott Meyers, you're absolutely right[1]
00097 
00102     bool operator==(const tuple &) const throw ();                      //[t75]
00103     bool operator!=(const tuple &rhs) const throw ()                    //[t75]
00104         { return !operator==(rhs); }
00106 
00107     const_iterator begin() const throw ()                               //[t82]
00108         { return const_iterator(*this, 0); }
00109     const_iterator end() const throw ()                                 //[t82]
00110         { return const_iterator(*this, size()); }
00111 
00116     reference front() const throw () { return field(*this, 0); }        //[t74]
00117     reference back() const throw () { return field(*this, size()-1); }  //[t75]
00118 
00119     const_reverse_fielditerator rbegin() const;                         //[t82]
00120     const_reverse_fielditerator rend() const;                           //[t82]
00121 
00122     reference operator[](size_type i) const throw ()                    //[t11]
00123         { return field(*this, i); }
00124     reference operator[](int i) const throw ()                          //[t2]
00125         { return operator[](size_type(i)); }
00126     reference operator[](const char[]) const;                           //[t11]
00127     reference operator[](const PGSTD::string &s) const                  //[t11]
00128         { return operator[](s.c_str()); }
00129     reference at(size_type) const throw (PGSTD::out_of_range);          //[t11]
00130     reference at(int i) const throw (PGSTD::out_of_range)               //[t11]
00131         { return at(size_type(i)); }
00132     reference at(const char[]) const;                                   //[t11]
00133     reference at(const PGSTD::string &s) const                          //[t11]
00134         { return at(s.c_str()); }
00136 
00137     size_type size() const throw () { return m_Home->columns(); }       //[t11]
00138 
00139     void swap(tuple &) throw ();                                        //[t11]
00140 
00141     result::size_type rownumber() const throw () { return m_Index; }    //[t11]
00142 
00147 
00148     size_type column_number(const PGSTD::string &ColName) const         //[t30]
00149         { return m_Home->column_number(ColName); }
00150 
00152     size_type column_number(const char ColName[]) const                 //[t30]
00153         { return m_Home->column_number(ColName); }
00154 
00156     oid column_type(size_type ColNum) const                             //[t7]
00157         { return m_Home->column_type(ColNum); }
00158 
00160     oid column_type(int ColNum) const                                   //[t7]
00161         { return column_type(size_type(ColNum)); }
00162 
00164     oid column_type(const PGSTD::string &ColName) const                 //[t7]
00165         { return column_type(column_number(ColName)); }
00166 
00168     oid column_type(const char ColName[]) const                         //[t7]
00169         { return column_type(column_number(ColName)); }
00170 
00172 
00179     oid column_table(size_type ColNum) const                            //[t2]
00180         { return m_Home->column_table(ColNum); }
00182 
00189     oid column_table(int ColNum) const                                  //[t2]
00190         { return column_table(size_type(ColNum)); }
00192 
00199     oid column_table(const PGSTD::string &ColName) const                //[t2]
00200         { return column_table(column_number(ColName)); }
00202 
00203     result::size_type num() const { return rownumber(); }               //[t1]
00204 
00205 
00206 #ifdef PQXX_DEPRECATED_HEADERS
00207 
00211 
00212     result::size_type Row() const PQXX_DEPRECATED { return rownumber(); }
00213 
00215     size_type ColumnNumber(const PGSTD::string &ColName) const PQXX_DEPRECATED
00216         { return column_number(ColName); }
00217 
00219     size_type ColumnNumber(const char ColName[]) const PQXX_DEPRECATED
00220         { return column_number(ColName); }
00222 #endif
00223 
00224   protected:
00225     friend class field;
00226     const result *m_Home;
00227     result::size_type m_Index;
00228 
00229     // Not allowed:
00230     tuple();
00231   };
00232 
00234 
00237   class PQXX_LIBEXPORT field
00238   {
00239   public:
00240     typedef size_t size_type;
00241 
00243 
00247     field(const tuple &T, tuple::size_type C) throw () :                //[t1]
00248         m_tup(T), m_col(C) {}
00249 
00254 
00255 
00271     bool operator==(const field &) const;                               //[t75]
00272 
00274 
00276     bool operator!=(const field &rhs) const {return !operator==(rhs);}  //[t82]
00278 
00283 
00284     const char *name() const { return home()->column_name(col()); }     //[t11]
00285 
00287     oid type() const { return home()->column_type(col()); }             //[t7]
00288 
00290 
00297     oid table() const { return home()->column_table(col()); }           //[t2]
00298 
00299     tuple::size_type num() const { return col(); }                      //[t82]
00301 
00306 
00307 
00312     const char *c_str() const { return home()->GetValue(idx(),col()); } //[t2]
00313 
00315     template<typename T> bool to(T &Obj) const                          //[t3]
00316     {
00317       if (is_null()) return false;
00318       try
00319       {
00320         from_string(c_str(), Obj);
00321       }
00322       catch (const PGSTD::exception &e)
00323       {
00324         throw PGSTD::domain_error("Error reading field " +
00325                                   PGSTD::string(name()) + ": " +
00326                                   e.what());
00327       }
00328       return true;
00329     }
00330 
00332     template<typename T> bool operator>>(T &Obj) const                  //[t7]
00333         { return to(Obj); }
00334 
00335 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00336 
00337     template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00338 
00340 
00343     template<> bool to<const char *>(const char *&Obj) const;
00344 #endif
00345 
00347     template<typename T> bool to(T &Obj, const T &Default) const        //[t12]
00348     {
00349       const bool NotNull = to(Obj);
00350       if (!NotNull) Obj = Default;
00351       return NotNull;
00352     }
00353 
00355 
00358     template<typename T> T as(const T &Default) const                   //[t1]
00359     {
00360       T Obj;
00361       to(Obj, Default);
00362       return Obj;
00363     }
00364 
00366     template<typename T> T as() const                                   //[t45]
00367     {
00368       T Obj;
00369       const bool NotNull = to(Obj);
00370       if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00371       return Obj;
00372     }
00373 
00374     bool is_null() const { return home()->GetIsNull(idx(), col()); }    //[t12]
00375     size_type size() const throw ()                                     //[t11]
00376         { return home()->GetLength(idx(),col()); }
00378 
00379 #ifdef PQXX_DEPRECATED_HEADERS
00380 
00381     const char *Name() const PQXX_DEPRECATED {return name();}
00382 #endif
00383 
00384   private:
00385     const result *home() const throw () { return m_tup.m_Home; }
00386     result::size_type idx() const throw () { return m_tup.m_Index; }
00387 
00388   protected:
00389     const tuple::size_type col() const throw () { return m_col; }
00390     tuple m_tup;
00391     tuple::size_type m_col;
00392   };
00393 
00394   typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00395                            const tuple,
00396                            result::difference_type,
00397                            const_iterator,
00398                            tuple> const_iterator_base;
00399 
00401 
00405   class PQXX_LIBEXPORT const_iterator :
00406     public const_iterator_base,
00407     public tuple
00408   {
00409   public:
00410     typedef const tuple *pointer;
00411     typedef tuple reference;
00412     typedef result::size_type size_type;
00413     typedef result::difference_type difference_type;
00414 
00415     const_iterator() throw () : tuple(0,0) {}
00416     const_iterator(const tuple &t) throw () : tuple(t) {}
00417 
00433     pointer operator->() const { return this; }                         //[t12]
00434     reference operator*() const { return tuple(*this); }                //[t12]
00436 
00441     const_iterator operator++(int);                                     //[t12]
00442     const_iterator &operator++() { ++m_Index; return *this; }           //[t1]
00443     const_iterator operator--(int);                                     //[t12]
00444     const_iterator &operator--() { --m_Index; return *this; }           //[t12]
00445 
00446     const_iterator &operator+=(difference_type i)                       //[t12]
00447         { m_Index+=i; return *this; }
00448     const_iterator &operator-=(difference_type i)                       //[t12]
00449         { m_Index-=i; return *this; }
00451 
00456     bool operator==(const const_iterator &i) const                      //[t12]
00457         {return m_Index==i.m_Index;}
00458     bool operator!=(const const_iterator &i) const                      //[t12]
00459         {return m_Index!=i.m_Index;}
00460     bool operator<(const const_iterator &i) const                       //[t12]
00461         {return m_Index<i.m_Index;}
00462     bool operator<=(const const_iterator &i) const                      //[t12]
00463         {return m_Index<=i.m_Index;}
00464     bool operator>(const const_iterator &i) const                       //[t12]
00465         {return m_Index>i.m_Index;}
00466     bool operator>=(const const_iterator &i) const                      //[t12]
00467         {return m_Index>=i.m_Index;}
00469 
00474     inline const_iterator operator+(difference_type) const;             //[t12]
00475     friend const_iterator
00476     operator+(difference_type, const_iterator);                         //[t12]
00477     inline const_iterator operator-(difference_type) const;             //[t12]
00478     inline difference_type operator-(const_iterator) const;             //[t12]
00480 
00481   private:
00482     friend class pqxx::result;
00483     const_iterator(const pqxx::result *r, result::size_type i) throw () :
00484         tuple(r, i) {}
00485   };
00486 
00487   class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00488   {
00489   public:
00490     typedef pqxx::result::const_iterator super;
00491     typedef pqxx::result::const_iterator iterator_type;
00492     using iterator_type::iterator_category;
00493     using iterator_type::difference_type;
00494     using iterator_type::pointer;
00495 #ifndef _MSC_VER
00496     using iterator_type::value_type;
00497     using iterator_type::reference;
00498 #else
00499     // Workaround for Visual C++.NET 2003, which has access problems
00500     typedef const tuple &reference;
00501     typedef tuple value_type;
00502 #endif
00503 
00504     const_reverse_iterator(const const_reverse_iterator &rhs) :         //[t75]
00505       const_iterator(rhs) {}
00506     explicit const_reverse_iterator(const const_iterator &rhs) :        //[t75]
00507       const_iterator(rhs) { super::operator--(); }
00508 
00509     iterator_type base() const throw ();                                //[t75]
00510 
00515     using const_iterator::operator->;                                   //[t75]
00516     using const_iterator::operator*;                                    //[t75]
00518  
00523     const_reverse_iterator &operator=(const const_reverse_iterator &r)  //[t75]
00524         { iterator_type::operator=(r); return *this; }
00525     const_reverse_iterator operator++()                                 //[t75]
00526         { iterator_type::operator--(); return *this; }
00527     const_reverse_iterator operator++(int);                             //[t75]
00528     const_reverse_iterator &operator--()                                //[t75]
00529         { iterator_type::operator++(); return *this; }
00530     const_reverse_iterator operator--(int);                             //[t75]
00531     const_reverse_iterator &operator+=(difference_type i)               //[t75]
00532         { iterator_type::operator-=(i); return *this; }
00533     const_reverse_iterator &operator-=(difference_type i)               //[t75]
00534         { iterator_type::operator+=(i); return *this; }
00536 
00541     const_reverse_iterator operator+(difference_type i) const           //[t75]
00542         { return const_reverse_iterator(base()-i); }
00543     const_reverse_iterator operator-(difference_type i)                 //[t75]
00544         { return const_reverse_iterator(base()+i); }
00545     difference_type operator-(const const_reverse_iterator &rhs) const  //[t75]
00546         { return rhs.const_iterator::operator-(*this); }
00548 
00553     bool operator==(const const_reverse_iterator &rhs) const throw ()   //[t75]
00554         { return iterator_type::operator==(rhs); }
00555     bool operator!=(const const_reverse_iterator &rhs) const throw ()   //[t75]
00556         { return !operator==(rhs); }
00557 
00558     bool operator<(const const_reverse_iterator &rhs) const             //[t75]
00559         { return iterator_type::operator>(rhs); }
00560     bool operator<=(const const_reverse_iterator &rhs) const            //[t75]
00561         { return iterator_type::operator>=(rhs); }
00562     bool operator>(const const_reverse_iterator &rhs) const             //[t75]
00563         { return iterator_type::operator<(rhs); }
00564     bool operator>=(const const_reverse_iterator &rhs) const            //[t75]
00565         { return iterator_type::operator<=(rhs); }
00567   };
00568 
00569   class PQXX_LIBEXPORT const_fielditerator :
00570     public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00571                            const field,
00572                            tuple::size_type>,
00573     public field
00574   {
00575     typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00576                                   const field,
00577                                   tuple::size_type> it;
00578   public:
00579     using it::pointer;
00580     typedef tuple::size_type size_type;
00581     typedef tuple::difference_type difference_type;
00582     typedef field reference;
00583 
00584     const_fielditerator(const tuple &T, tuple::size_type C) throw () :  //[t82]
00585       field(T, C) {}
00586     const_fielditerator(const field &F) throw () : field(F) {}          //[t82]
00587 
00592     pointer operator->() const { return this; }                         //[t82]
00593     reference operator*() const { return field(*this); }                //[t82]
00595 
00600     const_fielditerator operator++(int);                                //[t82]
00601     const_fielditerator &operator++() { ++m_col; return *this; }        //[t82]
00602     const_fielditerator operator--(int);                                //[t82]
00603     const_fielditerator &operator--() { --m_col; return *this; }        //[t82]
00604 
00605     const_fielditerator &operator+=(difference_type i)                  //[t82]
00606         { m_col+=i; return *this; }
00607     const_fielditerator &operator-=(difference_type i)                  //[t82]
00608         { m_col-=i; return *this; }
00610 
00615     bool operator==(const const_fielditerator &i) const                 //[t82]
00616         {return col()==i.col();}
00617     bool operator!=(const const_fielditerator &i) const                 //[t82]
00618         {return col()!=i.col();}
00619     bool operator<(const const_fielditerator &i) const                  //[t82]
00620         {return col()<i.col();}
00621     bool operator<=(const const_fielditerator &i) const                 //[t82]
00622         {return col()<=i.col();}
00623     bool operator>(const const_fielditerator &i) const                  //[t82]
00624         {return col()>i.col();}
00625     bool operator>=(const const_fielditerator &i) const                 //[t82]
00626         {return col()>=i.col();}
00628 
00633     inline const_fielditerator operator+(difference_type) const;        //[t82]
00634 
00635     friend const_fielditerator operator+(difference_type,
00636                                           const_fielditerator);         //[t82]
00637 
00638     inline const_fielditerator operator-(difference_type) const;        //[t82]
00639     inline difference_type operator-(const_fielditerator) const;        //[t82]
00641   };
00642 
00643   class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00644   {
00645   public:
00646     typedef const_fielditerator super;
00647     typedef const_fielditerator iterator_type;
00648     using iterator_type::iterator_category;
00649     using iterator_type::difference_type;
00650     using iterator_type::pointer;
00651 #ifndef _MSC_VER
00652     using iterator_type::value_type;
00653     using iterator_type::reference;
00654 #else
00655     // Workaround for Visual C++.NET 2003, which has access problems
00656     typedef field value_type;
00657     typedef const field &reference;
00658 #endif
00659 
00660     const_reverse_fielditerator(const const_reverse_fielditerator &r) : //[t82]
00661       const_fielditerator(r) {}
00662     explicit
00663       const_reverse_fielditerator(const super &rhs) throw() :           //[t82]
00664         const_fielditerator(rhs) { super::operator--(); }
00665 
00666     iterator_type base() const throw ();                                //[t82]
00667 
00672     using iterator_type::operator->;                                    //[t82]
00673     using iterator_type::operator*;                                     //[t82]
00675 
00680     const_reverse_fielditerator &
00681       operator=(const const_reverse_fielditerator &r)                   //[t82]
00682         { iterator_type::operator=(r); return *this; }
00683     const_reverse_fielditerator operator++()                            //[t82]
00684         { iterator_type::operator--(); return *this; }
00685     const_reverse_fielditerator operator++(int);                        //[t82]
00686     const_reverse_fielditerator &operator--()                           //[t82]
00687         { iterator_type::operator++(); return *this; }
00688     const_reverse_fielditerator operator--(int);                        //[t82]
00689     const_reverse_fielditerator &operator+=(difference_type i)          //[t82]
00690         { iterator_type::operator-=(i); return *this; }
00691     const_reverse_fielditerator &operator-=(difference_type i)          //[t82]
00692         { iterator_type::operator+=(i); return *this; }
00694 
00699     const_reverse_fielditerator operator+(difference_type i) const      //[t82]
00700         { return const_reverse_fielditerator(base()-i); }
00701     const_reverse_fielditerator operator-(difference_type i)            //[t82]
00702         { return const_reverse_fielditerator(base()+i); }
00703     difference_type
00704       operator-(const const_reverse_fielditerator &rhs) const           //[t82]
00705         { return rhs.const_fielditerator::operator-(*this); }
00707 
00712     bool
00713       operator==(const const_reverse_fielditerator &rhs) const throw () //[t82]
00714         { return iterator_type::operator==(rhs); }
00715     bool
00716       operator!=(const const_reverse_fielditerator &rhs) const throw () //[t82]
00717         { return !operator==(rhs); }
00718 
00719     bool operator<(const const_reverse_fielditerator &rhs) const        //[t82]
00720         { return iterator_type::operator>(rhs); }
00721     bool operator<=(const const_reverse_fielditerator &rhs) const       //[t82]
00722         { return iterator_type::operator>=(rhs); }
00723     bool operator>(const const_reverse_fielditerator &rhs) const        //[t82]
00724         { return iterator_type::operator<(rhs); }
00725     bool operator>=(const const_reverse_fielditerator &rhs) const       //[t82]
00726         { return iterator_type::operator<=(rhs); }
00728   };
00729 
00730 
00731   result() throw () : super() {}                                        //[t3]
00732   result(const result &rhs) throw () : super(rhs) {}                    //[t1]
00733 
00734   result &operator=(const result &rhs) throw ()                         //[t10]
00735         { super::operator=(rhs); return *this; }
00736 
00741   bool operator==(const result &) const throw ();                       //[t70]
00742   bool operator!=(const result &rhs) const throw ()                     //[t70]
00743         { return !operator==(rhs); }
00745 
00746   const_reverse_iterator rbegin() const                                 //[t75]
00747         { return const_reverse_iterator(end()); }
00748   const_reverse_iterator rend() const                                   //[t75]
00749         { return const_reverse_iterator(begin()); }
00750 
00751   const_iterator begin() const throw ()                                 //[t1]
00752         { return const_iterator(this, 0); }
00753   inline const_iterator end() const throw ();                           //[t1]
00754 
00755   reference front() const throw () { return tuple(this,0); }            //[t74]
00756   reference back() const throw () {return tuple(this,size()-1);}        //[t75]
00757 
00758   size_type size() const throw ();                                      //[t2]
00759   bool empty() const throw ();                                          //[t11]
00760   size_type capacity() const throw () { return size(); }                //[t20]
00761 
00762   void swap(result &) throw ();                                         //[t77]
00763 
00764   const tuple operator[](size_type i) const throw ()                    //[t2]
00765         { return tuple(this, i); }
00766   const tuple at(size_type) const throw (PGSTD::out_of_range);          //[t10]
00767 
00768   using super::clear;                                                   //[t20]
00769 
00774 
00775   tuple::size_type columns() const throw ();                            //[t11]
00776 
00778   tuple::size_type column_number(const char ColName[]) const;           //[t11]
00779 
00781   tuple::size_type column_number(const PGSTD::string &Name) const       //[t11]
00782         {return column_number(Name.c_str());}
00783 
00785   const char *column_name(tuple::size_type Number) const;               //[t11]
00786 
00788   oid column_type(tuple::size_type ColNum) const;                       //[t7]
00790   oid column_type(int ColNum) const                                     //[t7]
00791         { return column_type(tuple::size_type(ColNum)); }
00792 
00794   oid column_type(const PGSTD::string &ColName) const                   //[t7]
00795         { return column_type(column_number(ColName)); }
00796 
00798   oid column_type(const char ColName[]) const                           //[t7]
00799         { return column_type(column_number(ColName)); }
00800 
00802 
00809   oid column_table(tuple::size_type ColNum) const;                      //[t2]
00810 
00812 
00819   oid column_table(int ColNum) const                                    //[t2]
00820         { return column_table(tuple::size_type(ColNum)); }
00821 
00823 
00830   oid column_table(const PGSTD::string &ColName) const                  //[t2]
00831         { return column_table(column_number(ColName)); }
00833 
00835 
00838   oid inserted_oid() const;                                             //[t13]
00839 
00840 
00842 
00845   size_type affected_rows() const;                                      //[t7]
00846 
00847 
00848 #ifdef PQXX_DEPRECATED_HEADERS
00849 
00853 
00854   typedef tuple Tuple;
00856   typedef field Field;
00858   oid InsertedOid() const PQXX_DEPRECATED { return inserted_oid(); }
00860   size_type AffectedRows() const PQXX_DEPRECATED { return affected_rows(); }
00862   tuple::size_type Columns() const PQXX_DEPRECATED { return columns(); }
00864   tuple::size_type ColumnNumber(const char Name[]) const PQXX_DEPRECATED
00865         {return column_number(Name);}
00867   tuple::size_type ColumnNumber(const PGSTD::string &Name) const PQXX_DEPRECATED
00868         {return column_number(Name);}
00870   const char *ColumnName(tuple::size_type Number) const PQXX_DEPRECATED
00871         {return column_name(Number);}
00873 #endif
00874 
00875 
00876 private:
00877   friend class pqxx::result::field;
00878   const char *GetValue(size_type Row, tuple::size_type Col) const;
00879   bool GetIsNull(size_type Row, tuple::size_type Col) const;
00880   field::size_type GetLength(size_type, tuple::size_type) const;
00881 
00882   friend class connection_base;
00883   friend class pipeline;
00884   explicit result(internal::pq::PGresult *rhs) throw () : super(rhs) {}
00885   result &operator=(internal::pq::PGresult *rhs) throw ()
00886         { super::operator=(rhs); return *this; }
00887   bool operator!() const throw () { return !c_ptr(); }
00888   operator bool() const throw () { return c_ptr() != 0; }
00889   void PQXX_PRIVATE CheckStatus(const PGSTD::string &Query) const;
00890   void PQXX_PRIVATE CheckStatus(const char Query[]) const;
00891   int PQXX_PRIVATE errorposition() const throw ();
00892   PGSTD::string PQXX_PRIVATE StatusError() const;
00893 
00894   friend class Cursor;  // deprecated
00895   friend class cursor_base;
00896   const char *CmdStatus() const throw ();
00897 };
00898 
00899 
00901 
00921 template<typename STREAM>
00922 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)      //[t46]
00923 {
00924   S.write(F.c_str(), F.size());
00925   return S;
00926 }
00927 
00928 
00930 template<typename T>
00931 inline void from_string(const result::field &F, T &Obj)                 //[t46]
00932         { from_string(F.c_str(), Obj); }
00933 
00935 template<>
00936 inline PGSTD::string to_string(const result::field &Obj)                //[t74]
00937         { return to_string(Obj.c_str()); }
00938 
00939 
00941 template<>
00942 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00943 {
00944   if (is_null()) return false;
00945   Obj = c_str();
00946   return true;
00947 }
00948 
00950 
00955 template<>
00956 inline bool result::field::to<const char *>(const char *&Obj) const
00957 {
00958   if (is_null()) return false;
00959   Obj = c_str();
00960   return true;
00961 }
00962 
00963 
00964 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00965         { return const_reverse_fielditerator(end()); }
00966 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00967         { return const_reverse_fielditerator(begin()); }
00968 
00969 inline result::const_iterator
00970 result::const_iterator::operator+(difference_type o) const
00971         { return const_iterator(m_Home, m_Index + o); }
00972 
00973 inline result::const_iterator
00974 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00975         { return i + o; }
00976 
00977 inline result::const_iterator
00978 result::const_iterator::operator-(difference_type o) const
00979         { return const_iterator(m_Home, m_Index - o); }
00980 
00981 inline result::const_iterator::difference_type
00982 result::const_iterator::operator-(const_iterator i) const
00983         { return num()-i.num(); }
00984 
00985 inline result::const_iterator result::end() const throw ()
00986         { return const_iterator(this, size()); }
00987 
00988 
00989 inline result::const_reverse_iterator
00990 operator+(result::const_reverse_iterator::difference_type n,
00991           const result::const_reverse_iterator &i)
00992         { return result::const_reverse_iterator(i.base() - n); }
00993 
00994 inline result::const_fielditerator
00995 result::const_fielditerator::operator+(difference_type o) const
00996         { return const_fielditerator(m_tup, col() + o); }
00997 
00998 inline result::const_fielditerator
00999 operator+(result::const_fielditerator::difference_type o,
01000           result::const_fielditerator i)
01001         { return i + o; }
01002 
01003 inline result::const_fielditerator
01004 result::const_fielditerator::operator-(difference_type o) const
01005         { return const_fielditerator(m_tup, col() - o); }
01006 
01007 inline result::const_fielditerator::difference_type
01008 result::const_fielditerator::operator-(const_fielditerator i) const
01009         { return num()-i.num(); }
01010 
01011 
01012 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01013   class field_streambuf :
01014 #ifdef PQXX_HAVE_STREAMBUF
01015   public PGSTD::basic_streambuf<CHAR, TRAITS>
01016 #else
01017   public PGSTD::streambuf
01018 #endif
01019 {
01020 public:
01021   typedef CHAR char_type;
01022   typedef TRAITS traits_type;
01023   typedef typename traits_type::int_type int_type;
01024 #ifdef PQXX_HAVE_STREAMBUF
01025   typedef typename traits_type::pos_type pos_type;
01026   typedef typename traits_type::off_type off_type;
01027 #else
01028   typedef streamoff off_type;
01029   typedef streampos pos_type;
01030 #endif
01031   typedef PGSTD::ios::openmode openmode;
01032   typedef PGSTD::ios::seekdir seekdir;
01033 
01034   explicit field_streambuf(const result::field &F) :                    //[t74]
01035     m_Field(F)
01036   {
01037     initialize();
01038   }
01039 
01040 #ifdef PQXX_HAVE_STREAMBUF
01041 protected:
01042 #endif
01043   virtual int sync() { return traits_type::eof(); }
01044 
01045 protected:
01046   virtual pos_type seekoff(off_type, seekdir, openmode)
01047         { return traits_type::eof(); }
01048   virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
01049   virtual int_type overflow(int_type) { return traits_type::eof(); }
01050   virtual int_type underflow() { return traits_type::eof(); }
01051 
01052 private:
01053   const result::field &m_Field;
01054 
01055   int_type initialize()
01056   {
01057     char_type *G =
01058       reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
01059     setg(G, G, G + m_Field.size());
01060     return m_Field.size();
01061   }
01062 };
01063 
01064 
01066 
01074 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01075   class basic_fieldstream :
01076 #ifdef PQXX_HAVE_STREAMBUF
01077     public PGSTD::basic_istream<CHAR, TRAITS>
01078 #else
01079     public PGSTD::istream
01080 #endif
01081 {
01082 #ifdef PQXX_HAVE_STREAMBUF
01083   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
01084 #else
01085   typedef PGSTD::istream super;
01086 #endif
01087 
01088 public:
01089   typedef CHAR char_type;
01090   typedef TRAITS traits_type;
01091   typedef typename traits_type::int_type int_type;
01092   typedef typename traits_type::pos_type pos_type;
01093   typedef typename traits_type::off_type off_type;
01094 
01095   basic_fieldstream(const result::field &F) : super(0), m_Buf(F)
01096         { super::init(&m_Buf); }
01097 
01098 private:
01099   field_streambuf<CHAR, TRAITS> m_Buf;
01100 };
01101 
01102 typedef basic_fieldstream<char> fieldstream;
01103 
01104 } // namespace pqxx
01105 
01106 
01107 
01108 /*
01109 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
01110 Effective C++", points out that it is good style to have any class containing
01111 a member of pointer type define a destructor--just to show that it knows what it
01112 is doing with the pointer.  This helps prevent nasty memory leak / double
01113 deletion bugs typically resulting from programmers' omission to deal with such
01114 issues in their destructors.
01115 
01116 The @c -Weffc++ option in gcc generates warnings for noncompliance with Scott's
01117 style guidelines, and hence necessitates the definition of this destructor,
01118 trivial as it may be.
01119 */
01120 
01121 
01122 #include "pqxx/compiler-internal-post.hxx"

Generated on Sun Jun 18 14:51:00 2006 for libpqxx by  doxygen 1.4.6