Main Page | Modules | 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 
00099     bool operator==(const tuple &) const throw ();                      //[t75]
00100     bool operator!=(const tuple &rhs) const throw ()                    //[t75]
00101         { return !operator==(rhs); }
00103 
00104     const_iterator begin() const throw ()                               //[t82]
00105         { return const_iterator(*this, 0); }
00106     const_iterator end() const throw ()                                 //[t82]
00107         { return const_iterator(*this, size()); }
00108 
00113     reference front() const throw () { return field(*this, 0); }        //[t74]
00114     reference back() const throw () { return field(*this, size()-1); }  //[t75]
00115 
00116     const_reverse_fielditerator rbegin() const;                         //[t82]
00117     const_reverse_fielditerator rend() const;                           //[t82]
00118 
00119     reference operator[](size_type i) const throw ()                    //[t11]
00120         { return field(*this, i); }
00121     reference operator[](int i) const throw ()                          //[t2]
00122         { return operator[](size_type(i)); }
00123     reference operator[](const char[]) const;                           //[t11]
00124     reference operator[](const PGSTD::string &s) const                  //[t11]
00125         { return operator[](s.c_str()); }
00126     reference at(size_type) const throw (PGSTD::out_of_range);          //[t11]
00127     reference at(int i) const throw (PGSTD::out_of_range)               //[t11]
00128         { return at(size_type(i)); }
00129     reference at(const char[]) const;                                   //[t11]
00130     reference at(const PGSTD::string &s) const                          //[t11]
00131         { return at(s.c_str()); }
00133 
00134     size_type size() const throw () { return m_Home->columns(); }       //[t11]
00135 
00136     void swap(tuple &) throw ();                                        //[t11]
00137 
00138     result::size_type rownumber() const throw () { return m_Index; }    //[t11]
00139 
00144 
00145     size_type column_number(const PGSTD::string &ColName) const         //[t30]
00146         { return m_Home->column_number(ColName); }
00147 
00149     size_type column_number(const char ColName[]) const                 //[t30]
00150         { return m_Home->column_number(ColName); }
00151 
00153     oid column_type(size_type ColNum) const                             //[t7]
00154         { return m_Home->column_type(ColNum); }
00155 
00157     oid column_type(int ColNum) const                                   //[t7]
00158         { return column_type(size_type(ColNum)); }
00159 
00161     oid column_type(const PGSTD::string &ColName) const                 //[t7]
00162         { return column_type(column_number(ColName)); }
00163 
00165     oid column_type(const char ColName[]) const                         //[t7]
00166         { return column_type(column_number(ColName)); }
00167 
00169 
00176     oid column_table(size_type ColNum) const                            //[t2]
00177         { return m_Home->column_table(ColNum); }
00179 
00186     oid column_table(int ColNum) const                                  //[t2]
00187         { return column_table(size_type(ColNum)); }
00189 
00196     oid column_table(const PGSTD::string &ColName) const                //[t2]
00197         { return column_table(column_number(ColName)); }
00199 
00200     result::size_type num() const { return rownumber(); }               //[t1]
00201 
00202 
00203 #ifdef PQXX_DEPRECATED_HEADERS
00204 
00208 
00209     result::size_type Row() const { return rownumber(); }
00210 
00212     size_type ColumnNumber(const PGSTD::string &ColName) const
00213         { return column_number(ColName); }
00214 
00216     size_type ColumnNumber(const char ColName[]) const
00217         { return column_number(ColName); }
00219 #endif
00220 
00221   protected:
00222     friend class field;
00223     const result *m_Home;
00224     result::size_type m_Index;
00225 
00226     // Not allowed:
00227     tuple();
00228   };
00229 
00231 
00234   class PQXX_LIBEXPORT field
00235   {
00236   public:
00237     typedef size_t size_type;
00238 
00240 
00244     field(const tuple &T, tuple::size_type C) throw () :                //[t1]
00245         m_tup(T), m_col(C) {}
00246 
00251 
00252 
00268     bool operator==(const field &) const;                               //[t75]
00269 
00271 
00273     bool operator!=(const field &rhs) const {return !operator==(rhs);}  //[t82]
00275 
00280 
00281     const char *name() const { return home()->column_name(col()); }     //[t11]
00282 
00284     oid type() const { return home()->column_type(col()); }             //[t7]
00285 
00287 
00294     oid table() const { return home()->column_table(col()); }           //[t2]
00295 
00296     tuple::size_type num() const { return col(); }                      //[t82]
00298 
00303 
00304 
00309     const char *c_str() const { return home()->GetValue(idx(),col()); } //[t2]
00310 
00312     template<typename T> bool to(T &Obj) const                          //[t3]
00313     {
00314       if (is_null()) return false;
00315       try
00316       {
00317         from_string(c_str(), Obj);
00318       }
00319       catch (const PGSTD::exception &e)
00320       {
00321         throw PGSTD::domain_error("Error reading field " +
00322                                   PGSTD::string(name()) + ": " +
00323                                   e.what());
00324       }
00325       return true;
00326     }
00327 
00329     template<typename T> bool operator>>(T &Obj) const                  //[t7]
00330         { return to(Obj); }
00331 
00332 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00333 
00334     template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00335 
00337 
00340     template<> bool to<const char *>(const char *&Obj) const;
00341 #endif
00342 
00344     template<typename T> bool to(T &Obj, const T &Default) const                //[t12]
00345     {
00346       const bool NotNull = to(Obj);
00347       if (!NotNull) Obj = Default;
00348       return NotNull;
00349     }
00350 
00352 
00355     template<typename T> T as(const T &Default) const                   //[t1]
00356     {
00357       T Obj;
00358       to(Obj, Default);
00359       return Obj;
00360     }
00361 
00363     template<typename T> T as() const                                   //[t45]
00364     {
00365       T Obj;
00366       const bool NotNull = to(Obj);
00367       if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00368       return Obj;
00369     }
00370 
00371     bool is_null() const { return home()->GetIsNull(idx(), col()); }    //[t12]
00372     size_type size() const throw ()                                     //[t11]
00373         { return home()->GetLength(idx(),col()); }
00375 
00376 #ifdef PQXX_DEPRECATED_HEADERS
00377 
00378     const char *Name() const {return name();}
00379 #endif
00380 
00381   private:
00382     const result *home() const throw () { return m_tup.m_Home; }
00383     result::size_type idx() const throw () { return m_tup.m_Index; }
00384 
00385   protected:
00386     const tuple::size_type col() const throw () { return m_col; }
00387     tuple m_tup;
00388     tuple::size_type m_col;
00389   };
00390 
00391   typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00392                            const tuple,
00393                            result::difference_type,
00394                            const_iterator,
00395                            tuple> const_iterator_base;
00396 
00398 
00402   class PQXX_LIBEXPORT const_iterator :
00403     public const_iterator_base,
00404     public tuple
00405   {
00406   public:
00407     typedef const tuple *pointer;
00408     typedef tuple reference;
00409     typedef result::size_type size_type;
00410     typedef result::difference_type difference_type;
00411 
00412     const_iterator() throw () : tuple(0,0) {}
00413     const_iterator(const tuple &t) throw () : tuple(t) {}
00414 
00430     pointer operator->() const { return this; }                         //[t12]
00431     reference operator*() const { return tuple(*this); }                //[t12]
00433 
00438     const_iterator operator++(int);                                     //[t12]
00439     const_iterator &operator++() { ++m_Index; return *this; }           //[t1]
00440     const_iterator operator--(int);                                     //[t12]
00441     const_iterator &operator--() { --m_Index; return *this; }           //[t12]
00442 
00443     const_iterator &operator+=(difference_type i)                       //[t12]
00444         { m_Index+=i; return *this; }
00445     const_iterator &operator-=(difference_type i)                       //[t12]
00446         { m_Index-=i; return *this; }
00448 
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;}
00461     bool operator>(const const_iterator &i) const                       //[t12]
00462         {return m_Index>i.m_Index;}
00463     bool operator>=(const const_iterator &i) const                      //[t12]
00464         {return m_Index>=i.m_Index;}
00466 
00471     inline const_iterator operator+(difference_type) const;             //[t12]
00472     friend const_iterator
00473     operator+(difference_type, const_iterator);                         //[t12]
00474     inline const_iterator operator-(difference_type) const;             //[t12]
00475     inline difference_type operator-(const_iterator) const;             //[t12]
00477 
00478   private:
00479     friend class pqxx::result;
00480     const_iterator(const pqxx::result *r, result::size_type i) throw () :
00481         tuple(r, i) {}
00482   };
00483 
00484   class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00485   {
00486   public:
00487     typedef pqxx::result::const_iterator super;
00488     typedef pqxx::result::const_iterator iterator_type;
00489     using iterator_type::iterator_category;
00490     using iterator_type::difference_type;
00491     using iterator_type::pointer;
00492 #ifndef _MSC_VER
00493     using iterator_type::value_type;
00494     using iterator_type::reference;
00495 #else
00496     // Workaround for Visual C++.NET 2003, which has access problems
00497     typedef const tuple &reference;
00498     typedef tuple value_type;
00499 #endif
00500 
00501     const_reverse_iterator(const const_reverse_iterator &rhs) :         //[t75]
00502       const_iterator(rhs) {}
00503     explicit const_reverse_iterator(const const_iterator &rhs) :        //[t75]
00504       const_iterator(rhs) { super::operator--(); }
00505 
00506     iterator_type base() const throw ();                                //[t75]
00507 
00512     using const_iterator::operator->;                                   //[t75]
00513     using const_iterator::operator*;                                    //[t75]
00515  
00520     const_reverse_iterator &operator=(const const_reverse_iterator &r)  //[t75]
00521         { iterator_type::operator=(r); return *this; }
00522     const_reverse_iterator operator++()                                 //[t75]
00523         { iterator_type::operator--(); return *this; }
00524     const_reverse_iterator operator++(int);                             //[t75]
00525     const_reverse_iterator &operator--()                                //[t75]
00526         { iterator_type::operator++(); return *this; }
00527     const_reverse_iterator operator--(int);                             //[t75]
00528     const_reverse_iterator &operator+=(difference_type i)               //[t75]
00529         { iterator_type::operator-=(i); return *this; }
00530     const_reverse_iterator &operator-=(difference_type i)               //[t75]
00531         { iterator_type::operator+=(i); return *this; }
00533 
00538     const_reverse_iterator operator+(difference_type i) const           //[t75]
00539         { return const_reverse_iterator(base()-i); }
00540     const_reverse_iterator operator-(difference_type i)                 //[t75]
00541         { return const_reverse_iterator(base()+i); }
00542     difference_type operator-(const const_reverse_iterator &rhs) const  //[t75]
00543         { return rhs.const_iterator::operator-(*this); }
00545 
00550     bool operator==(const const_reverse_iterator &rhs) const throw ()   //[t75]
00551         { return iterator_type::operator==(rhs); }
00552     bool operator!=(const const_reverse_iterator &rhs) const throw ()   //[t75]
00553         { return !operator==(rhs); }
00554 
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); }
00559     bool operator>(const const_reverse_iterator &rhs) const             //[t75]
00560         { return iterator_type::operator<(rhs); }
00561     bool operator>=(const const_reverse_iterator &rhs) const            //[t75]
00562         { return iterator_type::operator<=(rhs); }
00564   };
00565 
00566   class PQXX_LIBEXPORT const_fielditerator :
00567     public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00568                            const field,
00569                            tuple::size_type>,
00570     public field
00571   {
00572     typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00573                                   const field,
00574                                   tuple::size_type> it;
00575   public:
00576     using it::pointer;
00577     typedef tuple::size_type size_type;
00578     typedef tuple::difference_type difference_type;
00579     typedef field reference;
00580 
00581     const_fielditerator(const tuple &T, tuple::size_type C) throw () :  //[t82]
00582       field(T, C) {}
00583     const_fielditerator(const field &F) throw () : field(F) {}          //[t82]
00584 
00589     pointer operator->() const { return this; }                         //[t82]
00590     reference operator*() const { return field(*this); }                //[t82]
00592 
00597     const_fielditerator operator++(int);                                //[t82]
00598     const_fielditerator &operator++() { ++m_col; return *this; }        //[t82]
00599     const_fielditerator operator--(int);                                //[t82]
00600     const_fielditerator &operator--() { --m_col; return *this; }        //[t82]
00601 
00602     const_fielditerator &operator+=(difference_type i)                  //[t82]
00603         { m_col+=i; return *this; }
00604     const_fielditerator &operator-=(difference_type i)                  //[t82]
00605         { m_col-=i; return *this; }
00607 
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();}
00620     bool operator>(const const_fielditerator &i) const                  //[t82]
00621         {return col()>i.col();}
00622     bool operator>=(const const_fielditerator &i) const                 //[t82]
00623         {return col()>=i.col();}
00625 
00630     inline const_fielditerator operator+(difference_type) const;        //[t82]
00631 
00632     friend const_fielditerator operator+(difference_type,
00633                                           const_fielditerator);         //[t82]
00634 
00635     inline const_fielditerator operator-(difference_type) const;        //[t82]
00636     inline difference_type operator-(const_fielditerator) const;        //[t82]
00638   };
00639 
00640   class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00641   {
00642   public:
00643     typedef const_fielditerator super;
00644     typedef const_fielditerator iterator_type;
00645     using iterator_type::iterator_category;
00646     using iterator_type::difference_type;
00647     using iterator_type::pointer;
00648 #ifndef _MSC_VER
00649     using iterator_type::value_type;
00650     using iterator_type::reference;
00651 #else
00652     // Workaround for Visual C++.NET 2003, which has access problems
00653     typedef field value_type;
00654     typedef const field &reference;
00655 #endif
00656 
00657     const_reverse_fielditerator(const const_reverse_fielditerator &r) : //[t82]
00658       const_fielditerator(r) {}
00659     explicit
00660       const_reverse_fielditerator(const super &rhs) throw() :           //[t82]
00661         const_fielditerator(rhs) { super::operator--(); }
00662 
00663     iterator_type base() const throw ();                                //[t82]
00664 
00669     using iterator_type::operator->;                                    //[t82]
00670     using iterator_type::operator*;                                     //[t82]
00672 
00677     const_reverse_fielditerator &
00678       operator=(const const_reverse_fielditerator &r)                   //[t82]
00679         { iterator_type::operator=(r); return *this; }
00680     const_reverse_fielditerator operator++()                            //[t82]
00681         { iterator_type::operator--(); return *this; }
00682     const_reverse_fielditerator operator++(int);                        //[t82]
00683     const_reverse_fielditerator &operator--()                           //[t82]
00684         { iterator_type::operator++(); return *this; }
00685     const_reverse_fielditerator operator--(int);                        //[t82]
00686     const_reverse_fielditerator &operator+=(difference_type i)          //[t82]
00687         { iterator_type::operator-=(i); return *this; }
00688     const_reverse_fielditerator &operator-=(difference_type i)          //[t82]
00689         { iterator_type::operator+=(i); return *this; }
00691 
00696     const_reverse_fielditerator operator+(difference_type i) const      //[t82]
00697         { return const_reverse_fielditerator(base()-i); }
00698     const_reverse_fielditerator operator-(difference_type i)            //[t82]
00699         { return const_reverse_fielditerator(base()+i); }
00700     difference_type
00701       operator-(const const_reverse_fielditerator &rhs) const           //[t82]
00702         { return rhs.const_fielditerator::operator-(*this); }
00704 
00709     bool
00710       operator==(const const_reverse_fielditerator &rhs) const throw () //[t82]
00711         { return iterator_type::operator==(rhs); }
00712     bool
00713       operator!=(const const_reverse_fielditerator &rhs) const throw () //[t82]
00714         { return !operator==(rhs); }
00715 
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); }
00720     bool operator>(const const_reverse_fielditerator &rhs) const        //[t82]
00721         { return iterator_type::operator<(rhs); }
00722     bool operator>=(const const_reverse_fielditerator &rhs) const       //[t82]
00723         { return iterator_type::operator<=(rhs); }
00725   };
00726 
00727 
00728   result() throw () : super() {}                                        //[t3]
00729   result(const result &rhs) throw () : super(rhs) {}                    //[t1]
00730 
00731   result &operator=(const result &rhs) throw ()                         //[t10]
00732         { super::operator=(rhs); return *this; }
00733 
00738   bool operator==(const result &) const throw ();                       //[t70]
00739   bool operator!=(const result &rhs) const throw ()                     //[t70]
00740         { return !operator==(rhs); }
00742 
00743   const_reverse_iterator rbegin() const                                 //[t75]
00744         { return const_reverse_iterator(end()); }
00745   const_reverse_iterator rend() const                                   //[t75]
00746         { return const_reverse_iterator(begin()); }
00747 
00748   const_iterator begin() const throw ()                                 //[t1]
00749         { return const_iterator(this, 0); }
00750   inline const_iterator end() const throw ();                           //[t1]
00751 
00752   reference front() const throw () { return tuple(this,0); }            //[t74]
00753   reference back() const throw () {return tuple(this,size()-1);}        //[t75]
00754 
00755   size_type size() const throw ();                                      //[t2]
00756   bool empty() const throw ();                                          //[t11]
00757   size_type capacity() const throw () { return size(); }                //[t20]
00758 
00759   void swap(result &) throw ();                                         //[t77]
00760 
00761   const tuple operator[](size_type i) const throw ()                    //[t2]
00762         { return tuple(this, i); }
00763   const tuple at(size_type) const throw (PGSTD::out_of_range);          //[t10]
00764 
00765   using super::clear;                                                   //[t20]
00766 
00771 
00772   tuple::size_type columns() const throw ();                            //[t11]
00773 
00775   tuple::size_type column_number(const char ColName[]) const;           //[t11]
00776 
00778   tuple::size_type column_number(const PGSTD::string &Name) const       //[t11]
00779         {return column_number(Name.c_str());}
00780 
00782   const char *column_name(tuple::size_type Number) const;               //[t11]
00783 
00785   oid column_type(tuple::size_type ColNum) const;                       //[t7]
00787   oid column_type(int ColNum) const                                     //[t7]
00788         { return column_type(tuple::size_type(ColNum)); }
00789 
00791   oid column_type(const PGSTD::string &ColName) const                   //[t7]
00792         { return column_type(column_number(ColName)); }
00793 
00795   oid column_type(const char ColName[]) const                           //[t7]
00796         { return column_type(column_number(ColName)); }
00797 
00799 
00806   oid column_table(tuple::size_type ColNum) const;                      //[t2]
00807 
00809 
00816   oid column_table(int ColNum) const                                    //[t2]
00817         { return column_table(tuple::size_type(ColNum)); }
00818 
00820 
00827   oid column_table(const PGSTD::string &ColName) const                  //[t2]
00828         { return column_table(column_number(ColName)); }
00830 
00832 
00835   oid inserted_oid() const;                                             //[t13]
00836 
00837 
00839 
00842   size_type affected_rows() const;                                      //[t7]
00843 
00844 
00845 #ifdef PQXX_DEPRECATED_HEADERS
00846 
00850 
00851   typedef tuple Tuple;
00853   typedef field Field;
00855   oid InsertedOid() const { return inserted_oid(); }
00857   size_type AffectedRows() const { return affected_rows(); }
00859   tuple::size_type Columns() const { return columns(); }
00861   tuple::size_type ColumnNumber(const char Name[]) const
00862         {return column_number(Name);}
00864   tuple::size_type ColumnNumber(const PGSTD::string &Name) const
00865         {return column_number(Name);}
00867   const char *ColumnName(tuple::size_type Number) const
00868         {return column_name(Number);}
00870 #endif
00871 
00872 
00873 private:
00874   friend class pqxx::result::field;
00875   const char *GetValue(size_type Row, tuple::size_type Col) const;
00876   bool GetIsNull(size_type Row, tuple::size_type Col) const;
00877   field::size_type GetLength(size_type, tuple::size_type) const;
00878 
00879   friend class connection_base;
00880   friend class pipeline;
00881   explicit result(internal::pq::PGresult *rhs) throw () : super(rhs) {}
00882   result &operator=(internal::pq::PGresult *rhs) throw ()
00883         { super::operator=(rhs); return *this; }
00884   bool operator!() const throw () { return !c_ptr(); }
00885   operator bool() const throw () { return c_ptr() != 0; }
00886   void PQXX_PRIVATE CheckStatus(const PGSTD::string &Query) const;
00887   void PQXX_PRIVATE CheckStatus(const char Query[]) const;
00888   int PQXX_PRIVATE errorposition() const throw ();
00889   PGSTD::string PQXX_PRIVATE StatusError() const;
00890 
00891   friend class Cursor;  // deprecated
00892   friend class cursor_base;
00893   const char *CmdStatus() const throw ();
00894 };
00895 
00896 
00898 
00917 template<typename STREAM>
00918 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)      //[t46]
00919 {
00920   S.write(F.c_str(), F.size());
00921   return S;
00922 }
00923 
00924 
00926 template<typename T>
00927 inline void from_string(const result::field &F, T &Obj)                 //[t46]
00928         { from_string(F.c_str(), Obj); }
00929 
00931 template<>
00932 inline PGSTD::string to_string(const result::field &Obj)                //[t74]
00933         { return to_string(Obj.c_str()); }
00934 
00935 
00937 template<>
00938 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00939 {
00940   if (is_null()) return false;
00941   Obj = c_str();
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 -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 

Generated on Mon Oct 3 20:28:59 2005 for libpqxx by  doxygen 1.4.2