result.hxx
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00036
00037
00038
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 }
00050 }
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) {}
00095 result(const result &rhs) PQXX_NOEXCEPT :
00096 super(rhs), m_data(rhs.m_data) {}
00097
00098 result &operator=(const result &rhs) PQXX_NOEXCEPT
00099 { super::operator=(rhs); m_data=rhs.m_data; return *this; }
00100
00105 bool operator==(const result &) const PQXX_NOEXCEPT;
00106 bool operator!=(const result &rhs) const PQXX_NOEXCEPT
00107 { return !operator==(rhs); }
00109
00110 const_reverse_iterator rbegin() const;
00111 const_reverse_iterator crbegin() const;
00112 const_reverse_iterator rend() const;
00113 const_reverse_iterator crend() const;
00114
00115 const_iterator begin() const PQXX_NOEXCEPT;
00116 const_iterator cbegin() const PQXX_NOEXCEPT;
00117 inline const_iterator end() const PQXX_NOEXCEPT;
00118 inline const_iterator cend() const PQXX_NOEXCEPT;
00119
00120 reference front() const PQXX_NOEXCEPT { return row(this,0); }
00121 reference back() const PQXX_NOEXCEPT {return row(this,size()-1);}
00122
00123 PQXX_PURE size_type size() const PQXX_NOEXCEPT;
00124 PQXX_PURE bool empty() const PQXX_NOEXCEPT;
00125 size_type capacity() const PQXX_NOEXCEPT { return size(); }
00126
00127 void swap(result &) PQXX_NOEXCEPT;
00128
00129 const row operator[](size_type i) const PQXX_NOEXCEPT
00130 { return row(this, i); }
00131 const row at(size_type) const;
00132
00133 void clear() PQXX_NOEXCEPT { super::reset(); m_data = 0; }
00134
00139
00140 PQXX_PURE row::size_type columns() const PQXX_NOEXCEPT;
00141
00143 row::size_type column_number(const char ColName[]) const;
00144
00146 row::size_type column_number(const std::string &Name) const
00147 {return column_number(Name.c_str());}
00148
00150 const char *column_name(row::size_type Number) const;
00151
00153 oid column_type(row::size_type ColNum) const;
00155 oid column_type(int ColNum) const
00156 { return column_type(row::size_type(ColNum)); }
00157
00159 oid column_type(const std::string &ColName) const
00160 { return column_type(column_number(ColName)); }
00161
00163 oid column_type(const char ColName[]) const
00164 { return column_type(column_number(ColName)); }
00165
00167 oid column_table(row::size_type ColNum) const;
00168
00170 oid column_table(int ColNum) const
00171 { return column_table(row::size_type(ColNum)); }
00172
00174 oid column_table(const std::string &ColName) const
00175 { return column_table(column_number(ColName)); }
00176
00178 row::size_type table_column(row::size_type ColNum) const;
00179
00181 row::size_type table_column(int ColNum) const
00182 { return table_column(row::size_type(ColNum)); }
00183
00185 row::size_type table_column(const std::string &ColName) const
00186 { return table_column(column_number(ColName)); }
00188
00190 PQXX_PURE const std::string &query() const PQXX_NOEXCEPT;
00191
00193
00196 PQXX_PURE oid inserted_oid() const;
00197
00199
00202 PQXX_PURE size_type affected_rows() const;
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; }
00279 reference operator*() const { return row(*this); }
00281
00286 const_result_iterator operator++(int);
00287 const_result_iterator &operator++() { ++m_Index; return *this; }
00288 const_result_iterator operator--(int);
00289 const_result_iterator &operator--() { --m_Index; return *this; }
00290
00291 const_result_iterator &operator+=(difference_type i)
00292 { m_Index = size_type(difference_type(m_Index) + i); return *this; }
00293 const_result_iterator &operator-=(difference_type i)
00294 { m_Index = size_type(difference_type(m_Index) - i); return *this; }
00296
00301 bool operator==(const const_result_iterator &i) const
00302 {return m_Index==i.m_Index;}
00303 bool operator!=(const const_result_iterator &i) const
00304 {return m_Index!=i.m_Index;}
00305 bool operator<(const const_result_iterator &i) const
00306 {return m_Index<i.m_Index;}
00307 bool operator<=(const const_result_iterator &i) const
00308 {return m_Index<=i.m_Index;}
00309 bool operator>(const const_result_iterator &i) const
00310 {return m_Index>i.m_Index;}
00311 bool operator>=(const const_result_iterator &i) const
00312 {return m_Index>=i.m_Index;}
00314
00319 inline const_result_iterator operator+(difference_type) const;
00320 friend const_result_iterator operator+(
00321 difference_type,
00322 const_result_iterator);
00323 inline const_result_iterator operator-(difference_type) const;
00324 inline difference_type operator-(const_result_iterator) const;
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
00350 typedef const row &reference;
00351 typedef row value_type;
00352 #endif
00353
00354 const_reverse_result_iterator(
00355 const const_reverse_result_iterator &rhs) :
00356 const_result_iterator(rhs) {}
00357 explicit const_reverse_result_iterator(
00358 const const_result_iterator &rhs) :
00359 const_result_iterator(rhs) { super::operator--(); }
00360
00361 PQXX_PURE const_result_iterator base() const PQXX_NOEXCEPT;
00362
00367 using const_result_iterator::operator->;
00368 using const_result_iterator::operator*;
00370
00375 const_reverse_result_iterator &operator=(
00376 const const_reverse_result_iterator &r)
00377 { iterator_type::operator=(r); return *this; }
00378 const_reverse_result_iterator operator++()
00379 { iterator_type::operator--(); return *this; }
00380 const_reverse_result_iterator operator++(int);
00381 const_reverse_result_iterator &operator--()
00382 { iterator_type::operator++(); return *this; }
00383 const_reverse_result_iterator operator--(int);
00384 const_reverse_result_iterator &operator+=(difference_type i)
00385 { iterator_type::operator-=(i); return *this; }
00386 const_reverse_result_iterator &operator-=(difference_type i)
00387 { iterator_type::operator+=(i); return *this; }
00389
00394 const_reverse_result_iterator operator+(difference_type i) const
00395 { return const_reverse_result_iterator(base() - i); }
00396 const_reverse_result_iterator operator-(difference_type i)
00397 { return const_reverse_result_iterator(base() + i); }
00398 difference_type operator-(
00399 const const_reverse_result_iterator &rhs) const
00400 { return rhs.const_result_iterator::operator-(*this); }
00402
00407 bool operator==(
00408 const const_reverse_result_iterator &rhs) const PQXX_NOEXCEPT
00409 { return iterator_type::operator==(rhs); }
00410 bool operator!=(
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
00415 { return iterator_type::operator>(rhs); }
00416 bool operator<=(const const_reverse_result_iterator &rhs) const
00417 { return iterator_type::operator>=(rhs); }
00418 bool operator>(const const_reverse_result_iterator &rhs) const
00419 { return iterator_type::operator<(rhs); }
00420 bool operator>=(const const_reverse_result_iterator &rhs) const
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)
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)
00460 { from_string(F.c_str(), Obj, F.size()); }
00461
00463 template<>
00464 inline std::string to_string(const field &Obj)
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 }
00505
00506
00507 #include "pqxx/compiler-internal-post.hxx"
00508
00509 #endif