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)  //[]
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)                   //[]
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         { return c_ptr() ? PQXXPQ::PQntuples(c_ptr()) : 0; }
00639   bool empty() const                                                    //[t11]
00640         { return !c_ptr() || !PQXXPQ::PQntuples(c_ptr()); }
00641   size_type capacity() const throw () { return size(); }                //[t20]
00642 
00643   void swap(result &) throw ();                                         //[t77]
00644 
00645   const tuple operator[](size_type i) const throw ()                    //[t2]
00646         { return tuple(this, i); }
00647   const tuple at(size_type) const throw (PGSTD::out_of_range);          //[t10]
00648 
00649   using super::clear;                                                   //[t20]
00650 
00652   tuple::size_type columns() const throw ()                             //[t11]
00653         { return PQnfields(c_ptr()); }
00654 
00656   tuple::size_type column_number(const char ColName[]) const;           //[t11]
00657 
00659   tuple::size_type column_number(const PGSTD::string &Name) const       //[t11]
00660         {return column_number(Name.c_str());}
00661 
00663   const char *column_name(tuple::size_type Number) const;               //[t11]
00664 
00666   oid column_type(tuple::size_type ColNum) const;                       //[t7]
00668   oid column_type(int ColNum) const                                     //[t7]
00669         { return column_type(tuple::size_type(ColNum)); }
00670 
00672   oid column_type(const PGSTD::string &ColName) const                   //[t7]
00673         { return column_type(column_number(ColName)); }
00674 
00676   oid column_type(const char ColName[]) const                           //[t7]
00677         { return column_type(column_number(ColName)); }
00678 
00680 
00687   oid column_table(tuple::size_type ColNum) const;                      //[t2]
00688 
00690 
00697   oid column_table(int ColNum) const                                    //[t2]
00698         { return column_table(tuple::size_type(ColNum)); }
00699 
00701 
00708   oid column_table(const PGSTD::string &ColName) const                  //[t2]
00709         { return column_table(column_number(ColName)); }
00710 
00712 
00715   oid inserted_oid() const { return PQoidValue(c_ptr()); }              //[t13]
00716 
00717 
00719 
00722   size_type affected_rows() const;                                      //[t7]
00723 
00724 
00725 #ifdef PQXX_DEPRECATED_HEADERS
00726 
00727   typedef tuple Tuple;
00729   typedef field Field;
00731   oid InsertedOid() const { return inserted_oid(); }
00733   size_type AffectedRows() const { return affected_rows(); }
00735   tuple::size_type Columns() const { return columns(); }
00737   tuple::size_type ColumnNumber(const char Name[]) const
00738         {return PQfnumber(c_ptr(),Name);}
00740   tuple::size_type ColumnNumber(const PGSTD::string &Name) const
00741         {return ColumnNumber(Name.c_str());}
00743   const char *ColumnName(tuple::size_type Number) const
00744         {return PQfname(c_ptr(),Number);}
00745 #endif
00746 
00747 
00748 private:
00749   friend class pqxx::result::field;
00750   const char *GetValue(size_type Row, tuple::size_type Col) const;
00751   bool GetIsNull(size_type Row, tuple::size_type Col) const;
00752   field::size_type GetLength(size_type Row, tuple::size_type Col) const;
00753 
00754   friend class connection_base;
00755   friend class pipeline;
00756   explicit result(PQXXPQ::PGresult *rhs) throw () : super(rhs) {}
00757   result &operator=(PQXXPQ::PGresult *rhs) throw ()
00758         { super::operator=(rhs); return *this; }
00759   bool operator!() const throw () { return !c_ptr(); }
00760   operator bool() const throw () { return c_ptr() != 0; }
00761   void CheckStatus(const PGSTD::string &Query) const;
00762   void CheckStatus(const char Query[]) const;
00763   int errorposition() const throw ();
00764   PGSTD::string StatusError() const;
00765 
00766   friend class Cursor;
00767   const char *CmdStatus() const throw () { return PQcmdStatus(c_ptr()); }
00768 };
00769 
00770 
00772 
00791 template<typename STREAM>
00792 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)      //[t46]
00793 {
00794   S.write(F.c_str(), F.size());
00795   return S;
00796 }
00797 
00798 
00800 template<typename T>
00801 inline void from_string(const result::field &F, T &Obj)                 //[t46]
00802         { from_string(F.c_str(), Obj); }
00803 
00805 template<>
00806 inline PGSTD::string to_string(const result::field &Obj)                //[t74]
00807         { return to_string(Obj.c_str()); }
00808 
00809 
00811 template<>
00812 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00813 {
00814   if (is_null()) return false;
00815   Obj = c_str();
00816   return true;
00817 }
00818 
00820 
00825 template<>
00826 inline bool result::field::to<const char *>(const char *&Obj) const
00827 {
00828   if (is_null()) return false;
00829   Obj = c_str();
00830   return true;
00831 }
00832 
00833 
00834 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00835         { return const_reverse_fielditerator(end()); }
00836 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00837         { return const_reverse_fielditerator(begin()); }
00838 
00839 inline result::const_iterator
00840 result::const_iterator::operator+(difference_type o) const
00841         { return const_iterator(m_Home, m_Index + o); }
00842 
00843 inline result::const_iterator
00844 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00845         { return i + o; }
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::difference_type
00852 result::const_iterator::operator-(const_iterator i) const
00853         { return num()-i.num(); }
00854 
00855 inline result::const_iterator result::end() const throw ()
00856         { return const_iterator(this, size()); }
00857 
00858 
00859 inline result::const_reverse_iterator
00860 operator+(result::const_reverse_iterator::difference_type n,
00861           const result::const_reverse_iterator &i)
00862         { return result::const_reverse_iterator(i.base() - n); }
00863 
00864 inline result::const_fielditerator
00865 result::const_fielditerator::operator+(difference_type o) const
00866         { return const_fielditerator(m_tup, col() + o); }
00867 
00868 inline result::const_fielditerator
00869 operator+(result::const_fielditerator::difference_type o,
00870           result::const_fielditerator i)
00871         { return i + o; }
00872 
00873 inline result::const_fielditerator
00874 result::const_fielditerator::operator-(difference_type o) const
00875         { return const_fielditerator(m_tup, col() - o); }
00876 
00877 inline result::const_fielditerator::difference_type
00878 result::const_fielditerator::operator-(const_fielditerator i) const
00879         { return num()-i.num(); }
00880 
00881 
00882 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00883   class field_streambuf :
00884 #ifdef PQXX_HAVE_STREAMBUF
00885   public PGSTD::basic_streambuf<CHAR, TRAITS>
00886 #else
00887   public PGSTD::streambuf
00888 #endif
00889 {
00890 public:
00891   typedef CHAR char_type;
00892   typedef TRAITS traits_type;
00893   typedef typename traits_type::int_type int_type;
00894 #ifdef PQXX_HAVE_STREAMBUF
00895   typedef typename traits_type::pos_type pos_type;
00896   typedef typename traits_type::off_type off_type;
00897 #else
00898   typedef streamoff off_type;
00899   typedef streampos pos_type;
00900 #endif
00901   typedef PGSTD::ios::openmode openmode;
00902   typedef PGSTD::ios::seekdir seekdir;
00903 
00904   explicit field_streambuf(const result::field &F) :                    //[t74]
00905     m_Field(F)
00906   {
00907     initialize();
00908   }
00909 
00910 #ifdef PQXX_HAVE_STREAMBUF
00911 protected:
00912 #endif
00913   virtual int sync() { return traits_type::eof(); }
00914 
00915 protected:
00916   virtual pos_type seekoff(off_type, seekdir, openmode)
00917         { return traits_type::eof(); }
00918   virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
00919   virtual int_type overflow(int_type) { return traits_type::eof(); }
00920   virtual int_type underflow() { return traits_type::eof(); }
00921 
00922 private:
00923   const result::field &m_Field;
00924 
00925   int_type initialize()
00926   {
00927     char_type *G =
00928       reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
00929     setg(G, G, G + m_Field.size());
00930     return m_Field.size();
00931   }
00932 };
00933 
00934 
00936 
00944 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00945   class basic_fieldstream :
00946 #ifdef PQXX_HAVE_STREAMBUF
00947     public PGSTD::basic_istream<CHAR, TRAITS>
00948 #else
00949     public PGSTD::istream
00950 #endif
00951 {
00952 #ifdef PQXX_HAVE_STREAMBUF
00953   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00954 #else
00955   typedef PGSTD::istream super;
00956 #endif
00957 
00958 public:
00959   typedef CHAR char_type;
00960   typedef TRAITS traits_type;
00961   typedef typename traits_type::int_type int_type;
00962   typedef typename traits_type::pos_type pos_type;
00963   typedef typename traits_type::off_type off_type;
00964 
00965   basic_fieldstream(const result::field &F) : super(&m_Buf), m_Buf(F) { }
00966 
00967 private:
00968   field_streambuf<CHAR, TRAITS> m_Buf;
00969 };
00970 
00971 typedef basic_fieldstream<char> fieldstream;
00972 
00973 } // namespace pqxx
00974 
00975 
00976 
00977 /*
00978 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More
00979 Effective C++", points out that it is good style to have any class containing
00980 a member of pointer type define a destructor--just to show that it knows what it
00981 is doing with the pointer.  This helps prevent nasty memory leak / double
00982 deletion bugs typically resulting from programmers' omission to deal with such
00983 issues in their destructors.
00984 
00985 The -Weffc++ option in gcc generates warnings for noncompliance with Scott's
00986 style guidelines, and hence necessitates the definition of this destructor,
00987 trivial as it may be.
00988 */
00989 
00990 

Generated on Mon Feb 28 10:24:56 2005 for libpqxx by  doxygen 1.4.1