libpqxx 4.0
|
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-2011, 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 #ifdef PQXX_HAVE_IOS 00026 #include <ios> 00027 #endif 00028 00029 #include <stdexcept> 00030 00031 #include "pqxx/internal/result_data.hxx" 00032 00033 #include "pqxx/except" 00034 #include "pqxx/field" 00035 #include "pqxx/tuple" 00036 #include "pqxx/util" 00037 00038 /* Methods tested in eg. self-test program test001 are marked with "//[t1]" 00039 */ 00040 00041 // TODO: Support SQL arrays 00042 00043 namespace pqxx 00044 { 00045 namespace internal 00046 { 00047 namespace gate 00048 { 00049 class result_connection; 00050 class result_creation; 00051 class result_sql_cursor; 00052 } // namespace internal::gate 00053 } // namespace internal 00054 00055 00056 class const_result_iterator; 00057 class const_reverse_result_iterator; 00058 00059 00061 00081 class PQXX_LIBEXPORT result : 00082 private internal::PQAlloc< 00083 const internal::result_data, internal::freemem_result_data> 00084 { 00085 typedef internal::PQAlloc< 00086 const internal::result_data, internal::freemem_result_data> super; 00087 public: 00088 typedef unsigned long size_type; 00089 typedef signed long difference_type; 00090 typedef tuple reference; 00091 typedef const_result_iterator const_iterator; 00092 typedef const_iterator pointer; 00093 typedef const_iterator iterator; 00094 typedef const_reverse_result_iterator const_reverse_iterator; 00095 typedef const_reverse_iterator reverse_iterator; 00096 00097 result() throw () : super(), m_data(0) {} //[t3] 00098 result(const result &rhs) throw () : //[t1] 00099 super(rhs), m_data(rhs.m_data) {} 00100 00101 result &operator=(const result &rhs) throw () //[t10] 00102 { super::operator=(rhs); m_data=rhs.m_data; return *this; } 00103 00108 bool operator==(const result &) const throw (); //[t70] 00109 bool operator!=(const result &rhs) const throw () //[t70] 00110 { return !operator==(rhs); } 00112 00113 const_reverse_iterator rbegin() const; //[t75] 00114 const_reverse_iterator rend() const; //[t75] 00115 00116 const_iterator begin() const throw (); //[t1] 00117 inline const_iterator end() const throw (); //[t1] 00118 00119 reference front() const throw () { return tuple(this,0); } //[t74] 00120 reference back() const throw () {return tuple(this,size()-1);} //[t75] 00121 00122 size_type PQXX_PURE size() const throw (); //[t2] 00123 bool PQXX_PURE empty() const throw (); //[t11] 00124 size_type capacity() const throw () { return size(); } //[t20] 00125 00126 void swap(result &) throw (); //[t77] 00127 00128 const tuple operator[](size_type i) const throw () //[t2] 00129 { return tuple(this, i); } 00130 const tuple at(size_type) const throw (range_error); //[t10] 00131 00132 void clear() throw () { super::reset(); m_data = 0; } //[t20] 00133 00138 00139 tuple::size_type PQXX_PURE columns() const throw (); //[t11] 00140 00142 tuple::size_type column_number(const char ColName[]) const; //[t11] 00143 00145 tuple::size_type column_number(const PGSTD::string &Name) const //[t11] 00146 {return column_number(Name.c_str());} 00147 00149 const char *column_name(tuple::size_type Number) const; //[t11] 00150 00152 oid column_type(tuple::size_type ColNum) const; //[t7] 00154 oid column_type(int ColNum) const //[t7] 00155 { return column_type(tuple::size_type(ColNum)); } 00156 00158 oid column_type(const PGSTD::string &ColName) const //[t7] 00159 { return column_type(column_number(ColName)); } 00160 00162 oid column_type(const char ColName[]) const //[t7] 00163 { return column_type(column_number(ColName)); } 00164 00166 oid column_table(tuple::size_type ColNum) const; //[t2] 00167 00169 oid column_table(int ColNum) const //[t2] 00170 { return column_table(tuple::size_type(ColNum)); } 00171 00173 oid column_table(const PGSTD::string &ColName) const //[t2] 00174 { return column_table(column_number(ColName)); } 00175 00177 tuple::size_type table_column(tuple::size_type ColNum) const; //[t93] 00178 00180 tuple::size_type table_column(int ColNum) const //[t93] 00181 { return table_column(tuple::size_type(ColNum)); } 00182 00184 tuple::size_type table_column(const PGSTD::string &ColName) const //[t93] 00185 { return table_column(column_number(ColName)); } 00187 00189 const PGSTD::string & PQXX_PURE query() const throw (); //[t70] 00190 00192 00195 oid PQXX_PURE inserted_oid() const; //[t13] 00196 00198 00201 size_type PQXX_PURE affected_rows() const; //[t7] 00202 00203 00204 private: 00205 friend class pqxx::field; 00206 const char * PQXX_PURE GetValue(size_type Row, tuple::size_type Col) const; 00207 bool PQXX_PURE GetIsNull(size_type Row, tuple::size_type Col) const; 00208 field::size_type PQXX_PURE GetLength( 00209 size_type, 00210 tuple::size_type) const throw (); 00211 00212 friend class pqxx::internal::gate::result_creation; 00213 result(internal::pq::PGresult *rhs, 00214 int protocol, 00215 const PGSTD::string &Query, 00216 int encoding_code); 00217 void PQXX_PRIVATE CheckStatus() const; 00218 00219 friend class pqxx::internal::gate::result_connection; 00220 bool operator!() const throw () { return !m_data; } 00221 operator bool() const throw () { return m_data != 0; } 00222 00223 void PQXX_PRIVATE PQXX_NORETURN ThrowSQLError( 00224 const PGSTD::string &Err, 00225 const PGSTD::string &Query) const; 00226 int PQXX_PRIVATE PQXX_PURE errorposition() const throw (); 00227 PGSTD::string PQXX_PRIVATE StatusError() const; 00228 00229 friend class pqxx::internal::gate::result_sql_cursor; 00230 const char * PQXX_PURE CmdStatus() const throw (); 00231 00233 pqxx::internal::pq::PGresult *m_data; 00234 00235 static const PGSTD::string PQXX_PRIVATE s_empty_string; 00236 }; 00237 00238 00240 00244 class PQXX_LIBEXPORT const_result_iterator : 00245 public PGSTD::iterator< 00246 PGSTD::random_access_iterator_tag, 00247 const tuple, 00248 result::difference_type, 00249 const_result_iterator, 00250 tuple>, 00251 public tuple 00252 { 00253 public: 00254 typedef const tuple *pointer; 00255 typedef tuple reference; 00256 typedef result::size_type size_type; 00257 typedef result::difference_type difference_type; 00258 00259 const_result_iterator() throw () : tuple(0,0) {} 00260 const_result_iterator(const tuple &t) throw () : tuple(t) {} 00261 00277 pointer operator->() const { return this; } //[t12] 00278 reference operator*() const { return tuple(*this); } //[t12] 00280 00285 const_result_iterator operator++(int); //[t12] 00286 const_result_iterator &operator++() { ++m_Index; return *this; } //[t1] 00287 const_result_iterator operator--(int); //[t12] 00288 const_result_iterator &operator--() { --m_Index; return *this; } //[t12] 00289 00290 const_result_iterator &operator+=(difference_type i) //[t12] 00291 { m_Index = size_type(difference_type(m_Index) + i); return *this; } 00292 const_result_iterator &operator-=(difference_type i) //[t12] 00293 { m_Index = size_type(difference_type (m_Index) - i); return *this; } 00295 00300 bool operator==(const const_result_iterator &i) const //[t12] 00301 {return m_Index==i.m_Index;} 00302 bool operator!=(const const_result_iterator &i) const //[t12] 00303 {return m_Index!=i.m_Index;} 00304 bool operator<(const const_result_iterator &i) const //[t12] 00305 {return m_Index<i.m_Index;} 00306 bool operator<=(const const_result_iterator &i) const //[t12] 00307 {return m_Index<=i.m_Index;} 00308 bool operator>(const const_result_iterator &i) const //[t12] 00309 {return m_Index>i.m_Index;} 00310 bool operator>=(const const_result_iterator &i) const //[t12] 00311 {return m_Index>=i.m_Index;} 00313 00318 inline const_result_iterator operator+(difference_type) const; //[t12] 00319 friend const_result_iterator operator+( //[t12] 00320 difference_type, 00321 const_result_iterator); 00322 inline const_result_iterator operator-(difference_type) const; //[t12] 00323 inline difference_type operator-(const_result_iterator) const; //[t12] 00325 00326 private: 00327 friend class pqxx::result; 00328 const_result_iterator(const pqxx::result *r, result::size_type i) throw () : 00329 tuple(r, i) {} 00330 }; 00331 00332 00334 class PQXX_LIBEXPORT const_reverse_result_iterator : 00335 private const_result_iterator 00336 { 00337 public: 00338 typedef const_result_iterator super; 00339 typedef const_result_iterator iterator_type; 00340 using iterator_type::iterator_category; 00341 using iterator_type::difference_type; 00342 using iterator_type::pointer; 00343 #ifndef _MSC_VER 00344 using iterator_type::value_type; 00345 using iterator_type::reference; 00346 #else 00347 // Workaround for Visual C++.NET 2003, which has access problems 00348 typedef const tuple &reference; 00349 typedef tuple value_type; 00350 #endif 00351 00352 const_reverse_result_iterator( //[t75] 00353 const const_reverse_result_iterator &rhs) : 00354 const_result_iterator(rhs) {} 00355 explicit const_reverse_result_iterator( //[t75] 00356 const const_result_iterator &rhs) : 00357 const_result_iterator(rhs) { super::operator--(); } 00358 00359 const_result_iterator PQXX_PURE base() const throw (); //[t75] 00360 00365 using const_result_iterator::operator->; //[t75] 00366 using const_result_iterator::operator*; //[t75] 00368 00373 const_reverse_result_iterator &operator=( //[t75] 00374 const const_reverse_result_iterator &r) 00375 { iterator_type::operator=(r); return *this; } 00376 const_reverse_result_iterator operator++() //[t75] 00377 { iterator_type::operator--(); return *this; } 00378 const_reverse_result_iterator operator++(int); //[t75] 00379 const_reverse_result_iterator &operator--() //[t75] 00380 { iterator_type::operator++(); return *this; } 00381 const_reverse_result_iterator operator--(int); //[t75] 00382 const_reverse_result_iterator &operator+=(difference_type i) //[t75] 00383 { iterator_type::operator-=(i); return *this; } 00384 const_reverse_result_iterator &operator-=(difference_type i) //[t75] 00385 { iterator_type::operator+=(i); return *this; } 00387 00392 const_reverse_result_iterator operator+(difference_type i) const //[t75] 00393 { return const_reverse_result_iterator(base() - i); } 00394 const_reverse_result_iterator operator-(difference_type i) //[t75] 00395 { return const_reverse_result_iterator(base() + i); } 00396 difference_type operator-( //[t75] 00397 const const_reverse_result_iterator &rhs) const 00398 { return rhs.const_result_iterator::operator-(*this); } 00400 00405 bool operator==( //[t75] 00406 const const_reverse_result_iterator &rhs) const throw () 00407 { return iterator_type::operator==(rhs); } 00408 bool operator!=( //[t75] 00409 const const_reverse_result_iterator &rhs) const throw () 00410 { return !operator==(rhs); } 00411 00412 bool operator<(const const_reverse_result_iterator &rhs) const //[t75] 00413 { return iterator_type::operator>(rhs); } 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); } 00421 }; 00422 00423 00424 00426 00446 template<typename CHAR> 00447 inline PGSTD::basic_ostream<CHAR> &operator<<( 00448 PGSTD::basic_ostream<CHAR> &S, const pqxx::field &F) //[t46] 00449 { 00450 S.write(F.c_str(), PGSTD::streamsize(F.size())); 00451 return S; 00452 } 00453 00454 00456 template<typename T> 00457 inline void from_string(const field &F, T &Obj) //[t46] 00458 { from_string(F.c_str(), Obj, F.size()); } 00459 00461 template<> 00462 inline PGSTD::string to_string(const field &Obj) //[t74] 00463 { return PGSTD::string(Obj.c_str(), Obj.size()); } 00464 00465 00466 inline const_result_iterator 00467 const_result_iterator::operator+(result::difference_type o) const 00468 { 00469 return const_result_iterator( 00470 m_Home, size_type(result::difference_type(m_Index) + o)); 00471 } 00472 00473 inline const_result_iterator 00474 operator+(result::difference_type o, const_result_iterator i) 00475 { return i + o; } 00476 00477 inline const_result_iterator 00478 const_result_iterator::operator-(result::difference_type o) const 00479 { 00480 return const_result_iterator( 00481 m_Home, 00482 result::size_type(result::difference_type(m_Index) - o)); 00483 } 00484 00485 inline result::difference_type 00486 const_result_iterator::operator-(const_result_iterator i) const 00487 { return result::difference_type(num() - i.num()); } 00488 00489 inline const_result_iterator result::end() const throw () 00490 { return const_result_iterator(this, size()); } 00491 00492 00493 inline const_reverse_result_iterator 00494 operator+(result::difference_type n, 00495 const const_reverse_result_iterator &i) 00496 { return const_reverse_result_iterator(i.base() - n); } 00497 00498 } // namespace pqxx 00499 00500 00501 #include "pqxx/compiler-internal-post.hxx" 00502 00503 #endif