Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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-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_IOS
00022 #include <ios>
00023 #endif
00024 
00025 #include <stdexcept>
00026 
00027 #include "pqxx/util"
00028 
00029 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
00030  */
00031 
00032 // TODO: Support SQL arrays
00033 
00034 namespace pqxx
00035 {
00037 
00055 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::pq::PGresult>
00056 {
00057   typedef internal::PQAlloc<internal::pq::PGresult> super;
00058 public:
00059   class const_iterator;
00060   class const_fielditerator;
00061   class const_reverse_fielditerator;
00062   class tuple;
00063   class field;
00064   typedef unsigned long size_type;
00065   typedef signed long difference_type;
00066   typedef tuple reference;
00067   typedef const_iterator pointer;
00068 
00070 
00081   class PQXX_LIBEXPORT tuple
00082   {
00083   public:
00084     typedef unsigned int size_type;
00085     typedef signed int difference_type;
00086     typedef const_fielditerator const_iterator;
00087     typedef field reference;
00088     typedef const_fielditerator pointer;
00089     typedef const_reverse_fielditerator const_reverse_iterator;
00090 
00091     tuple(const result *r, result::size_type i) throw () :
00092       m_Home(r), m_Index(i) {}
00093     ~tuple() throw () {} // Yes Scott Meyers, you're absolutely right[1]
00094 
00095     bool operator==(const tuple &) const throw ();                      //[t75]
00096     bool operator!=(const tuple &rhs) const throw ()                    //[t75]
00097         { return !operator==(rhs); }
00098 
00099     const_iterator begin() const throw ()                               //[t82]
00100         { return const_iterator(*this, 0); }
00101     const_iterator end() const throw ()                                 //[t82]
00102         { return const_iterator(*this, size()); }
00103 
00104     reference front() const throw () { return field(*this, 0); }        //[t74]
00105     reference back() const throw () { return field(*this, size()-1); }  //[t75]
00106 
00107     const_reverse_fielditerator rbegin() const;                         //[t82]
00108     const_reverse_fielditerator rend() const;                           //[t82]
00109 
00110     reference operator[](size_type i) const throw ()                    //[t11]
00111         { return field(*this, i); }
00112     reference operator[](int i) const throw ()                          //[t2]
00113         { return operator[](size_type(i)); }
00114     reference operator[](const char[]) const;                           //[t11]
00115     reference operator[](const PGSTD::string &s) const                  //[t11]
00116         { return operator[](s.c_str()); }
00117     reference at(size_type) const throw (PGSTD::out_of_range);          //[t11]
00118     reference at(int i) const throw (PGSTD::out_of_range)               //[t11]
00119         { return at(size_type(i)); }
00120     reference at(const char[]) const;                                   //[t11]
00121     reference at(const PGSTD::string &s) const                          //[t11]
00122         { return at(s.c_str()); }
00123 
00124     size_type size() const throw () { return m_Home->columns(); }       //[t11]
00125 
00126     void swap(tuple &) throw ();                                        //[t11]
00127 
00128     result::size_type rownumber() const throw () { return m_Index; }    //[t11]
00129 
00131     size_type column_number(const PGSTD::string &ColName) const         //[t30]
00132         { return m_Home->column_number(ColName); }
00133 
00135     size_type column_number(const char ColName[]) const                 //[t30]
00136         { return m_Home->column_number(ColName); }
00137 
00139     oid column_type(size_type ColNum) const                             //[t7]
00140         { return m_Home->column_type(ColNum); }
00141 
00143     oid column_type(int ColNum) const                                   //[t7]
00144         { return column_type(size_type(ColNum)); }
00145 
00147     oid column_type(const PGSTD::string &ColName) const                 //[t7]
00148         { return column_type(column_number(ColName)); }
00149 
00151     oid column_type(const char ColName[]) const                         //[t7]
00152         { return column_type(column_number(ColName)); }
00153 
00154     result::size_type num() const { return rownumber(); }               //[t1]
00155 
00157 
00164     oid column_table(size_type ColNum) const                            //[t2]
00165         { return m_Home->column_table(ColNum); }
00167 
00174     oid column_table(int ColNum) const                                  //[t2]
00175         { return column_table(size_type(ColNum)); }
00177 
00184     oid column_table(const PGSTD::string &ColName) const                //[t2]
00185         { return column_table(column_number(ColName)); }
00186 
00187 
00188 #ifdef PQXX_DEPRECATED_HEADERS
00189 
00190     result::size_type Row() const { return rownumber(); }
00191 
00193     size_type ColumnNumber(const PGSTD::string &ColName) const
00194         { return column_number(ColName); }
00195 
00197     size_type ColumnNumber(const char ColName[]) const
00198         { return column_number(ColName); }
00199 #endif
00200 
00201   protected:
00202     friend class field;
00203     const result *m_Home;
00204     result::size_type m_Index;
00205 
00206     // Not allowed:
00207     tuple();
00208   };
00209 
00211 
00214   class PQXX_LIBEXPORT field
00215   {
00216   public:
00217     typedef size_t size_type;
00218 
00220 
00224     field(const tuple &T, tuple::size_type C) throw () :                //[t1]
00225         m_tup(T), m_col(C) {}
00226 
00228 
00244     bool operator==(const field &) const;                               //[t75]
00245 
00247 
00249     bool operator!=(const field &rhs) const {return !operator==(rhs);}  //[t82]
00250 
00252 
00257     const char *c_str() const { return home()->GetValue(idx(),col()); } //[t2]
00258 
00260     const char *name() const { return home()->column_name(col()); }     //[t11]
00261 
00263     oid type() const { return home()->column_type(col()); }             //[t7]
00264 
00266 
00273     oid table() const { return home()->column_table(col()); }           //[t2]
00274 
00276     template<typename T> bool to(T &Obj) const                          //[t3]
00277     {
00278       if (is_null()) return false;
00279       try
00280       {
00281         from_string(c_str(), Obj);
00282       }
00283       catch (const PGSTD::exception &e)
00284       {
00285         throw PGSTD::domain_error("Error reading field " +
00286                                   PGSTD::string(name()) + ": " +
00287                                   e.what());
00288       }
00289       return true;
00290     }
00291 
00293     template<typename T> bool operator>>(T &Obj) const                  //[t7]
00294         { return to(Obj); }
00295 
00296 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00297 
00298     template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00299 
00301 
00304     template<> bool to<const char *>(const char *&Obj) const;
00305 #endif
00306 
00308     template<typename T> bool to(T &Obj, const T &Default) const                //[t12]
00309     {
00310       const bool NotNull = to(Obj);
00311       if (!NotNull) Obj = Default;
00312       return NotNull;
00313     }
00314 
00316 
00319     template<typename T> T as(const T &Default) const                   //[t1]
00320     {
00321       T Obj;
00322       to(Obj, Default);
00323       return Obj;
00324     }
00325 
00327     template<typename T> T as() const                                   //[t45]
00328     {
00329       T Obj;
00330       const bool NotNull = to(Obj);
00331       if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00332       return Obj;
00333     }
00334 
00335     bool is_null() const { return home()->GetIsNull(idx(), col()); }    //[t12]
00336     size_type size() const throw ()                                     //[t11]
00337         { return home()->GetLength(idx(),col()); }
00338     tuple::size_type num() const { return col(); }                      //[t82]
00339 
00340 #ifdef PQXX_DEPRECATED_HEADERS
00341 
00342     const char *Name() const {return name();}
00343 #endif
00344 
00345   private:
00346     const result *home() const throw () { return m_tup.m_Home; }
00347     result::size_type idx() const throw () { return m_tup.m_Index; }
00348 
00349   protected:
00350     const tuple::size_type col() const throw () { return m_col; }
00351     tuple m_tup;
00352     tuple::size_type m_col;
00353   };
00354 
00355   typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00356                            const tuple,
00357                            result::difference_type,
00358                            const_iterator,
00359                            tuple> const_iterator_base;
00360 
00362 
00366   class PQXX_LIBEXPORT const_iterator :
00367     public const_iterator_base,
00368     public tuple
00369   {
00370   public:
00371     typedef const tuple *pointer;
00372     typedef tuple reference;
00373     typedef result::size_type size_type;
00374     typedef result::difference_type difference_type;
00375 
00376     const_iterator() throw () : tuple(0,0) {}
00377     const_iterator(const tuple &t) throw () : tuple(t) {}
00378 
00390     pointer operator->() const { return this; }                         //[t12]
00391     reference operator*() const { return tuple(*this); }                //[t12]
00392 
00393     const_iterator operator++(int);                                     //[t12]
00394     const_iterator &operator++() { ++m_Index; return *this; }           //[t1]
00395     const_iterator operator--(int);                                     //[t12]
00396     const_iterator &operator--() { --m_Index; return *this; }           //[t12]
00397 
00398     const_iterator &operator+=(difference_type i)                       //[t12]
00399         { m_Index+=i; return *this; }
00400     const_iterator &operator-=(difference_type i)                       //[t12]
00401         { m_Index-=i; return *this; }
00402 
00403     bool operator==(const const_iterator &i) const                      //[t12]
00404         {return m_Index==i.m_Index;}
00405     bool operator!=(const const_iterator &i) const                      //[t12]
00406         {return m_Index!=i.m_Index;}
00407     bool operator<(const const_iterator &i) const                       //[t12]
00408         {return m_Index<i.m_Index;}
00409     bool operator<=(const const_iterator &i) const                      //[t12]
00410         {return m_Index<=i.m_Index;}
00411     bool operator>(const const_iterator &i) const                       //[t12]
00412         {return m_Index>i.m_Index;}
00413     bool operator>=(const const_iterator &i) const                      //[t12]
00414         {return m_Index>=i.m_Index;}
00415 
00416     inline const_iterator operator+(difference_type) const;             //[t12]
00417     friend const_iterator
00418     operator+(difference_type, const_iterator);                         //[t12]
00419     inline const_iterator operator-(difference_type) const;             //[t12]
00420     inline difference_type operator-(const_iterator) const;             //[t12]
00421 
00422   private:
00423     friend class pqxx::result;
00424     const_iterator(const pqxx::result *r, result::size_type i) throw () :
00425         tuple(r, i) {}
00426   };
00427 
00428   class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00429   {
00430   public:
00431     typedef const_iterator iterator_type;
00432     using iterator_type::iterator_category;
00433     using iterator_type::difference_type;
00434     using iterator_type::pointer;
00435 #ifndef _MSC_VER
00436     using iterator_type::value_type;
00437     using iterator_type::reference;
00438 #else
00439     // Workaround for Visual C++.NET 2003, which has access problems
00440     typedef const tuple &reference;
00441     typedef tuple value_type;
00442 #endif
00443 
00444     const_reverse_iterator(const const_reverse_iterator &rhs) :         //[t75]
00445       const_iterator(rhs), m_tmp(rhs) {}
00446     explicit const_reverse_iterator(const const_iterator &rhs) :        //[t75]
00447       const_iterator(rhs), m_tmp() {}
00448 
00449     iterator_type base() const throw () { return *this; }               //[t75]
00450 
00451     const_reverse_iterator &operator=(const const_reverse_iterator &r)  //[t75]
00452         { iterator_type::operator=(r); return *this; }
00453     pointer operator->() const throw ()                                 //[t75]
00454         { m_tmp=*this; --m_tmp; return &m_tmp; }
00455     reference operator*() const throw () { return *operator->(); }      //[t75]
00456     const_reverse_iterator operator++()                                 //[t75]
00457         { iterator_type::operator--(); return *this; }
00458     const_reverse_iterator operator++(int);                             //[t75]
00459     const_reverse_iterator &operator--()                                //[t75]
00460         { iterator_type::operator++(); return *this; }
00461     const_reverse_iterator operator--(int);                             //[t75]
00462     const_reverse_iterator operator+(difference_type i) const           //[t75]
00463         { return const_reverse_iterator(iterator_type(*this)-i); }
00464     const_reverse_iterator &operator+=(difference_type i)               //[t75]
00465         { iterator_type::operator-=(i); return *this; }
00466     const_reverse_iterator operator-(difference_type i)                 //[t75]
00467         { return const_reverse_iterator(iterator_type(*this)+i); }
00468     const_reverse_iterator &operator-=(difference_type i)               //[t75]
00469         { iterator_type::operator+=(i); return *this; }
00470 
00471     bool operator==(const const_reverse_iterator &rhs) const throw ()   //[t75]
00472         { return iterator_type::operator==(rhs); }
00473     bool operator!=(const const_reverse_iterator &rhs) const throw ()   //[t75]
00474         { return !operator==(rhs); }
00475 
00476     bool operator<(const const_reverse_iterator &rhs) const             //[t75]
00477         { return iterator_type::operator>(rhs); }
00478     bool operator<=(const const_reverse_iterator &rhs) const            //[t75]
00479         { return iterator_type::operator>=(rhs); }
00480     bool operator>(const const_reverse_iterator &rhs) const             //[t75]
00481         { return iterator_type::operator<(rhs); }
00482     bool operator>=(const const_reverse_iterator &rhs) const            //[t75]
00483         { return iterator_type::operator<=(rhs); }
00484     difference_type operator-(const const_reverse_iterator &rhs) const  //[t75]
00485         { return rhs.base() - base(); }
00486 
00487   private:
00489 
00494     mutable iterator_type m_tmp;
00495   };
00496 
00497   class PQXX_LIBEXPORT const_fielditerator :
00498     public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00499                            const field,
00500                            tuple::size_type>,
00501     public field
00502   {
00503     typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00504                                   const field,
00505                                   tuple::size_type> it;
00506   public:
00507     using it::pointer;
00508     typedef tuple::size_type size_type;
00509     typedef tuple::difference_type difference_type;
00510     typedef field reference;
00511 
00512     const_fielditerator(const tuple &T, tuple::size_type C) throw () :  //[t82]
00513       field(T, C) {}
00514     const_fielditerator(const field &F) throw () : field(F) {}          //[t82]
00515 
00516     pointer operator->() const { return this; }                         //[t82]
00517     reference operator*() const { return field(*this); }                //[t82]
00518 
00519     const_fielditerator operator++(int);                                //[t82]
00520     const_fielditerator &operator++() { ++m_col; return *this; }        //[t82]
00521     const_fielditerator operator--(int);                                //[t82]
00522     const_fielditerator &operator--() { --m_col; return *this; }        //[t82]
00523 
00524     const_fielditerator &operator+=(difference_type i)                  //[t82]
00525         { m_col+=i; return *this; }
00526     const_fielditerator &operator-=(difference_type i)                  //[t82]
00527         { m_col-=i; return *this; }
00528 
00529     bool operator==(const const_fielditerator &i) const                 //[t82]
00530         {return col()==i.col();}
00531     bool operator!=(const const_fielditerator &i) const                 //[t82]
00532         {return col()!=i.col();}
00533     bool operator<(const const_fielditerator &i) const                  //[t82]
00534         {return col()<i.col();}
00535     bool operator<=(const const_fielditerator &i) const                 //[t82]
00536         {return col()<=i.col();}
00537     bool operator>(const const_fielditerator &i) const                  //[t82]
00538         {return col()>i.col();}
00539     bool operator>=(const const_fielditerator &i) const                 //[t82]
00540         {return col()>=i.col();}
00541 
00542     inline const_fielditerator operator+(difference_type) const;        //[t82]
00543 
00544     friend const_fielditerator operator+(difference_type,
00545                                           const_fielditerator);         //[t82]
00546 
00547     inline const_fielditerator operator-(difference_type) const;        //[t82]
00548     inline difference_type operator-(const_fielditerator) const;        //[t82]
00549   };
00550 
00551   class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00552   {
00553   public:
00554     typedef const_fielditerator iterator_type;
00555     using iterator_type::iterator_category;
00556     using iterator_type::difference_type;
00557     using iterator_type::pointer;
00558 #ifndef _MSC_VER
00559     using iterator_type::value_type;
00560     using iterator_type::reference;
00561 #else
00562     // Workaround for Visual C++.NET 2003, which has access problems
00563     typedef field value_type;
00564     typedef const field &reference;
00565 #endif
00566 
00567     iterator_type base() const throw () { return *this; }               //[t82]
00568     const_reverse_fielditerator(const const_reverse_fielditerator &rhs) //[t82]
00569       : const_fielditerator(rhs), m_tmp(rhs.m_tmp) {}
00570     explicit
00571       const_reverse_fielditerator(const const_fielditerator &rhs) :     //[t82]
00572       const_fielditerator(rhs), m_tmp(rhs) {}
00573 
00574     const_reverse_fielditerator &
00575       operator=(const const_reverse_fielditerator &r)                   //[t82]
00576         { iterator_type::operator=(r); return *this; }
00577     pointer operator->() const throw ()                                 //[t82]
00578         { m_tmp = *this; --m_tmp; return &m_tmp; }
00579     reference operator*() const throw () { return *operator->(); }      //[t82]
00580     const_reverse_fielditerator operator++()                            //[t82]
00581         { iterator_type::operator--(); return *this; }
00582     const_reverse_fielditerator operator++(int);                        //[t82]
00583     const_reverse_fielditerator &operator--()                           //[t82]
00584         { iterator_type::operator++(); return *this; }
00585     const_reverse_fielditerator operator--(int);                        //[t82]
00586     const_reverse_fielditerator operator+(difference_type i) const      //[t82]
00587         { return const_reverse_fielditerator(iterator_type(*this)-i); }
00588     const_reverse_fielditerator &operator+=(difference_type i)          //[t82]
00589         { iterator_type::operator-=(i); return *this; }
00590     const_reverse_fielditerator operator-(difference_type i)            //[t82]
00591         { return const_reverse_fielditerator(iterator_type(*this)+i); }
00592     const_reverse_fielditerator &operator-=(difference_type i)          //[t82]
00593         { iterator_type::operator+=(i); return *this; }
00594 
00595     bool
00596       operator==(const const_reverse_fielditerator &rhs) const throw () //[t82]
00597         { return iterator_type::operator==(rhs); }
00598     bool
00599       operator!=(const const_reverse_fielditerator &rhs) const throw () //[t82]
00600         { return !operator==(rhs); }
00601 
00602 
00603     bool operator<(const const_reverse_fielditerator &rhs) const        //[t82]
00604         { return iterator_type::operator>(rhs); }
00605     bool operator<=(const const_reverse_fielditerator &rhs) const       //[t82]
00606         { return iterator_type::operator>=(rhs); }
00607     bool operator>(const const_reverse_fielditerator &rhs) const        //[t82]
00608         { return iterator_type::operator<(rhs); }
00609     bool operator>=(const const_reverse_fielditerator &rhs) const       //[t82]
00610         { return iterator_type::operator<=(rhs); }
00611     difference_type
00612       operator-(const const_reverse_fielditerator &rhs) const           //[t82]
00613         { return rhs.base() - base(); }
00614 
00615   private:
00617 
00622     mutable iterator_type m_tmp;
00623   };
00624 
00625 
00626   result() throw () : super() {}                                        //[t3]
00627   result(const result &rhs) throw () : super(rhs) {}                    //[t1]
00628 
00629   result &operator=(const result &rhs) throw ()                         //[t10]
00630         { super::operator=(rhs); return *this; }
00631 
00632   bool operator==(const result &) const throw ();                       //[t70]
00633   bool operator!=(const result &rhs) const throw ()                     //[t70]
00634         { return !operator==(rhs); }
00635 
00636   const_reverse_iterator rbegin() const                                 //[t75]
00637         { return const_reverse_iterator(end()); }
00638   const_reverse_iterator rend() const                                   //[t75]
00639         { return const_reverse_iterator(begin()); }
00640 
00641   const_iterator begin() const throw ()                                 //[t1]
00642         { return const_iterator(this, 0); }
00643   inline const_iterator end() const throw ();                           //[t1]
00644 
00645   reference front() const throw () { return tuple(this,0); }            //[t74]
00646   reference back() const throw () {return tuple(this,size()-1);}        //[t75]
00647 
00648   size_type size() const throw ();                                      //[t2]
00649   bool empty() const throw ();                                          //[t11]
00650   size_type capacity() const throw () { return size(); }                //[t20]
00651 
00652   void swap(result &) throw ();                                         //[t77]
00653 
00654   const tuple operator[](size_type i) const throw ()                    //[t2]
00655         { return tuple(this, i); }
00656   const tuple at(size_type) const throw (PGSTD::out_of_range);          //[t10]
00657 
00658   using super::clear;                                                   //[t20]
00659 
00661   tuple::size_type columns() const throw ();                            //[t11]
00662 
00664   tuple::size_type column_number(const char ColName[]) const;           //[t11]
00665 
00667   tuple::size_type column_number(const PGSTD::string &Name) const       //[t11]
00668         {return column_number(Name.c_str());}
00669 
00671   const char *column_name(tuple::size_type Number) const;               //[t11]
00672 
00674   oid column_type(tuple::size_type ColNum) const;                       //[t7]
00676   oid column_type(int ColNum) const                                     //[t7]
00677         { return column_type(tuple::size_type(ColNum)); }
00678 
00680   oid column_type(const PGSTD::string &ColName) const                   //[t7]
00681         { return column_type(column_number(ColName)); }
00682 
00684   oid column_type(const char ColName[]) const                           //[t7]
00685         { return column_type(column_number(ColName)); }
00686 
00688 
00695   oid column_table(tuple::size_type ColNum) const;                      //[t2]
00696 
00698 
00705   oid column_table(int ColNum) const                                    //[t2]
00706         { return column_table(tuple::size_type(ColNum)); }
00707 
00709 
00716   oid column_table(const PGSTD::string &ColName) const                  //[t2]
00717         { return column_table(column_number(ColName)); }
00718 
00720 
00723   oid inserted_oid() const;                                             //[t13]
00724 
00725 
00727 
00730   size_type affected_rows() const;                                      //[t7]
00731 
00732 
00733 #ifdef PQXX_DEPRECATED_HEADERS
00734 
00735   typedef tuple Tuple;
00737   typedef field Field;
00739   oid InsertedOid() const { return inserted_oid(); }
00741   size_type AffectedRows() const { return affected_rows(); }
00743   tuple::size_type Columns() const { return columns(); }
00745   tuple::size_type ColumnNumber(const char Name[]) const
00746         {return column_number(Name);}
00748   tuple::size_type ColumnNumber(const PGSTD::string &Name) const
00749         {return column_number(Name);}
00751   const char *ColumnName(tuple::size_type Number) const
00752         {return column_name(Number);}
00753 #endif
00754 
00755 
00756 private:
00757   friend class pqxx::result::field;
00758   const char *GetValue(size_type Row, tuple::size_type Col) const;
00759   bool GetIsNull(size_type Row, tuple::size_type Col) const;
00760   field::size_type GetLength(size_type, tuple::size_type) const;
00761 
00762   friend class connection_base;
00763   friend class pipeline;
00764   explicit result(internal::pq::PGresult *rhs) throw () : super(rhs) {}
00765   result &operator=(internal::pq::PGresult *rhs) throw ()
00766         { super::operator=(rhs); return *this; }
00767   bool operator!() const throw () { return !c_ptr(); }
00768   operator bool() const throw () { return c_ptr() != 0; }
00769   void PQXX_PRIVATE CheckStatus(const PGSTD::string &Query) const;
00770   void PQXX_PRIVATE CheckStatus(const char Query[]) const;
00771   int PQXX_PRIVATE errorposition() const throw ();
00772   PGSTD::string PQXX_PRIVATE StatusError() const;
00773 
00774   friend class Cursor;
00775   const char *CmdStatus() const throw ();
00776 };
00777 
00778 
00780 
00799 template<typename STREAM>
00800 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)      //[t46]
00801 {
00802   S.write(F.c_str(), F.size());
00803   return S;
00804 }
00805 
00806 
00808 template<typename T>
00809 inline void from_string(const result::field &F, T &Obj)                 //[t46]
00810         { from_string(F.c_str(), Obj); }
00811 
00813 template<>
00814 inline PGSTD::string to_string(const result::field &Obj)                //[t74]
00815         { return to_string(Obj.c_str()); }
00816 
00817 
00819 template<>
00820 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00821 {
00822   if (is_null()) return false;
00823   Obj = c_str();
00824   return true;
00825 }
00826 
00828 
00833 template<>
00834 inline bool result::field::to<const char *>(const char *&Obj) const
00835 {
00836   if (is_null()) return false;
00837   Obj = c_str();
00838   return true;
00839 }
00840 
00841 
00842 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00843         { return const_reverse_fielditerator(end()); }
00844 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00845         { return const_reverse_fielditerator(begin()); }
00846 
00847 inline result::const_iterator
00848 result::const_iterator::operator+(difference_type o) const
00849         { return const_iterator(m_Home, m_Index + o); }
00850 
00851 inline result::const_iterator
00852 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00853         { return i + o; }
00854 
00855 inline result::const_iterator
00856 result::const_iterator::operator-(difference_type o) const
00857         { return const_iterator(m_Home, m_Index - o); }
00858 
00859 inline result::const_iterator::difference_type
00860 result::const_iterator::operator-(const_iterator i) const
00861         { return num()-i.num(); }
00862 
00863 inline result::const_iterator result::end() const throw ()
00864         { return const_iterator(this, size()); }
00865 
00866 
00867 inline result::const_reverse_iterator
00868 operator+(result::const_reverse_iterator::difference_type n,
00869           const result::const_reverse_iterator &i)
00870         { return result::const_reverse_iterator(i.base() - n); }
00871 
00872 inline result::const_fielditerator
00873 result::const_fielditerator::operator+(difference_type o) const
00874         { return const_fielditerator(m_tup, col() + o); }
00875 
00876 inline result::const_fielditerator
00877 operator+(result::const_fielditerator::difference_type o,
00878           result::const_fielditerator i)
00879         { return i + o; }
00880 
00881 inline result::const_fielditerator
00882 result::const_fielditerator::operator-(difference_type o) const
00883         { return const_fielditerator(m_tup, col() - o); }
00884 
00885 inline result::const_fielditerator::difference_type
00886 result::const_fielditerator::operator-(const_fielditerator i) const
00887         { return num()-i.num(); }
00888 
00889 
00890 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00891   class field_streambuf :
00892 #ifdef PQXX_HAVE_STREAMBUF
00893   public PGSTD::basic_streambuf<CHAR, TRAITS>
00894 #else
00895   public PGSTD::streambuf
00896 #endif
00897 {
00898 public:
00899   typedef CHAR char_type;
00900   typedef TRAITS traits_type;
00901   typedef typename traits_type::int_type int_type;
00902 #ifdef PQXX_HAVE_STREAMBUF
00903   typedef typename traits_type::pos_type pos_type;
00904   typedef typename traits_type::off_type off_type;
00905 #else
00906   typedef streamoff off_type;
00907   typedef streampos pos_type;
00908 #endif
00909   typedef PGSTD::ios::openmode openmode;
00910   typedef PGSTD::ios::seekdir seekdir;
00911 
00912   explicit field_streambuf(const result::field &F) :                    //[t74]
00913     m_Field(F)
00914   {
00915     initialize();
00916   }
00917 
00918 #ifdef PQXX_HAVE_STREAMBUF
00919 protected:
00920 #endif
00921   virtual int sync() { return traits_type::eof(); }
00922 
00923 protected:
00924   virtual pos_type seekoff(off_type, seekdir, openmode)
00925         { return traits_type::eof(); }
00926   virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
00927   virtual int_type overflow(int_type) { return traits_type::eof(); }
00928   virtual int_type underflow() { return traits_type::eof(); }
00929 
00930 private:
00931   const result::field &m_Field;
00932 
00933   int_type initialize()
00934   {
00935     char_type *G =
00936       reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
00937     setg(G, G, G + m_Field.size());
00938     return m_Field.size();
00939   }
00940 };
00941 
00942 
00944 
00952 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00953   class basic_fieldstream :
00954 #ifdef PQXX_HAVE_STREAMBUF
00955     public PGSTD::basic_istream<CHAR, TRAITS>
00956 #else
00957     public PGSTD::istream
00958 #endif
00959 {
00960 #ifdef PQXX_HAVE_STREAMBUF
00961   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00962 #else
00963   typedef PGSTD::istream super;
00964 #endif
00965 
00966 public:
00967   typedef CHAR char_type;
00968   typedef TRAITS traits_type;
00969   typedef typename traits_type::int_type int_type;
00970   typedef typename traits_type::pos_type pos_type;
00971   typedef typename traits_type::off_type off_type;
00972 
00973   basic_fieldstream(const result::field &F) : super(0), m_Buf(F)
00974         { super::init(&m_Buf); }
00975 
00976 private:
00977   field_streambuf<CHAR, TRAITS> m_Buf;
00978 };
00979 
00980 typedef basic_fieldstream<char> fieldstream;
00981 
00982 } // namespace pqxx
00983 
00984 
00985 
00986 /*
00987 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
00988 Effective C++", points out that it is good style to have any class containing
00989 a member of pointer type define a destructor--just to show that it knows what it
00990 is doing with the pointer.  This helps prevent nasty memory leak / double
00991 deletion bugs typically resulting from programmers' omission to deal with such
00992 issues in their destructors.
00993 
00994 The -Weffc++ option in gcc generates warnings for noncompliance with Scott's
00995 style guidelines, and hence necessitates the definition of this destructor,
00996 trivial as it may be.
00997 */
00998 
00999 

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