00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef PQXX_RESULT_H
00015 #define PQXX_RESULT_H
00016
00017 #include <stdexcept>
00018
00019 #include "pqxx/util.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028 namespace pqxx
00029 {
00030
00032
00039 class PQXX_LIBEXPORT Result
00040 {
00041 public:
00042 Result() : m_Result(0), m_Refcount(0) {}
00043 Result(const Result &rhs) :
00044 m_Result(0), m_Refcount(0) { MakeRef(rhs); }
00045 ~Result() { LoseRef(); }
00046
00047 Result &operator=(const Result &);
00048
00049 typedef Result_size_type size_type;
00050 class Field;
00051
00052
00053
00055
00063 class Tuple
00064 {
00065 public:
00066 typedef Tuple_size_type size_type;
00067 Tuple(const Result *r, size_type i) : m_Home(r), m_Index(i) {}
00068 ~Tuple() {}
00069
00070 inline Field operator[](size_type) const;
00071 Field operator[](const char[]) const;
00072 Field operator[](PGSTD::string s) const
00073 { return operator[](s.c_str()); }
00074 Field at(size_type) const;
00075 Field at(const char[]) const;
00076 Field at(PGSTD::string s) const { return at(s.c_str()); }
00077
00078 inline size_type size() const;
00079
00080 Result::size_type Row() const { return m_Index; }
00081
00082 protected:
00083 const Result *m_Home;
00084 Result::size_type m_Index;
00085 };
00086
00087
00089
00092 class Field : private Tuple
00093 {
00094 public:
00095 using Tuple::size_type;
00096
00097 Field(const Tuple &R, Tuple::size_type C) : Tuple(R), m_Col(C) {}
00098
00100 const char *c_str() const {return m_Home->GetValue(m_Index,m_Col);}
00101
00103 inline const char *Name() const;
00104
00106 template<typename T> bool to(T &Obj) const
00107 {
00108 if (is_null())
00109 return false;
00110
00111 try
00112 {
00113 FromString(c_str(), Obj);
00114 }
00115 catch (const PGSTD::exception &e)
00116 {
00117 throw PGSTD::runtime_error("Error reading field " +
00118 PGSTD::string(Name()) +
00119 ": " +
00120 e.what());
00121 }
00122 return true;
00123 }
00124
00126 template<typename T> bool to(T &Obj, const T &Default) const
00127 {
00128 const bool NotNull = to(Obj);
00129 if (!NotNull)
00130 Obj = Default;
00131 return NotNull;
00132 }
00133
00134 bool is_null() const { return m_Home->GetIsNull(m_Index,m_Col); }
00135
00136 int size() const { return m_Home->GetLength(m_Index,m_Col); }
00137
00138 private:
00139
00140 Tuple::size_type m_Col;
00141 };
00142
00143
00145
00149 class const_iterator :
00150 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00151 const Tuple,
00152 Result::size_type>,
00153 public Tuple
00154 {
00155 public:
00156
00163 pointer operator->() const { return this; }
00164 reference operator*() const { return *operator->(); }
00165
00166 const_iterator operator++(int);
00167 const_iterator &operator++() { ++m_Index; return *this; }
00168 const_iterator operator--(int);
00169 const_iterator &operator--() { --m_Index; return *this; }
00170
00171 const_iterator &operator+=(difference_type i)
00172 { m_Index+=i; return *this; }
00173 const_iterator &operator-=(difference_type i)
00174 { m_Index-=i; return *this; }
00175
00176 bool operator==(const const_iterator &i) const
00177 {return m_Index==i.m_Index;}
00178 bool operator!=(const const_iterator &i) const
00179 {return m_Index!=i.m_Index;}
00180 bool operator<(const const_iterator &i) const
00181 {return m_Index<i.m_Index;}
00182 bool operator<=(const const_iterator &i) const
00183 {return m_Index<=i.m_Index;}
00184 bool operator>(const const_iterator &i) const
00185 {return m_Index>i.m_Index;}
00186 bool operator>=(const const_iterator &i) const
00187 {return m_Index>=i.m_Index;}
00188
00189 inline const_iterator operator+(difference_type o) const;
00190
00191 friend const_iterator operator+(difference_type o,
00192 const_iterator i);
00193
00194 inline const_iterator operator-(difference_type o) const;
00195
00196 inline difference_type operator-(const_iterator i) const;
00197
00198 Result::size_type num() const { return Row(); }
00199
00200 private:
00201 friend class Result;
00202 const_iterator(const Result *r, Result::size_type i) : Tuple(r, i) {}
00203 };
00204
00205 const_iterator begin() const { return const_iterator(this, 0); }
00206 inline const_iterator end() const;
00207
00208
00209 size_type size() const { return m_Result ? PQntuples(m_Result) : 0; }
00210 bool empty() const { return !m_Result || !PQntuples(m_Result); }
00211 size_type capacity() const { return size(); }
00212
00213 const Tuple operator[](size_type i) const { return Tuple(this, i); }
00214 const Tuple at(size_type i) const;
00215
00216 void clear() { LoseRef(); }
00217
00218 Tuple::size_type Columns() const { return PQnfields(m_Result); }
00219
00221 Tuple::size_type ColumnNumber(const char Name[]) const
00222 {return PQfnumber(m_Result,Name);}
00224 Tuple::size_type ColumnNumber(std::string Name) const
00225 {return ColumnNumber(Name.c_str());}
00226 const char *ColumnName(Tuple::size_type Number) const
00227 {return PQfname(m_Result,Number);}
00228
00229 private:
00230 PGresult *m_Result;
00231 mutable int *m_Refcount;
00232
00233 friend class Result::Field;
00234 const char *GetValue(size_type Row, Tuple::size_type Col) const;
00235 bool GetIsNull(size_type Row, Tuple::size_type Col) const;
00236 Field::size_type GetLength(size_type Row, Tuple::size_type Col) const;
00237
00238 friend class Connection;
00239 explicit Result(PGresult *rhs) : m_Result(rhs), m_Refcount(0) {MakeRef(rhs);}
00240 Result &operator=(PGresult *);
00241 bool operator!() const { return !m_Result; }
00242 operator bool() const { return m_Result != 0; }
00243 void CheckStatus() const;
00244
00245
00246 void MakeRef(PGresult *);
00247 void MakeRef(const Result &);
00248 void LoseRef() throw ();
00249 };
00250
00251
00252
00253
00254 template<> inline bool Result::Field::to(PGSTD::string &Obj) const
00255 {
00256 if (is_null())
00257 return false;
00258 Obj = c_str();
00259 return true;
00260 }
00261
00262 template<> inline bool Result::Field::to(const char *&Obj) const
00263 {
00264 if (is_null())
00265 return false;
00266 Obj = c_str();
00267 return true;
00268 }
00269
00270
00271 inline Result::Field
00272 Result::Tuple::operator[](Result::Tuple::size_type i) const
00273 {
00274 return Field(*this, i);
00275 }
00276
00277 inline Result::Tuple::size_type Result::Tuple::size() const
00278 {
00279 return m_Home->Columns();
00280 }
00281
00282 inline const char *Result::Field::Name() const
00283 {
00284 return m_Home->ColumnName(m_Col);
00285 }
00286
00287 inline Result::const_iterator
00288 Result::const_iterator::operator+(difference_type o) const
00289 {
00290 return const_iterator(m_Home, m_Index + o);
00291 }
00292
00293 inline Result::const_iterator
00294 operator+(Result::const_iterator::difference_type o,
00295 Result::const_iterator i)
00296 {
00297 return i + o;
00298 }
00299
00300 inline Result::const_iterator
00301 Result::const_iterator::operator-(difference_type o) const
00302 {
00303 return const_iterator(m_Home, m_Index - o);
00304 }
00305
00306 inline Result::const_iterator::difference_type
00307 Result::const_iterator::operator-(const_iterator i) const
00308 {
00309 return num()-i.num();
00310 }
00311
00312 inline Result::const_iterator Result::end() const
00313 {
00314 return const_iterator(this, size());
00315 }
00316
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 #endif
00339