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       const char *const bytes = c_str();
00318       if (!bytes[0] && is_null()) return false;
00319       from_string(bytes, Obj);
00320       return true;
00321     }
00322 
00324     template<typename T> bool operator>>(T &Obj) const                  //[t7]
00325         { return to(Obj); }
00326 
00327 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00329     template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00330 
00332 
00335     template<> bool to<const char *>(const char *&Obj) const;
00336 #endif
00337 
00339     template<typename T> bool to(T &Obj, const T &Default) const        //[t12]
00340     {
00341       const bool NotNull = to(Obj);
00342       if (!NotNull) Obj = Default;
00343       return NotNull;
00344     }
00345 
00347 
00350     template<typename T> T as(const T &Default) const                   //[t1]
00351     {
00352       T Obj;
00353       to(Obj, Default);
00354       return Obj;
00355     }
00356 
00358     template<typename T> T as() const                                   //[t45]
00359     {
00360       T Obj;
00361       const bool NotNull = to(Obj);
00362       if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00363       return Obj;
00364     }
00365 
00366     bool is_null() const { return home()->GetIsNull(idx(), col()); }    //[t12]
00367     size_type size() const throw ()                                     //[t11]
00368         { return home()->GetLength(idx(),col()); }
00370 
00371 #ifdef PQXX_DEPRECATED_HEADERS
00373     const char *Name() const PQXX_DEPRECATED {return name();}
00374 #endif
00375 
00376   private:
00377     const result *home() const throw () { return m_tup.m_Home; }
00378     result::size_type idx() const throw () { return m_tup.m_Index; }
00379 
00380   protected:
00381     const tuple::size_type col() const throw () { return m_col; }
00382     tuple m_tup;
00383     tuple::size_type m_col;
00384   };
00385 
00386   typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00387                            const tuple,
00388                            result::difference_type,
00389                            const_iterator,
00390                            tuple>
00391         const_iterator_base;
00392 
00394 
00398   class PQXX_LIBEXPORT const_iterator :
00399     public const_iterator_base,
00400     public tuple
00401   {
00402   public:
00403     typedef const tuple *pointer;
00404     typedef tuple reference;
00405     typedef result::size_type size_type;
00406     typedef result::difference_type difference_type;
00407 
00408     const_iterator() throw () : tuple(0,0) {}
00409     const_iterator(const tuple &t) throw () : tuple(t) {}
00410 
00426     pointer operator->() const { return this; }                         //[t12]
00427     reference operator*() const { return tuple(*this); }                //[t12]
00429 
00434     const_iterator operator++(int);                                     //[t12]
00435     const_iterator &operator++() { ++m_Index; return *this; }           //[t1]
00436     const_iterator operator--(int);                                     //[t12]
00437     const_iterator &operator--() { --m_Index; return *this; }           //[t12]
00438 
00439     const_iterator &operator+=(difference_type i)                       //[t12]
00440         { m_Index+=i; return *this; }
00441     const_iterator &operator-=(difference_type i)                       //[t12]
00442         { m_Index-=i; return *this; }
00444 
00449     bool operator==(const const_iterator &i) const                      //[t12]
00450         {return m_Index==i.m_Index;}
00451     bool operator!=(const const_iterator &i) const                      //[t12]
00452         {return m_Index!=i.m_Index;}
00453     bool operator<(const const_iterator &i) const                       //[t12]
00454         {return m_Index<i.m_Index;}
00455     bool operator<=(const const_iterator &i) const                      //[t12]
00456         {return m_Index<=i.m_Index;}
00457     bool operator>(const const_iterator &i) const                       //[t12]
00458         {return m_Index>i.m_Index;}
00459     bool operator>=(const const_iterator &i) const                      //[t12]
00460         {return m_Index>=i.m_Index;}
00462 
00467     inline const_iterator operator+(difference_type) const;             //[t12]
00468     friend const_iterator
00469     operator+(difference_type, const_iterator);                         //[t12]
00470     inline const_iterator operator-(difference_type) const;             //[t12]
00471     inline difference_type operator-(const_iterator) const;             //[t12]
00473 
00474   private:
00475     friend class pqxx::result;
00476     const_iterator(const pqxx::result *r, result::size_type i) throw () :
00477         tuple(r, i) {}
00478   };
00479 
00480   class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00481   {
00482   public:
00483     typedef pqxx::result::const_iterator super;
00484     typedef pqxx::result::const_iterator iterator_type;
00485     using iterator_type::iterator_category;
00486     using iterator_type::difference_type;
00487     using iterator_type::pointer;
00488 #ifndef _MSC_VER
00489     using iterator_type::value_type;
00490     using iterator_type::reference;
00491 #else
00492     // Workaround for Visual C++.NET 2003, which has access problems
00493     typedef const tuple &reference;
00494     typedef tuple value_type;
00495 #endif
00496 
00497     const_reverse_iterator(const const_reverse_iterator &rhs) :         //[t75]
00498       const_iterator(rhs) {}
00499     explicit const_reverse_iterator(const const_iterator &rhs) :        //[t75]
00500       const_iterator(rhs) { super::operator--(); }
00501 
00502     iterator_type base() const throw ();                                //[t75]
00503 
00508     using const_iterator::operator->;                                   //[t75]
00509     using const_iterator::operator*;                                    //[t75]
00511 
00516     const_reverse_iterator &operator=(const const_reverse_iterator &r)  //[t75]
00517         { iterator_type::operator=(r); return *this; }
00518     const_reverse_iterator operator++()                                 //[t75]
00519         { iterator_type::operator--(); return *this; }
00520     const_reverse_iterator operator++(int);                             //[t75]
00521     const_reverse_iterator &operator--()                                //[t75]
00522         { iterator_type::operator++(); return *this; }
00523     const_reverse_iterator operator--(int);                             //[t75]
00524     const_reverse_iterator &operator+=(difference_type i)               //[t75]
00525         { iterator_type::operator-=(i); return *this; }
00526     const_reverse_iterator &operator-=(difference_type i)               //[t75]
00527         { iterator_type::operator+=(i); return *this; }
00529 
00534     const_reverse_iterator operator+(difference_type i) const           //[t75]
00535         { return const_reverse_iterator(base()-i); }
00536     const_reverse_iterator operator-(difference_type i)                 //[t75]
00537         { return const_reverse_iterator(base()+i); }
00538     difference_type operator-(const const_reverse_iterator &rhs) const  //[t75]
00539         { return rhs.const_iterator::operator-(*this); }
00541 
00546     bool operator==(const const_reverse_iterator &rhs) const throw ()   //[t75]
00547         { return iterator_type::operator==(rhs); }
00548     bool operator!=(const const_reverse_iterator &rhs) const throw ()   //[t75]
00549         { return !operator==(rhs); }
00550 
00551     bool operator<(const const_reverse_iterator &rhs) const             //[t75]
00552         { return iterator_type::operator>(rhs); }
00553     bool operator<=(const const_reverse_iterator &rhs) const            //[t75]
00554         { return iterator_type::operator>=(rhs); }
00555     bool operator>(const const_reverse_iterator &rhs) const             //[t75]
00556         { return iterator_type::operator<(rhs); }
00557     bool operator>=(const const_reverse_iterator &rhs) const            //[t75]
00558         { return iterator_type::operator<=(rhs); }
00560   };
00561 
00562   class PQXX_LIBEXPORT const_fielditerator :
00563     public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00564                            const field,
00565                            tuple::size_type>,
00566     public field
00567   {
00568     typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00569                                   const field,
00570                                   tuple::size_type> it;
00571   public:
00572     using it::pointer;
00573     typedef tuple::size_type size_type;
00574     typedef tuple::difference_type difference_type;
00575     typedef field reference;
00576 
00577     const_fielditerator(const tuple &T, tuple::size_type C) throw () :  //[t82]
00578       field(T, C) {}
00579     const_fielditerator(const field &F) throw () : field(F) {}          //[t82]
00580 
00585     pointer operator->() const { return this; }                         //[t82]
00586     reference operator*() const { return field(*this); }                //[t82]
00588 
00593     const_fielditerator operator++(int);                                //[t82]
00594     const_fielditerator &operator++() { ++m_col; return *this; }        //[t82]
00595     const_fielditerator operator--(int);                                //[t82]
00596     const_fielditerator &operator--() { --m_col; return *this; }        //[t82]
00597 
00598     const_fielditerator &operator+=(difference_type i)                  //[t82]
00599         { m_col+=i; return *this; }
00600     const_fielditerator &operator-=(difference_type i)                  //[t82]
00601         { m_col-=i; return *this; }
00603 
00608     bool operator==(const const_fielditerator &i) const                 //[t82]
00609         {return col()==i.col();}
00610     bool operator!=(const const_fielditerator &i) const                 //[t82]
00611         {return col()!=i.col();}
00612     bool operator<(const const_fielditerator &i) const                  //[t82]
00613         {return col()<i.col();}
00614     bool operator<=(const const_fielditerator &i) const                 //[t82]
00615         {return col()<=i.col();}
00616     bool operator>(const const_fielditerator &i) const                  //[t82]
00617         {return col()>i.col();}
00618     bool operator>=(const const_fielditerator &i) const                 //[t82]
00619         {return col()>=i.col();}
00621 
00626     inline const_fielditerator operator+(difference_type) const;        //[t82]
00627 
00628     friend const_fielditerator operator+(difference_type,
00629                                           const_fielditerator);         //[t82]
00630 
00631     inline const_fielditerator operator-(difference_type) const;        //[t82]
00632     inline difference_type operator-(const_fielditerator) const;        //[t82]
00634   };
00635 
00636   class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00637   {
00638   public:
00639     typedef const_fielditerator super;
00640     typedef const_fielditerator iterator_type;
00641     using iterator_type::iterator_category;
00642     using iterator_type::difference_type;
00643     using iterator_type::pointer;
00644 #ifndef _MSC_VER
00645     using iterator_type::value_type;
00646     using iterator_type::reference;
00647 #else
00648     // Workaround for Visual C++.NET 2003, which has access problems
00649     typedef field value_type;
00650     typedef const field &reference;
00651 #endif
00652 
00653     const_reverse_fielditerator(const const_reverse_fielditerator &r) : //[t82]
00654       const_fielditerator(r) {}
00655     explicit
00656       const_reverse_fielditerator(const super &rhs) throw() :           //[t82]
00657         const_fielditerator(rhs) { super::operator--(); }
00658 
00659     iterator_type base() const throw ();                                //[t82]
00660 
00665     using iterator_type::operator->;                                    //[t82]
00666     using iterator_type::operator*;                                     //[t82]
00668 
00673     const_reverse_fielditerator &
00674       operator=(const const_reverse_fielditerator &r)                   //[t82]
00675         { iterator_type::operator=(r); return *this; }
00676     const_reverse_fielditerator operator++()                            //[t82]
00677         { iterator_type::operator--(); return *this; }
00678     const_reverse_fielditerator operator++(int);                        //[t82]
00679     const_reverse_fielditerator &operator--()                           //[t82]
00680         { iterator_type::operator++(); return *this; }
00681     const_reverse_fielditerator operator--(int);                        //[t82]
00682     const_reverse_fielditerator &operator+=(difference_type i)          //[t82]
00683         { iterator_type::operator-=(i); return *this; }
00684     const_reverse_fielditerator &operator-=(difference_type i)          //[t82]
00685         { iterator_type::operator+=(i); return *this; }
00687 
00692     const_reverse_fielditerator operator+(difference_type i) const      //[t82]
00693         { return const_reverse_fielditerator(base()-i); }
00694     const_reverse_fielditerator operator-(difference_type i)            //[t82]
00695         { return const_reverse_fielditerator(base()+i); }
00696     difference_type
00697       operator-(const const_reverse_fielditerator &rhs) const           //[t82]
00698         { return rhs.const_fielditerator::operator-(*this); }
00700 
00705     bool
00706       operator==(const const_reverse_fielditerator &rhs) const throw () //[t82]
00707         { return iterator_type::operator==(rhs); }
00708     bool
00709       operator!=(const const_reverse_fielditerator &rhs) const throw () //[t82]
00710         { return !operator==(rhs); }
00711 
00712     bool operator<(const const_reverse_fielditerator &rhs) const        //[t82]
00713         { return iterator_type::operator>(rhs); }
00714     bool operator<=(const const_reverse_fielditerator &rhs) const       //[t82]
00715         { return iterator_type::operator>=(rhs); }
00716     bool operator>(const const_reverse_fielditerator &rhs) const        //[t82]
00717         { return iterator_type::operator<(rhs); }
00718     bool operator>=(const const_reverse_fielditerator &rhs) const       //[t82]
00719         { return iterator_type::operator<=(rhs); }
00721   };
00722 
00723 
00724   result() throw () : super() {}                                        //[t3]
00725   result(const result &rhs) throw () : super(rhs) {}                    //[t1]
00726 
00727   result &operator=(const result &rhs) throw ()                         //[t10]
00728         { super::operator=(rhs); return *this; }
00729 
00734   bool operator==(const result &) const throw ();                       //[t70]
00735   bool operator!=(const result &rhs) const throw ()                     //[t70]
00736         { return !operator==(rhs); }
00738 
00739   const_reverse_iterator rbegin() const                                 //[t75]
00740         { return const_reverse_iterator(end()); }
00741   const_reverse_iterator rend() const                                   //[t75]
00742         { return const_reverse_iterator(begin()); }
00743 
00744   const_iterator begin() const throw ()                                 //[t1]
00745         { return const_iterator(this, 0); }
00746   inline const_iterator end() const throw ();                           //[t1]
00747 
00748   reference front() const throw () { return tuple(this,0); }            //[t74]
00749   reference back() const throw () {return tuple(this,size()-1);}        //[t75]
00750 
00751   size_type size() const throw ();                                      //[t2]
00752   bool empty() const throw ();                                          //[t11]
00753   size_type capacity() const throw () { return size(); }                //[t20]
00754 
00755   void swap(result &) throw ();                                         //[t77]
00756 
00757   const tuple operator[](size_type i) const throw ()                    //[t2]
00758         { return tuple(this, i); }
00759   const tuple at(size_type) const throw (PGSTD::out_of_range);          //[t10]
00760 
00761   using super::clear;                                                   //[t20]
00762 
00767 
00768   tuple::size_type columns() const throw ();                            //[t11]
00769 
00771   tuple::size_type column_number(const char ColName[]) const;           //[t11]
00772 
00774   tuple::size_type column_number(const PGSTD::string &Name) const       //[t11]
00775         {return column_number(Name.c_str());}
00776 
00778   const char *column_name(tuple::size_type Number) const;               //[t11]
00779 
00781   oid column_type(tuple::size_type ColNum) const;                       //[t7]
00783   oid column_type(int ColNum) const                                     //[t7]
00784         { return column_type(tuple::size_type(ColNum)); }
00785 
00787   oid column_type(const PGSTD::string &ColName) const                   //[t7]
00788         { return column_type(column_number(ColName)); }
00789 
00791   oid column_type(const char ColName[]) const                           //[t7]
00792         { return column_type(column_number(ColName)); }
00793 
00795 
00802   oid column_table(tuple::size_type ColNum) const;                      //[t2]
00803 
00805 
00812   oid column_table(int ColNum) const                                    //[t2]
00813         { return column_table(tuple::size_type(ColNum)); }
00814 
00816 
00823   oid column_table(const PGSTD::string &ColName) const                  //[t2]
00824         { return column_table(column_number(ColName)); }
00826 
00828 
00831   oid inserted_oid() const;                                             //[t13]
00832 
00833 
00835 
00838   size_type affected_rows() const;                                      //[t7]
00839 
00840 
00841 #ifdef PQXX_DEPRECATED_HEADERS
00842 
00846 
00847   typedef tuple Tuple;
00849   typedef field Field;
00851   oid InsertedOid() const PQXX_DEPRECATED { return inserted_oid(); }
00853   size_type AffectedRows() const PQXX_DEPRECATED { return affected_rows(); }
00855   tuple::size_type Columns() const PQXX_DEPRECATED { return columns(); }
00857   tuple::size_type ColumnNumber(const char Name[]) const PQXX_DEPRECATED
00858         {return column_number(Name);}
00860   tuple::size_type ColumnNumber(const PGSTD::string &Name) const PQXX_DEPRECATED
00861         {return column_number(Name);}
00863   const char *ColumnName(tuple::size_type Number) const PQXX_DEPRECATED
00864         {return column_name(Number);}
00866 #endif
00867 
00868 
00869 private:
00870   friend class pqxx::result::field;
00871   const char *GetValue(size_type Row, tuple::size_type Col) const;
00872   bool GetIsNull(size_type Row, tuple::size_type Col) const;
00873   field::size_type GetLength(size_type, tuple::size_type) const;
00874 
00875   friend class connection_base;
00876   friend class pipeline;
00877   explicit result(internal::pq::PGresult *rhs) throw () : super(rhs) {}
00878   result &operator=(internal::pq::PGresult *rhs) throw ()
00879         { super::operator=(rhs); return *this; }
00880   bool operator!() const throw () { return !c_ptr(); }
00881   operator bool() const throw () { return c_ptr() != 0; }
00882   void PQXX_PRIVATE CheckStatus(const PGSTD::string &Query) const;
00883   void PQXX_PRIVATE CheckStatus(const char Query[]) const;
00884   void PQXX_PRIVATE ThrowSQLError(const PGSTD::string &Err,
00885         const PGSTD::string &Query) const;
00886   int PQXX_PRIVATE errorposition() const throw ();
00887   PGSTD::string PQXX_PRIVATE StatusError() const;
00888 
00889   friend class Cursor;  // deprecated
00890   friend class cursor_base;
00891   const char *CmdStatus() const throw ();
00892 };
00893 
00894 
00896 
00916 template<typename STREAM>
00917 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)      //[t46]
00918 {
00919   S.write(F.c_str(), F.size());
00920   return S;
00921 }
00922 
00923 
00925 template<typename T>
00926 inline void from_string(const result::field &F, T &Obj)                 //[t46]
00927         { from_string(F.c_str(), Obj, F.size()); }
00928 
00930 template<>
00931 inline PGSTD::string to_string(const result::field &Obj)                //[t74]
00932         { return PGSTD::string(Obj.c_str(), Obj.size()); }
00933 
00934 
00936 template<>
00937 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00938 {
00939   const char *const bytes = c_str();
00940   if (!bytes[0] && is_null()) return false;
00941   Obj = PGSTD::string(bytes, size());
00942   return true;
00943 }
00944 
00946 
00951 template<>
00952 inline bool result::field::to<const char *>(const char *&Obj) const
00953 {
00954   if (is_null()) return false;
00955   Obj = c_str();
00956   return true;
00957 }
00958 
00959 
00960 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00961         { return const_reverse_fielditerator(end()); }
00962 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00963         { return const_reverse_fielditerator(begin()); }
00964 
00965 inline result::const_iterator
00966 result::const_iterator::operator+(difference_type o) const
00967         { return const_iterator(m_Home, m_Index + o); }
00968 
00969 inline result::const_iterator
00970 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00971         { return i + o; }
00972 
00973 inline result::const_iterator
00974 result::const_iterator::operator-(difference_type o) const
00975         { return const_iterator(m_Home, m_Index - o); }
00976 
00977 inline result::const_iterator::difference_type
00978 result::const_iterator::operator-(const_iterator i) const
00979         { return num()-i.num(); }
00980 
00981 inline result::const_iterator result::end() const throw ()
00982         { return const_iterator(this, size()); }
00983 
00984 
00985 inline result::const_reverse_iterator
00986 operator+(result::const_reverse_iterator::difference_type n,
00987           const result::const_reverse_iterator &i)
00988         { return result::const_reverse_iterator(i.base() - n); }
00989 
00990 inline result::const_fielditerator
00991 result::const_fielditerator::operator+(difference_type o) const
00992         { return const_fielditerator(m_tup, col() + o); }
00993 
00994 inline result::const_fielditerator
00995 operator+(result::const_fielditerator::difference_type o,
00996           result::const_fielditerator i)
00997         { return i + o; }
00998 
00999 inline result::const_fielditerator
01000 result::const_fielditerator::operator-(difference_type o) const
01001         { return const_fielditerator(m_tup, col() - o); }
01002 
01003 inline result::const_fielditerator::difference_type
01004 result::const_fielditerator::operator-(const_fielditerator i) const
01005         { return num()-i.num(); }
01006 
01007 
01008 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01009   class field_streambuf :
01010 #ifdef PQXX_HAVE_STREAMBUF
01011   public PGSTD::basic_streambuf<CHAR, TRAITS>
01012 #else
01013   public PGSTD::streambuf
01014 #endif
01015 {
01016 public:
01017   typedef CHAR char_type;
01018   typedef TRAITS traits_type;
01019   typedef typename traits_type::int_type int_type;
01020 #ifdef PQXX_HAVE_STREAMBUF
01021   typedef typename traits_type::pos_type pos_type;
01022   typedef typename traits_type::off_type off_type;
01023 #else
01024   typedef streamoff off_type;
01025   typedef streampos pos_type;
01026 #endif
01027   typedef PGSTD::ios::openmode openmode;
01028   typedef PGSTD::ios::seekdir seekdir;
01029 
01030   explicit field_streambuf(const result::field &F) :                    //[t74]
01031     m_Field(F)
01032   {
01033     initialize();
01034   }
01035 
01036 #ifdef PQXX_HAVE_STREAMBUF
01037 protected:
01038 #endif
01039   virtual int sync() { return traits_type::eof(); }
01040 
01041 protected:
01042   virtual pos_type seekoff(off_type, seekdir, openmode)
01043         { return traits_type::eof(); }
01044   virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
01045   virtual int_type overflow(int_type) { return traits_type::eof(); }
01046   virtual int_type underflow() { return traits_type::eof(); }
01047 
01048 private:
01049   const result::field &m_Field;
01050 
01051   int_type initialize()
01052   {
01053     char_type *G =
01054       reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
01055     setg(G, G, G + m_Field.size());
01056     return m_Field.size();
01057   }
01058 };
01059 
01060 
01062 
01070 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01071   class basic_fieldstream :
01072 #ifdef PQXX_HAVE_STREAMBUF
01073     public PGSTD::basic_istream<CHAR, TRAITS>
01074 #else
01075     public PGSTD::istream
01076 #endif
01077 {
01078 #ifdef PQXX_HAVE_STREAMBUF
01079   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
01080 #else
01081   typedef PGSTD::istream super;
01082 #endif
01083 
01084 public:
01085   typedef CHAR char_type;
01086   typedef TRAITS traits_type;
01087   typedef typename traits_type::int_type int_type;
01088   typedef typename traits_type::pos_type pos_type;
01089   typedef typename traits_type::off_type off_type;
01090 
01091   basic_fieldstream(const result::field &F) : super(0), m_Buf(F)
01092         { super::init(&m_Buf); }
01093 
01094 private:
01095   field_streambuf<CHAR, TRAITS> m_Buf;
01096 };
01097 
01098 typedef basic_fieldstream<char> fieldstream;
01099 
01100 } // namespace pqxx
01101 
01102 
01103 
01104 /*
01105 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
01106 Effective C++", points out that it is good style to have any class containing
01107 a member of pointer type define a destructor--just to show that it knows what it
01108 is doing with the pointer.  This helps prevent nasty memory leak / double
01109 deletion bugs typically resulting from programmers' omission to deal with such
01110 issues in their destructors.
01111 
01112 The @c -Weffc++ option in gcc generates warnings for noncompliance with Scott's
01113 style guidelines, and hence necessitates the definition of this destructor,
01114 trivial as it may be.
01115 */
01116 
01117 
01118 #include "pqxx/compiler-internal-post.hxx"

Generated on Wed Sep 6 16:54:12 2006 for libpqxx by  doxygen 1.4.7