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/tuple 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_TUPLE 00020 #define PQXX_H_TUPLE 00021 00022 #include "pqxx/compiler-public.hxx" 00023 #include "pqxx/compiler-internal-pre.hxx" 00024 00025 #include "pqxx/except" 00026 #include "pqxx/field" 00027 00028 00029 /* Methods tested in eg. self-test program test001 are marked with "//[t1]" 00030 */ 00031 00032 namespace pqxx 00033 { 00034 class const_tuple_iterator; 00035 class const_reverse_tuple_iterator; 00036 class result; 00037 00038 00040 00051 class PQXX_LIBEXPORT tuple 00052 { 00053 public: 00054 typedef tuple_size_type size_type; 00055 typedef tuple_difference_type difference_type; 00056 typedef const_tuple_iterator const_iterator; 00057 typedef const_iterator iterator; 00058 typedef field reference; 00059 typedef const_tuple_iterator pointer; 00060 typedef const_reverse_tuple_iterator const_reverse_iterator; 00061 typedef const_reverse_iterator reverse_iterator; 00062 00064 tuple(const result *r, size_t i) throw (); 00065 00066 ~tuple() throw () {} // Yes Scott Meyers, you're absolutely right[1] 00067 00072 bool PQXX_PURE operator==(const tuple &) const throw (); //[t75] 00073 bool operator!=(const tuple &rhs) const throw () //[t75] 00074 { return !operator==(rhs); } 00076 00077 const_iterator begin() const throw (); //[t82] 00078 const_iterator end() const throw (); //[t82] 00079 00084 reference front() const throw (); //[t74] 00085 reference back() const throw (); //[t75] 00086 00087 const_reverse_tuple_iterator rbegin() const; //[t82] 00088 const_reverse_tuple_iterator rend() const; //[t82] 00089 00090 reference operator[](size_type) const throw (); //[t11] 00091 reference operator[](int) const throw (); //[t2] 00092 reference operator[](const char[]) const; //[t11] 00093 reference operator[](const PGSTD::string &) const; //[t11] 00094 reference at(size_type) const throw (range_error); //[t11] 00095 reference at(int) const throw (range_error); //[t11] 00096 reference at(const char[]) const; //[t11] 00097 reference at(const PGSTD::string &) const; //[t11] 00099 00100 size_type size() const throw () //[t11] 00101 { return m_End-m_Begin; } 00102 00103 void swap(tuple &) throw (); //[t11] 00104 00105 size_t rownumber() const throw () { return m_Index; } //[t11] 00106 00111 00112 size_type column_number(const PGSTD::string &ColName) const //[t30] 00113 { return column_number(ColName.c_str()); } 00114 00116 size_type column_number(const char[]) const; //[t30] 00117 00119 oid column_type(size_type) const; //[t7] 00120 00122 oid column_type(int ColNum) const //[t7] 00123 { return column_type(size_type(ColNum)); } 00124 00126 oid column_type(const PGSTD::string &ColName) const //[t7] 00127 { return column_type(column_number(ColName)); } 00128 00130 oid column_type(const char ColName[]) const //[t7] 00131 { return column_type(column_number(ColName)); } 00132 00134 oid column_table(size_type ColNum) const; //[t2] 00135 00137 oid column_table(int ColNum) const //[t2] 00138 { return column_table(size_type(ColNum)); } 00140 oid column_table(const PGSTD::string &ColName) const //[t2] 00141 { return column_table(column_number(ColName)); } 00142 00144 00154 size_type table_column(size_type) const; //[t93] 00155 00157 size_type table_column(int ColNum) const //[t93] 00158 { return table_column(size_type(ColNum)); } 00159 00161 size_type table_column(const PGSTD::string &ColName) const //[t93] 00162 { return table_column(column_number(ColName)); } 00164 00165 size_t num() const { return rownumber(); } //[t1] 00166 00179 tuple slice(size_type Begin, size_type End) const; 00180 00181 // Is this an empty slice? 00182 bool PQXX_PURE empty() const throw (); 00183 00184 protected: 00185 friend class field; 00186 const result *m_Home; 00187 size_t m_Index; 00188 size_type m_Begin; 00189 size_type m_End; 00190 00191 private: 00192 // Not allowed: 00193 tuple(); 00194 }; 00195 00196 00198 class PQXX_LIBEXPORT const_tuple_iterator : 00199 public PGSTD::iterator<PGSTD::random_access_iterator_tag, 00200 const field, 00201 tuple::size_type>, 00202 public field 00203 { 00204 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag, 00205 const field, 00206 tuple::size_type> it; 00207 public: 00208 using it::pointer; 00209 typedef tuple::size_type size_type; 00210 typedef tuple::difference_type difference_type; 00211 typedef field reference; 00212 00213 const_tuple_iterator(const tuple &T, tuple::size_type C) throw () : //[t82] 00214 field(T, C) {} 00215 const_tuple_iterator(const field &F) throw () : field(F) {} //[t82] 00216 00221 pointer operator->() const { return this; } //[t82] 00222 reference operator*() const { return field(*this); } //[t82] 00224 00229 const_tuple_iterator operator++(int); //[t82] 00230 const_tuple_iterator &operator++() { ++m_col; return *this; } //[t82] 00231 const_tuple_iterator operator--(int); //[t82] 00232 const_tuple_iterator &operator--() { --m_col; return *this; } //[t82] 00233 00234 const_tuple_iterator &operator+=(difference_type i) //[t82] 00235 { m_col = size_type(difference_type(m_col) + i); return *this; } 00236 const_tuple_iterator &operator-=(difference_type i) //[t82] 00237 { m_col = size_type(difference_type(m_col) - i); return *this; } 00239 00244 bool operator==(const const_tuple_iterator &i) const //[t82] 00245 {return col()==i.col();} 00246 bool operator!=(const const_tuple_iterator &i) const //[t82] 00247 {return col()!=i.col();} 00248 bool operator<(const const_tuple_iterator &i) const //[t82] 00249 {return col()<i.col();} 00250 bool operator<=(const const_tuple_iterator &i) const //[t82] 00251 {return col()<=i.col();} 00252 bool operator>(const const_tuple_iterator &i) const //[t82] 00253 {return col()>i.col();} 00254 bool operator>=(const const_tuple_iterator &i) const //[t82] 00255 {return col()>=i.col();} 00257 00262 inline const_tuple_iterator operator+(difference_type) const; //[t82] 00263 00264 friend const_tuple_iterator operator+( //[t82] 00265 difference_type, 00266 const_tuple_iterator); 00267 00268 inline const_tuple_iterator operator-(difference_type) const; //[t82] 00269 inline difference_type operator-(const_tuple_iterator) const; //[t82] 00271 }; 00272 00273 00275 class PQXX_LIBEXPORT const_reverse_tuple_iterator : private const_tuple_iterator 00276 { 00277 public: 00278 typedef const_tuple_iterator super; 00279 typedef const_tuple_iterator iterator_type; 00280 using iterator_type::iterator_category; 00281 using iterator_type::difference_type; 00282 using iterator_type::pointer; 00283 #ifndef _MSC_VER 00284 using iterator_type::value_type; 00285 using iterator_type::reference; 00286 #else 00287 // Workaround for Visual C++.NET 2003, which has access problems 00288 typedef field value_type; 00289 typedef const field &reference; 00290 #endif 00291 00292 const_reverse_tuple_iterator(const const_reverse_tuple_iterator &r) : //[t82] 00293 const_tuple_iterator(r) {} 00294 explicit 00295 const_reverse_tuple_iterator(const super &rhs) throw() : //[t82] 00296 const_tuple_iterator(rhs) { super::operator--(); } 00297 00298 iterator_type PQXX_PURE base() const throw (); //[t82] 00299 00304 using iterator_type::operator->; //[t82] 00305 using iterator_type::operator*; //[t82] 00307 00312 const_reverse_tuple_iterator & 00313 operator=(const const_reverse_tuple_iterator &r) //[t82] 00314 { iterator_type::operator=(r); return *this; } 00315 const_reverse_tuple_iterator operator++() //[t82] 00316 { iterator_type::operator--(); return *this; } 00317 const_reverse_tuple_iterator operator++(int); //[t82] 00318 const_reverse_tuple_iterator &operator--() //[t82] 00319 { iterator_type::operator++(); return *this; } 00320 const_reverse_tuple_iterator operator--(int); //[t82] 00321 const_reverse_tuple_iterator &operator+=(difference_type i) //[t82] 00322 { iterator_type::operator-=(i); return *this; } 00323 const_reverse_tuple_iterator &operator-=(difference_type i) //[t82] 00324 { iterator_type::operator+=(i); return *this; } 00326 00331 const_reverse_tuple_iterator operator+(difference_type i) const //[t82] 00332 { return const_reverse_tuple_iterator(base()-i); } 00333 const_reverse_tuple_iterator operator-(difference_type i) //[t82] 00334 { return const_reverse_tuple_iterator(base()+i); } 00335 difference_type 00336 operator-(const const_reverse_tuple_iterator &rhs) const //[t82] 00337 { return rhs.const_tuple_iterator::operator-(*this); } 00339 00344 bool 00345 operator==(const const_reverse_tuple_iterator &rhs) const throw () //[t82] 00346 { return iterator_type::operator==(rhs); } 00347 bool 00348 operator!=(const const_reverse_tuple_iterator &rhs) const throw () //[t82] 00349 { return !operator==(rhs); } 00350 00351 bool operator<(const const_reverse_tuple_iterator &rhs) const //[t82] 00352 { return iterator_type::operator>(rhs); } 00353 bool operator<=(const const_reverse_tuple_iterator &rhs) const //[t82] 00354 { return iterator_type::operator>=(rhs); } 00355 bool operator>(const const_reverse_tuple_iterator &rhs) const //[t82] 00356 { return iterator_type::operator<(rhs); } 00357 bool operator>=(const const_reverse_tuple_iterator &rhs) const //[t82] 00358 { return iterator_type::operator<=(rhs); } 00360 }; 00361 00362 00363 inline const_tuple_iterator 00364 const_tuple_iterator::operator+(difference_type o) const 00365 { 00366 return const_tuple_iterator( 00367 tuple(home(), idx()), 00368 size_type(difference_type(col()) + o)); 00369 } 00370 00371 inline const_tuple_iterator 00372 operator+(const_tuple_iterator::difference_type o, const_tuple_iterator i) 00373 { return i + o; } 00374 00375 inline const_tuple_iterator 00376 const_tuple_iterator::operator-(difference_type o) const 00377 { 00378 return const_tuple_iterator( 00379 tuple(home(), idx()), 00380 size_type(difference_type(col()) - o)); 00381 } 00382 00383 inline const_tuple_iterator::difference_type 00384 const_tuple_iterator::operator-(const_tuple_iterator i) const 00385 { return difference_type(num() - i.num()); } 00386 00387 00388 } // namespace pqxx 00389 00390 00391 /* 00392 [1] Scott Meyers, in one of his essential books, "Effective C++" and "More 00393 Effective C++", points out that it is good style to have any class containing 00394 a member of pointer type define a destructor--just to show that it knows what it 00395 is doing with the pointer. This helps prevent nasty memory leak / double 00396 deletion bugs typically resulting from programmers' omission to deal with such 00397 issues in their destructors. 00398 00399 The @c -Weffc++ option in gcc generates warnings for noncompliance with Scott's 00400 style guidelines, and hence necessitates the definition of this destructor, 00401 trivial as it may be. 00402 */ 00403 00404 00405 #include "pqxx/compiler-internal-post.hxx" 00406 00407 #endif