result.hxx

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 rows from a database query
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
00010  *
00011  * Copyright (c) 2001-2016, 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 #ifndef PQXX_H_RESULT
00020 #define PQXX_H_RESULT
00021 
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024 
00025 #include <ios>
00026 #include <stdexcept>
00027 
00028 #include "pqxx/internal/result_data.hxx"
00029 
00030 #include "pqxx/except"
00031 #include "pqxx/field"
00032 #include "pqxx/row"
00033 #include "pqxx/util"
00034 
00035 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
00036  */
00037 
00038 // TODO: Support SQL arrays
00039 
00040 namespace pqxx
00041 {
00042 namespace internal
00043 {
00044 namespace gate
00045 {
00046 class result_connection;
00047 class result_creation;
00048 class result_sql_cursor;
00049 } // namespace internal::gate
00050 } // namespace internal
00051 
00052 
00053 class const_result_iterator;
00054 class const_reverse_result_iterator;
00055 
00056 
00058 
00078 class PQXX_LIBEXPORT result :
00079   private internal::PQAlloc<
00080         const internal::result_data, internal::freemem_result_data>
00081 {
00082   typedef internal::PQAlloc<
00083         const internal::result_data, internal::freemem_result_data> super;
00084 public:
00085   typedef unsigned long size_type;
00086   typedef signed long difference_type;
00087   typedef row reference;
00088   typedef const_result_iterator const_iterator;
00089   typedef const_iterator pointer;
00090   typedef const_iterator iterator;
00091   typedef const_reverse_result_iterator const_reverse_iterator;
00092   typedef const_reverse_iterator reverse_iterator;
00093 
00094   result() PQXX_NOEXCEPT : super(), m_data(0) {}                                //[t3]
00095   result(const result &rhs) PQXX_NOEXCEPT :                                     //[t1]
00096         super(rhs), m_data(rhs.m_data) {}
00097 
00098   result &operator=(const result &rhs) PQXX_NOEXCEPT                            //[t10]
00099         { super::operator=(rhs); m_data=rhs.m_data; return *this; }
00100 
00105   bool operator==(const result &) const PQXX_NOEXCEPT;                  //[t70]
00106   bool operator!=(const result &rhs) const PQXX_NOEXCEPT                //[t70]
00107         { return !operator==(rhs); }
00109 
00110   const_reverse_iterator rbegin() const;                                //[t75]
00111   const_reverse_iterator crbegin() const;
00112   const_reverse_iterator rend() const;                                  //[t75]
00113   const_reverse_iterator crend() const;
00114 
00115   const_iterator begin() const PQXX_NOEXCEPT;                           //[t1]
00116   const_iterator cbegin() const PQXX_NOEXCEPT;
00117   inline const_iterator end() const PQXX_NOEXCEPT;                      //[t1]
00118   inline const_iterator cend() const PQXX_NOEXCEPT;
00119 
00120   reference front() const PQXX_NOEXCEPT { return row(this,0); }         //[t74]
00121   reference back() const PQXX_NOEXCEPT {return row(this,size()-1);}     //[t75]
00122 
00123   PQXX_PURE size_type size() const PQXX_NOEXCEPT;                       //[t2]
00124   PQXX_PURE bool empty() const PQXX_NOEXCEPT;                           //[t11]
00125   size_type capacity() const PQXX_NOEXCEPT { return size(); }           //[t20]
00126 
00127   void swap(result &) PQXX_NOEXCEPT;                                    //[t77]
00128 
00129   const row operator[](size_type i) const PQXX_NOEXCEPT                 //[t2]
00130         { return row(this, i); }
00131   const row at(size_type) const;                                        //[t10]
00132 
00133   void clear() PQXX_NOEXCEPT { super::reset(); m_data = 0; }            //[t20]
00134 
00139 
00140   PQXX_PURE row::size_type columns() const PQXX_NOEXCEPT;               //[t11]
00141 
00143   row::size_type column_number(const char ColName[]) const;             //[t11]
00144 
00146   row::size_type column_number(const std::string &Name) const           //[t11]
00147         {return column_number(Name.c_str());}
00148 
00150   const char *column_name(row::size_type Number) const;                 //[t11]
00151 
00153   oid column_type(row::size_type ColNum) const;                         //[t7]
00155   oid column_type(int ColNum) const                                     //[t7]
00156         { return column_type(row::size_type(ColNum)); }
00157 
00159   oid column_type(const std::string &ColName) const                     //[t7]
00160         { return column_type(column_number(ColName)); }
00161 
00163   oid column_type(const char ColName[]) const                           //[t7]
00164         { return column_type(column_number(ColName)); }
00165 
00167   oid column_table(row::size_type ColNum) const;                        //[t2]
00168 
00170   oid column_table(int ColNum) const                                    //[t2]
00171         { return column_table(row::size_type(ColNum)); }
00172 
00174   oid column_table(const std::string &ColName) const                    //[t2]
00175         { return column_table(column_number(ColName)); }
00176 
00178   row::size_type table_column(row::size_type ColNum) const;             //[t93]
00179 
00181   row::size_type table_column(int ColNum) const                         //[t93]
00182         { return table_column(row::size_type(ColNum)); }
00183 
00185   row::size_type table_column(const std::string &ColName) const         //[t93]
00186         { return table_column(column_number(ColName)); }
00188 
00190   PQXX_PURE const std::string &query() const PQXX_NOEXCEPT;             //[t70]
00191 
00193 
00196   PQXX_PURE oid inserted_oid() const;                                   //[t13]
00197 
00199 
00202   PQXX_PURE size_type affected_rows() const;                            //[t7]
00203 
00204 
00205 private:
00206   friend class pqxx::field;
00207   PQXX_PURE const char *GetValue(size_type Row, row::size_type Col) const;
00208   PQXX_PURE bool GetIsNull(size_type Row, row::size_type Col) const;
00209   PQXX_PURE field::size_type GetLength(
00210         size_type,
00211         row::size_type) const PQXX_NOEXCEPT;
00212 
00213   friend class pqxx::internal::gate::result_creation;
00214   result(internal::pq::PGresult *rhs,
00215         int protocol,
00216         const std::string &Query,
00217         int encoding_code);
00218   PQXX_PRIVATE void CheckStatus() const;
00219 
00220   friend class pqxx::internal::gate::result_connection;
00221   bool operator!() const PQXX_NOEXCEPT { return !m_data; }
00222   operator bool() const PQXX_NOEXCEPT { return m_data != 0; }
00223 
00224   PQXX_NORETURN PQXX_PRIVATE void ThrowSQLError(
00225         const std::string &Err,
00226         const std::string &Query) const;
00227   PQXX_PRIVATE PQXX_PURE int errorposition() const PQXX_NOEXCEPT;
00228   PQXX_PRIVATE std::string StatusError() const;
00229 
00230   friend class pqxx::internal::gate::result_sql_cursor;
00231   PQXX_PURE const char *CmdStatus() const PQXX_NOEXCEPT;
00232 
00234   pqxx::internal::pq::PGresult *m_data;
00235 
00236   PQXX_PRIVATE static const std::string s_empty_string;
00237 };
00238 
00239 
00241 
00245 class PQXX_LIBEXPORT const_result_iterator :
00246   public std::iterator<
00247         std::random_access_iterator_tag,
00248         const row,
00249         result::difference_type,
00250         const_result_iterator,
00251         row>,
00252   public row
00253 {
00254 public:
00255   typedef const row *pointer;
00256   typedef row reference;
00257   typedef result::size_type size_type;
00258   typedef result::difference_type difference_type;
00259 
00260   const_result_iterator() PQXX_NOEXCEPT : row(0,0) {}
00261   const_result_iterator(const row &t) PQXX_NOEXCEPT : row(t) {}
00262 
00278   pointer operator->() const { return this; }                           //[t12]
00279   reference operator*() const { return row(*this); }                    //[t12]
00281 
00286   const_result_iterator operator++(int);                                //[t12]
00287   const_result_iterator &operator++() { ++m_Index; return *this; }      //[t1]
00288   const_result_iterator operator--(int);                                //[t12]
00289   const_result_iterator &operator--() { --m_Index; return *this; }      //[t12]
00290 
00291   const_result_iterator &operator+=(difference_type i)                  //[t12]
00292       { m_Index = size_type(difference_type(m_Index) + i); return *this; }
00293   const_result_iterator &operator-=(difference_type i)                  //[t12]
00294       { m_Index = size_type(difference_type(m_Index) - i); return *this; }
00296 
00301   bool operator==(const const_result_iterator &i) const                 //[t12]
00302       {return m_Index==i.m_Index;}
00303   bool operator!=(const const_result_iterator &i) const                 //[t12]
00304       {return m_Index!=i.m_Index;}
00305   bool operator<(const const_result_iterator &i) const                  //[t12]
00306       {return m_Index<i.m_Index;}
00307   bool operator<=(const const_result_iterator &i) const                 //[t12]
00308       {return m_Index<=i.m_Index;}
00309   bool operator>(const const_result_iterator &i) const                  //[t12]
00310       {return m_Index>i.m_Index;}
00311   bool operator>=(const const_result_iterator &i) const                 //[t12]
00312       {return m_Index>=i.m_Index;}
00314 
00319   inline const_result_iterator operator+(difference_type) const;        //[t12]
00320   friend const_result_iterator operator+(                               //[t12]
00321         difference_type,
00322         const_result_iterator);
00323   inline const_result_iterator operator-(difference_type) const;        //[t12]
00324   inline difference_type operator-(const_result_iterator) const;        //[t12]
00326 
00327 private:
00328   friend class pqxx::result;
00329   const_result_iterator(const pqxx::result *r, result::size_type i)
00330         PQXX_NOEXCEPT :
00331     row(r, i) {}
00332 };
00333 
00334 
00336 class PQXX_LIBEXPORT const_reverse_result_iterator :
00337   private const_result_iterator
00338 {
00339 public:
00340   typedef const_result_iterator super;
00341   typedef const_result_iterator iterator_type;
00342   using iterator_type::iterator_category;
00343   using iterator_type::difference_type;
00344   using iterator_type::pointer;
00345 #ifndef _MSC_VER
00346   using iterator_type::value_type;
00347   using iterator_type::reference;
00348 #else
00349   // Workaround for Visual C++.NET 2003, which has access problems
00350   typedef const row &reference;
00351   typedef row value_type;
00352 #endif
00353 
00354   const_reverse_result_iterator(                                        //[t75]
00355         const const_reverse_result_iterator &rhs) :
00356     const_result_iterator(rhs) {}
00357   explicit const_reverse_result_iterator(                               //[t75]
00358         const const_result_iterator &rhs) :
00359     const_result_iterator(rhs) { super::operator--(); }
00360 
00361   PQXX_PURE const_result_iterator base() const PQXX_NOEXCEPT;           //[t75]
00362 
00367   using const_result_iterator::operator->;                              //[t75]
00368   using const_result_iterator::operator*;                               //[t75]
00370 
00375   const_reverse_result_iterator &operator=(                             //[t75]
00376         const const_reverse_result_iterator &r)
00377       { iterator_type::operator=(r); return *this; }
00378   const_reverse_result_iterator operator++()                            //[t75]
00379       { iterator_type::operator--(); return *this; }
00380   const_reverse_result_iterator operator++(int);                        //[t75]
00381   const_reverse_result_iterator &operator--()                           //[t75]
00382       { iterator_type::operator++(); return *this; }
00383   const_reverse_result_iterator operator--(int);                        //[t75]
00384   const_reverse_result_iterator &operator+=(difference_type i)          //[t75]
00385       { iterator_type::operator-=(i); return *this; }
00386   const_reverse_result_iterator &operator-=(difference_type i)          //[t75]
00387       { iterator_type::operator+=(i); return *this; }
00389 
00394   const_reverse_result_iterator operator+(difference_type i) const      //[t75]
00395       { return const_reverse_result_iterator(base() - i); }
00396   const_reverse_result_iterator operator-(difference_type i)            //[t75]
00397       { return const_reverse_result_iterator(base() + i); }
00398   difference_type operator-(                                            //[t75]
00399         const const_reverse_result_iterator &rhs) const
00400       { return rhs.const_result_iterator::operator-(*this); }
00402 
00407   bool operator==(                                                      //[t75]
00408         const const_reverse_result_iterator &rhs) const PQXX_NOEXCEPT
00409       { return iterator_type::operator==(rhs); }
00410   bool operator!=(                                                      //[t75]
00411         const const_reverse_result_iterator &rhs) const PQXX_NOEXCEPT
00412       { return !operator==(rhs); }
00413 
00414   bool operator<(const const_reverse_result_iterator &rhs) const        //[t75]
00415       { return iterator_type::operator>(rhs); }
00416   bool operator<=(const const_reverse_result_iterator &rhs) const       //[t75]
00417       { return iterator_type::operator>=(rhs); }
00418   bool operator>(const const_reverse_result_iterator &rhs) const        //[t75]
00419       { return iterator_type::operator<(rhs); }
00420   bool operator>=(const const_reverse_result_iterator &rhs) const       //[t75]
00421       { return iterator_type::operator<=(rhs); }
00423 };
00424 
00425 
00426 
00428 
00448 template<typename CHAR>
00449 inline std::basic_ostream<CHAR> &operator<<(
00450         std::basic_ostream<CHAR> &S, const pqxx::field &F)              //[t46]
00451 {
00452   S.write(F.c_str(), std::streamsize(F.size()));
00453   return S;
00454 }
00455 
00456 
00458 template<typename T>
00459 inline void from_string(const field &F, T &Obj)                         //[t46]
00460         { from_string(F.c_str(), Obj, F.size()); }
00461 
00463 template<>
00464 inline std::string to_string(const field &Obj)                          //[t74]
00465         { return std::string(Obj.c_str(), Obj.size()); }
00466 
00467 
00468 inline const_result_iterator
00469 const_result_iterator::operator+(result::difference_type o) const
00470 {
00471   return const_result_iterator(
00472         m_Home, size_type(result::difference_type(m_Index) + o));
00473 }
00474 
00475 inline const_result_iterator
00476 operator+(result::difference_type o, const_result_iterator i)
00477         { return i + o; }
00478 
00479 inline const_result_iterator
00480 const_result_iterator::operator-(result::difference_type o) const
00481 {
00482   return const_result_iterator(
00483         m_Home,
00484         result::size_type(result::difference_type(m_Index) - o));
00485 }
00486 
00487 inline result::difference_type
00488 const_result_iterator::operator-(const_result_iterator i) const
00489         { return result::difference_type(num() - i.num()); }
00490 
00491 inline const_result_iterator result::end() const PQXX_NOEXCEPT
00492         { return const_result_iterator(this, size()); }
00493 
00494 
00495 inline const_result_iterator result::cend() const PQXX_NOEXCEPT
00496         { return end(); }
00497 
00498 
00499 inline const_reverse_result_iterator
00500 operator+(result::difference_type n,
00501           const const_reverse_result_iterator &i)
00502         { return const_reverse_result_iterator(i.base() - n); }
00503 
00504 } // namespace pqxx
00505 
00506 
00507 #include "pqxx/compiler-internal-post.hxx"
00508 
00509 #endif

Generated on 17 Mar 2017 for libpqxx by  doxygen 1.6.1