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 
00044 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::pq::PGresult>
00045 {
00046   typedef internal::PQAlloc<internal::pq::PGresult> super;
00047 public:
00048   class const_iterator;
00049   class const_fielditerator;
00050   class const_reverse_fielditerator;
00051   class tuple;
00052   class field;
00053   typedef unsigned long size_type;
00054   typedef signed long difference_type;
00055   typedef tuple reference;
00056   typedef const_iterator pointer;
00057 
00059 
00070   class PQXX_LIBEXPORT tuple
00071   {
00072   public:
00073     typedef unsigned int size_type;
00074     typedef signed int difference_type;
00075     typedef const_fielditerator const_iterator;
00076     typedef field reference;
00077     typedef const_fielditerator pointer;
00078     typedef const_reverse_fielditerator const_reverse_iterator;
00079 
00080     tuple(const result *r, result::size_type i) throw () :
00081       m_Home(r), m_Index(i) {}
00082     ~tuple() throw () {} // Yes Scott Meyers, you're absolutely right[1]
00083 
00084     bool operator==(const tuple &) const throw ();                      //[t75]
00085     bool operator!=(const tuple &rhs) const throw ()                    //[t75]
00086         { return !operator==(rhs); }
00087 
00088     const_iterator begin() const throw ()                               //[t82]
00089         { return const_iterator(*this, 0); }
00090     const_iterator end() const throw ()                                 //[t82]
00091         { return const_iterator(*this, size()); }
00092 
00093     reference front() const throw () { return field(*this, 0); }        //[t74]
00094     reference back() const throw () { return field(*this, size()-1); }  //[t75]
00095 
00096     const_reverse_fielditerator rbegin() const;                         //[t82]
00097     const_reverse_fielditerator rend() const;                           //[t82]
00098 
00099     reference operator[](size_type i) const throw ()                    //[t11]
00100         { return field(*this, i); }
00101     reference operator[](int i) const throw ()                          //[t2]
00102         { return operator[](size_type(i)); }
00103     reference operator[](const char[]) const;                           //[t11]
00104     reference operator[](const PGSTD::string &s) const                  //[t11]
00105         { return operator[](s.c_str()); }
00106     reference at(size_type) const throw (PGSTD::out_of_range);          //[t11]
00107     reference at(int i) const throw (PGSTD::out_of_range)               //[t11]
00108         { return at(size_type(i)); }
00109     reference at(const char[]) const;                                   //[t11]
00110     reference at(const PGSTD::string &s) const                          //[t11]
00111         { return at(s.c_str()); }
00112 
00113     size_type size() const throw () { return m_Home->columns(); }       //[t11]
00114 
00115     void swap(tuple &) throw ();                                        //[t11]
00116 
00117     result::size_type rownumber() const throw () { return m_Index; }    //[t11]
00118 
00120     size_type column_number(const PGSTD::string &ColName) const         //[t30]
00121         { return m_Home->column_number(ColName); }
00122 
00124     size_type column_number(const char ColName[]) const                 //[t30]
00125         { return m_Home->column_number(ColName); }
00126 
00128     oid column_type(size_type ColNum) const                             //[t7]
00129         { return m_Home->column_type(ColNum); }
00130 
00132     oid column_type(int ColNum) const                                   //[t7]
00133         { return column_type(size_type(ColNum)); }
00134 
00136     oid column_type(const PGSTD::string &ColName) const                 //[t7]
00137         { return column_type(column_number(ColName)); }
00138 
00140     oid column_type(const char ColName[]) const                         //[t7]
00141         { return column_type(column_number(ColName)); }
00142 
00143     result::size_type num() const { return rownumber(); }               //[t1]
00144 
00146 
00153     oid column_table(size_type ColNum) const                            //[t2]
00154         { return m_Home->column_table(ColNum); }
00156 
00163     oid column_table(int ColNum) const                                  //[t2]
00164         { return column_table(size_type(ColNum)); }
00166 
00173     oid column_table(const PGSTD::string &ColName) const                //[t2]
00174         { return column_table(column_number(ColName)); }
00175 
00176 
00177 #ifdef PQXX_DEPRECATED_HEADERS
00178 
00179     result::size_type Row() const { return rownumber(); }
00180 
00182     size_type ColumnNumber(const PGSTD::string &ColName) const
00183         { return column_number(ColName); }
00184 
00186     size_type ColumnNumber(const char ColName[]) const
00187         { return column_number(ColName); }
00188 #endif
00189 
00190   protected:
00191     friend class field;
00192     const result *m_Home;
00193     result::size_type m_Index;
00194 
00195     // Not allowed:
00196     tuple();
00197   };
00198 
00200 
00203   class PQXX_LIBEXPORT field
00204   {
00205   public:
00206     typedef size_t size_type;
00207 
00209 
00213     field(const tuple &T, tuple::size_type C) throw () :                //[t1]
00214         m_tup(T), m_col(C) {}
00215 
00217 
00233     bool operator==(const field &) const;                               //[t75]
00234 
00236 
00238     bool operator!=(const field &rhs) const {return !operator==(rhs);}  //[t82]
00239 
00241 
00246     const char *c_str() const { return home()->GetValue(idx(),col()); } //[t2]
00247 
00249     const char *name() const { return home()->column_name(col()); }     //[t11]
00250 
00252     oid type() const { return home()->column_type(col()); }             //[t7]
00253 
00255 
00262     oid table() const { return home()->column_table(col()); }           //[t2]
00263 
00265     template<typename T> bool to(T &Obj) const                          //[t3]
00266     {
00267       if (is_null()) return false;
00268       try
00269       {
00270         from_string(c_str(), Obj);
00271       }
00272       catch (const PGSTD::exception &e)
00273       {
00274         throw PGSTD::domain_error("Error reading field " +
00275                                   PGSTD::string(name()) + ": " +
00276                                   e.what());
00277       }
00278       return true;
00279     }
00280 
00282     template<typename T> bool operator>>(T &Obj) const                  //[t7]
00283         { return to(Obj); }
00284 
00285 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00286 
00287     template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00288 
00290 
00293     template<> bool to<const char *>(const char *&Obj) const;
00294 #endif
00295 
00297     template<typename T> bool to(T &Obj, const T &Default) const                //[t12]
00298     {
00299       const bool NotNull = to(Obj);
00300       if (!NotNull) Obj = Default;
00301       return NotNull;
00302     }
00303 
00305 
00308     template<typename T> T as(const T &Default) const                   //[t1]
00309     {
00310       T Obj;
00311       to(Obj, Default);
00312       return Obj;
00313     }
00314 
00316     template<typename T> T as() const                                   //[t45]
00317     {
00318       T Obj;
00319       const bool NotNull = to(Obj);
00320       if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00321       return Obj;
00322     }
00323 
00324     bool is_null() const { return home()->GetIsNull(idx(), col()); }    //[t12]
00325     size_type size() const throw ()                                     //[t11]
00326         { return home()->GetLength(idx(),col()); }
00327     tuple::size_type num() const { return col(); }                      //[t82]
00328 
00329 #ifdef PQXX_DEPRECATED_HEADERS
00330 
00331     const char *Name() const {return name();}
00332 #endif
00333 
00334   private:
00335     const result *home() const throw () { return m_tup.m_Home; }
00336     result::size_type idx() const throw () { return m_tup.m_Index; }
00337 
00338   protected:
00339     const tuple::size_type col() const throw () { return m_col; }
00340     tuple m_tup;
00341     tuple::size_type m_col;
00342   };
00343 
00344   typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00345                            const tuple,
00346                            result::difference_type,
00347                            const_iterator,
00348                            tuple> const_iterator_base;
00349 
00351 
00355   class PQXX_LIBEXPORT const_iterator :
00356     public const_iterator_base,
00357     public tuple
00358   {
00359   public:
00360     typedef const tuple *pointer;
00361     typedef tuple reference;
00362     typedef result::size_type size_type;
00363     typedef result::difference_type difference_type;
00364 
00365     const_iterator() throw () : tuple(0,0) {}
00366     const_iterator(const tuple &t) throw () : tuple(t) {}
00367 
00379     pointer operator->() const { return this; }                         //[t12]
00380     reference operator*() const { return tuple(*this); }                //[t12]
00381 
00382     const_iterator operator++(int);                                     //[t12]
00383     const_iterator &operator++() { ++m_Index; return *this; }           //[t1]
00384     const_iterator operator--(int);                                     //[t12]
00385     const_iterator &operator--() { --m_Index; return *this; }           //[t12]
00386 
00387     const_iterator &operator+=(difference_type i)                       //[t12]
00388         { m_Index+=i; return *this; }
00389     const_iterator &operator-=(difference_type i)                       //[t12]
00390         { m_Index-=i; return *this; }
00391 
00392     bool operator==(const const_iterator &i) const                      //[t12]
00393         {return m_Index==i.m_Index;}
00394     bool operator!=(const const_iterator &i) const                      //[t12]
00395         {return m_Index!=i.m_Index;}
00396     bool operator<(const const_iterator &i) const                       //[t12]
00397         {return m_Index<i.m_Index;}
00398     bool operator<=(const const_iterator &i) const                      //[t12]
00399         {return m_Index<=i.m_Index;}
00400     bool operator>(const const_iterator &i) const                       //[t12]
00401         {return m_Index>i.m_Index;}
00402     bool operator>=(const const_iterator &i) const                      //[t12]
00403         {return m_Index>=i.m_Index;}
00404 
00405     inline const_iterator operator+(difference_type) const;             //[t12]
00406     friend const_iterator
00407     operator+(difference_type, const_iterator);                         //[t12]
00408     inline const_iterator operator-(difference_type) const;             //[t12]
00409     inline difference_type operator-(const_iterator) const;             //[t12]
00410 
00411   private:
00412     friend class pqxx::result;
00413     const_iterator(const pqxx::result *r, result::size_type i) throw () :
00414         tuple(r, i) {}
00415   };
00416 
00417   class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00418   {
00419   public:
00420     typedef const_iterator iterator_type;
00421     using iterator_type::iterator_category;
00422     using iterator_type::difference_type;
00423     using iterator_type::pointer;
00424 #ifndef _MSC_VER
00425     using iterator_type::value_type;
00426     using iterator_type::reference;
00427 #else
00428     // Workaround for Visual C++.NET 2003, which has access problems
00429     typedef const tuple &reference;
00430     typedef tuple value_type;
00431 #endif
00432 
00433     const_reverse_iterator(const const_reverse_iterator &rhs) :         //[t75]
00434       const_iterator(rhs), m_tmp(rhs) {}
00435     explicit const_reverse_iterator(const const_iterator &rhs) :        //[t75]
00436       const_iterator(rhs), m_tmp() {}
00437 
00438     iterator_type base() const throw () { return *this; }               //[t75]
00439 
00440     const_reverse_iterator &operator=(const const_reverse_iterator &r)  //[t75]
00441         { iterator_type::operator=(r); return *this; }
00442     pointer operator->() const throw ()                                 //[t75]
00443         { m_tmp=*this; --m_tmp; return &m_tmp; }
00444     reference operator*() const throw () { return *operator->(); }      //[t75]
00445     const_reverse_iterator operator++()                                 //[t75]
00446         { iterator_type::operator--(); return *this; }
00447     const_reverse_iterator operator++(int);                             //[t75]
00448     const_reverse_iterator &operator--()                                //[t75]
00449         { iterator_type::operator++(); return *this; }
00450     const_reverse_iterator operator--(int);                             //[t75]
00451     const_reverse_iterator operator+(difference_type i) const           //[t75]
00452         { return const_reverse_iterator(iterator_type(*this)-i); }
00453     const_reverse_iterator &operator+=(difference_type i)               //[t75]
00454         { iterator_type::operator-=(i); return *this; }
00455     const_reverse_iterator operator-(difference_type i)                 //[t75]
00456         { return const_reverse_iterator(iterator_type(*this)+i); }
00457     const_reverse_iterator &operator-=(difference_type i)               //[t75]
00458         { iterator_type::operator+=(i); return *this; }
00459 
00460     bool operator==(const const_reverse_iterator &rhs) const throw ()   //[t75]
00461         { return iterator_type::operator==(rhs); }
00462     bool operator!=(const const_reverse_iterator &rhs) const throw ()   //[t75]
00463         { return !operator==(rhs); }
00464 
00465     bool operator<(const const_reverse_iterator &rhs) const             //[t75]
00466         { return iterator_type::operator>(rhs); }
00467     bool operator<=(const const_reverse_iterator &rhs) const            //[t75]
00468         { return iterator_type::operator>=(rhs); }
00469     bool operator>(const const_reverse_iterator &rhs) const             //[t75]
00470         { return iterator_type::operator<(rhs); }
00471     bool operator>=(const const_reverse_iterator &rhs) const            //[t75]
00472         { return iterator_type::operator<=(rhs); }
00473     difference_type operator-(const const_reverse_iterator &rhs) const  //[t75]
00474         { return rhs.base() - base(); }
00475 
00476   private:
00478 
00483     mutable iterator_type m_tmp;
00484   };
00485 
00486   class PQXX_LIBEXPORT const_fielditerator :
00487     public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00488                            const field,
00489                            tuple::size_type>,
00490     public field
00491   {
00492     typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00493                                   const field,
00494                                   tuple::size_type> it;
00495   public:
00496     using it::pointer;
00497     typedef tuple::size_type size_type;
00498     typedef tuple::difference_type difference_type;
00499     typedef field reference;
00500 
00501     const_fielditerator(const tuple &T, tuple::size_type C) throw () :  //[t82]
00502       field(T, C) {}
00503     const_fielditerator(const field &F) throw () : field(F) {}          //[t82]
00504 
00505     pointer operator->() const { return this; }                         //[t82]
00506     reference operator*() const { return field(*this); }                //[t82]
00507 
00508     const_fielditerator operator++(int);                                //[t82]
00509     const_fielditerator &operator++() { ++m_col; return *this; }        //[t82]
00510     const_fielditerator operator--(int);                                //[t82]
00511     const_fielditerator &operator--() { --m_col; return *this; }        //[t82]
00512 
00513     const_fielditerator &operator+=(difference_type i)                  //[t82]
00514         { m_col+=i; return *this; }
00515     const_fielditerator &operator-=(difference_type i)                  //[t82]
00516         { m_col-=i; return *this; }
00517 
00518     bool operator==(const const_fielditerator &i) const                 //[t82]
00519         {return col()==i.col();}
00520     bool operator!=(const const_fielditerator &i) const                 //[t82]
00521         {return col()!=i.col();}
00522     bool operator<(const const_fielditerator &i) const                  //[t82]
00523         {return col()<i.col();}
00524     bool operator<=(const const_fielditerator &i) const                 //[t82]
00525         {return col()<=i.col();}
00526     bool operator>(const const_fielditerator &i) const                  //[t82]
00527         {return col()>i.col();}
00528     bool operator>=(const const_fielditerator &i) const                 //[t82]
00529         {return col()>=i.col();}
00530 
00531     inline const_fielditerator operator+(difference_type) const;        //[t82]
00532 
00533     friend const_fielditerator operator+(difference_type,
00534                                           const_fielditerator);         //[t82]
00535 
00536     inline const_fielditerator operator-(difference_type) const;        //[t82]
00537     inline difference_type operator-(const_fielditerator) const;        //[t82]
00538   };
00539 
00540   class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00541   {
00542   public:
00543     typedef const_fielditerator iterator_type;
00544     using iterator_type::iterator_category;
00545     using iterator_type::difference_type;
00546     using iterator_type::pointer;
00547 #ifndef _MSC_VER
00548     using iterator_type::value_type;
00549     using iterator_type::reference;
00550 #else
00551     // Workaround for Visual C++.NET 2003, which has access problems
00552     typedef field value_type;
00553     typedef const field &reference;
00554 #endif
00555 
00556     iterator_type base() const throw () { return *this; }               //[t82]
00557     const_reverse_fielditerator(const const_reverse_fielditerator &rhs) //[t82]
00558       : const_fielditerator(rhs), m_tmp(rhs.m_tmp) {}
00559     explicit
00560       const_reverse_fielditerator(const const_fielditerator &rhs) :     //[t82]
00561       const_fielditerator(rhs), m_tmp(rhs) {}
00562 
00563     const_reverse_fielditerator &
00564       operator=(const const_reverse_fielditerator &r)                   //[t82]
00565         { iterator_type::operator=(r); return *this; }
00566     pointer operator->() const throw ()                                 //[t82]
00567         { m_tmp = *this; --m_tmp; return &m_tmp; }
00568     reference operator*() const throw () { return *operator->(); }      //[t82]
00569     const_reverse_fielditerator operator++()                            //[t82]
00570         { iterator_type::operator--(); return *this; }
00571     const_reverse_fielditerator operator++(int);                        //[t82]
00572     const_reverse_fielditerator &operator--()                           //[t82]
00573         { iterator_type::operator++(); return *this; }
00574     const_reverse_fielditerator operator--(int);                        //[t82]
00575     const_reverse_fielditerator operator+(difference_type i) const      //[t82]
00576         { return const_reverse_fielditerator(iterator_type(*this)-i); }
00577     const_reverse_fielditerator &operator+=(difference_type i)          //[t82]
00578         { iterator_type::operator-=(i); return *this; }
00579     const_reverse_fielditerator operator-(difference_type i)            //[t82]
00580         { return const_reverse_fielditerator(iterator_type(*this)+i); }
00581     const_reverse_fielditerator &operator-=(difference_type i)          //[t82]
00582         { iterator_type::operator+=(i); return *this; }
00583 
00584     bool
00585       operator==(const const_reverse_fielditerator &rhs) const throw () //[t82]
00586         { return iterator_type::operator==(rhs); }
00587     bool
00588       operator!=(const const_reverse_fielditerator &rhs) const throw () //[t82]
00589         { return !operator==(rhs); }
00590 
00591 
00592     bool operator<(const const_reverse_fielditerator &rhs) const        //[t82]
00593         { return iterator_type::operator>(rhs); }
00594     bool operator<=(const const_reverse_fielditerator &rhs) const       //[t82]
00595         { return iterator_type::operator>=(rhs); }
00596     bool operator>(const const_reverse_fielditerator &rhs) const        //[t82]
00597         { return iterator_type::operator<(rhs); }
00598     bool operator>=(const const_reverse_fielditerator &rhs) const       //[t82]
00599         { return iterator_type::operator<=(rhs); }
00600     difference_type
00601       operator-(const const_reverse_fielditerator &rhs) const           //[t82]
00602         { return rhs.base() - base(); }
00603 
00604   private:
00606 
00611     mutable iterator_type m_tmp;
00612   };
00613 
00614 
00615   result() throw () : super() {}                                        //[t3]
00616   result(const result &rhs) throw () : super(rhs) {}                    //[t1]
00617 
00618   result &operator=(const result &rhs) throw ()                         //[t10]
00619         { super::operator=(rhs); return *this; }
00620 
00621   bool operator==(const result &) const throw ();                       //[t70]
00622   bool operator!=(const result &rhs) const throw ()                     //[t70]
00623         { return !operator==(rhs); }
00624 
00625   const_reverse_iterator rbegin() const                                 //[t75]
00626         { return const_reverse_iterator(end()); }
00627   const_reverse_iterator rend() const                                   //[t75]
00628         { return const_reverse_iterator(begin()); }
00629 
00630   const_iterator begin() const throw ()                                 //[t1]
00631         { return const_iterator(this, 0); }
00632   inline const_iterator end() const throw ();                           //[t1]
00633 
00634   reference front() const throw () { return tuple(this,0); }            //[t74]
00635   reference back() const throw () {return tuple(this,size()-1);}        //[t75]
00636 
00637   size_type size() const throw ();                                      //[t2]
00638   bool empty() const throw ();                                          //[t11]
00639   size_type capacity() const throw () { return size(); }                //[t20]
00640 
00641   void swap(result &) throw ();                                         //[t77]
00642 
00643   const tuple operator[](size_type i) const throw ()                    //[t2]
00644         { return tuple(this, i); }
00645   const tuple at(size_type) const throw (PGSTD::out_of_range);          //[t10]
00646 
00647   using super::clear;                                                   //[t20]
00648 
00650   tuple::size_type columns() const throw ();                            //[t11]
00651 
00653   tuple::size_type column_number(const char ColName[]) const;           //[t11]
00654 
00656   tuple::size_type column_number(const PGSTD::string &Name) const       //[t11]
00657         {return column_number(Name.c_str());}
00658 
00660   const char *column_name(tuple::size_type Number) const;               //[t11]
00661 
00663   oid column_type(tuple::size_type ColNum) const;                       //[t7]
00665   oid column_type(int ColNum) const                                     //[t7]
00666         { return column_type(tuple::size_type(ColNum)); }
00667 
00669   oid column_type(const PGSTD::string &ColName) const                   //[t7]
00670         { return column_type(column_number(ColName)); }
00671 
00673   oid column_type(const char ColName[]) const                           //[t7]
00674         { return column_type(column_number(ColName)); }
00675 
00677 
00684   oid column_table(tuple::size_type ColNum) const;                      //[t2]
00685 
00687 
00694   oid column_table(int ColNum) const                                    //[t2]
00695         { return column_table(tuple::size_type(ColNum)); }
00696 
00698 
00705   oid column_table(const PGSTD::string &ColName) const                  //[t2]
00706         { return column_table(column_number(ColName)); }
00707 
00709 
00712   oid inserted_oid() const;                                             //[t13]
00713 
00714 
00716 
00719   size_type affected_rows() const;                                      //[t7]
00720 
00721 
00722 #ifdef PQXX_DEPRECATED_HEADERS
00723 
00724   typedef tuple Tuple;
00726   typedef field Field;
00728   oid InsertedOid() const { return inserted_oid(); }
00730   size_type AffectedRows() const { return affected_rows(); }
00732   tuple::size_type Columns() const { return columns(); }
00734   tuple::size_type ColumnNumber(const char Name[]) const
00735         {return column_number(Name);}
00737   tuple::size_type ColumnNumber(const PGSTD::string &Name) const
00738         {return column_number(Name);}
00740   const char *ColumnName(tuple::size_type Number) const
00741         {return column_name(Number);}
00742 #endif
00743 
00744 
00745 private:
00746   friend class pqxx::result::field;
00747   const char *GetValue(size_type Row, tuple::size_type Col) const;
00748   bool GetIsNull(size_type Row, tuple::size_type Col) const;
00749   field::size_type GetLength(size_type Row, tuple::size_type Col) const;
00750 
00751   friend class connection_base;
00752   friend class pipeline;
00753   explicit result(internal::pq::PGresult *rhs) throw () : super(rhs) {}
00754   result &operator=(internal::pq::PGresult *rhs) throw ()
00755         { super::operator=(rhs); return *this; }
00756   bool operator!() const throw () { return !c_ptr(); }
00757   operator bool() const throw () { return c_ptr() != 0; }
00758   void CheckStatus(const PGSTD::string &Query) const;
00759   void CheckStatus(const char Query[]) const;
00760   int errorposition() const throw ();
00761   PGSTD::string StatusError() const;
00762 
00763   friend class Cursor;
00764   const char *CmdStatus() const throw ();
00765 };
00766 
00767 
00769 
00788 template<typename STREAM>
00789 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)      //[t46]
00790 {
00791   S.write(F.c_str(), F.size());
00792   return S;
00793 }
00794 
00795 
00797 template<typename T>
00798 inline void from_string(const result::field &F, T &Obj)                 //[t46]
00799         { from_string(F.c_str(), Obj); }
00800 
00802 template<>
00803 inline PGSTD::string to_string(const result::field &Obj)                //[t74]
00804         { return to_string(Obj.c_str()); }
00805 
00806 
00808 template<>
00809 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00810 {
00811   if (is_null()) return false;
00812   Obj = c_str();
00813   return true;
00814 }
00815 
00817 
00822 template<>
00823 inline bool result::field::to<const char *>(const char *&Obj) const
00824 {
00825   if (is_null()) return false;
00826   Obj = c_str();
00827   return true;
00828 }
00829 
00830 
00831 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00832         { return const_reverse_fielditerator(end()); }
00833 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00834         { return const_reverse_fielditerator(begin()); }
00835 
00836 inline result::const_iterator
00837 result::const_iterator::operator+(difference_type o) const
00838         { return const_iterator(m_Home, m_Index + o); }
00839 
00840 inline result::const_iterator
00841 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00842         { return i + o; }
00843 
00844 inline result::const_iterator
00845 result::const_iterator::operator-(difference_type o) const
00846         { return const_iterator(m_Home, m_Index - o); }
00847 
00848 inline result::const_iterator::difference_type
00849 result::const_iterator::operator-(const_iterator i) const
00850         { return num()-i.num(); }
00851 
00852 inline result::const_iterator result::end() const throw ()
00853         { return const_iterator(this, size()); }
00854 
00855 
00856 inline result::const_reverse_iterator
00857 operator+(result::const_reverse_iterator::difference_type n,
00858           const result::const_reverse_iterator &i)
00859         { return result::const_reverse_iterator(i.base() - n); }
00860 
00861 inline result::const_fielditerator
00862 result::const_fielditerator::operator+(difference_type o) const
00863         { return const_fielditerator(m_tup, col() + o); }
00864 
00865 inline result::const_fielditerator
00866 operator+(result::const_fielditerator::difference_type o,
00867           result::const_fielditerator i)
00868         { return i + o; }
00869 
00870 inline result::const_fielditerator
00871 result::const_fielditerator::operator-(difference_type o) const
00872         { return const_fielditerator(m_tup, col() - o); }
00873 
00874 inline result::const_fielditerator::difference_type
00875 result::const_fielditerator::operator-(const_fielditerator i) const
00876         { return num()-i.num(); }
00877 
00878 
00879 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00880   class field_streambuf :
00881 #ifdef PQXX_HAVE_STREAMBUF
00882   public PGSTD::basic_streambuf<CHAR, TRAITS>
00883 #else
00884   public PGSTD::streambuf
00885 #endif
00886 {
00887 public:
00888   typedef CHAR char_type;
00889   typedef TRAITS traits_type;
00890   typedef typename traits_type::int_type int_type;
00891 #ifdef PQXX_HAVE_STREAMBUF
00892   typedef typename traits_type::pos_type pos_type;
00893   typedef typename traits_type::off_type off_type;
00894 #else
00895   typedef streamoff off_type;
00896   typedef streampos pos_type;
00897 #endif
00898   typedef PGSTD::ios::openmode openmode;
00899   typedef PGSTD::ios::seekdir seekdir;
00900 
00901   explicit field_streambuf(const result::field &F) :                    //[t74]
00902     m_Field(F)
00903   {
00904     initialize();
00905   }
00906 
00907 #ifdef PQXX_HAVE_STREAMBUF
00908 protected:
00909 #endif
00910   virtual int sync() { return traits_type::eof(); }
00911 
00912 protected:
00913   virtual pos_type seekoff(off_type, seekdir, openmode)
00914         { return traits_type::eof(); }
00915   virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
00916   virtual int_type overflow(int_type) { return traits_type::eof(); }
00917   virtual int_type underflow() { return traits_type::eof(); }
00918 
00919 private:
00920   const result::field &m_Field;
00921 
00922   int_type initialize()
00923   {
00924     char_type *G =
00925       reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
00926     setg(G, G, G + m_Field.size());
00927     return m_Field.size();
00928   }
00929 };
00930 
00931 
00933 
00941 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00942   class basic_fieldstream :
00943 #ifdef PQXX_HAVE_STREAMBUF
00944     public PGSTD::basic_istream<CHAR, TRAITS>
00945 #else
00946     public PGSTD::istream
00947 #endif
00948 {
00949 #ifdef PQXX_HAVE_STREAMBUF
00950   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00951 #else
00952   typedef PGSTD::istream super;
00953 #endif
00954 
00955 public:
00956   typedef CHAR char_type;
00957   typedef TRAITS traits_type;
00958   typedef typename traits_type::int_type int_type;
00959   typedef typename traits_type::pos_type pos_type;
00960   typedef typename traits_type::off_type off_type;
00961 
00962   basic_fieldstream(const result::field &F) : super(&m_Buf), m_Buf(F) { }
00963 
00964 private:
00965   field_streambuf<CHAR, TRAITS> m_Buf;
00966 };
00967 
00968 typedef basic_fieldstream<char> fieldstream;
00969 
00970 } // namespace pqxx
00971 
00972 
00973 
00974 /*
00975 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
00976 Effective C++", points out that it is good style to have any class containing
00977 a member of pointer type define a destructor--just to show that it knows what it
00978 is doing with the pointer.  This helps prevent nasty memory leak / double
00979 deletion bugs typically resulting from programmers' omission to deal with such
00980 issues in their destructors.
00981 
00982 The -Weffc++ option in gcc generates warnings for noncompliance with Scott's
00983 style guidelines, and hence necessitates the definition of this destructor,
00984 trivial as it may be.
00985 */
00986 
00987 

Generated on Sat Mar 19 18:42:42 2005 for libpqxx by  doxygen 1.4.1