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 namespace pqxx
00028 {
00029
00031
00038 class PQXX_LIBEXPORT Result
00039 {
00040 public:
00041 Result() : m_Result(0), m_Refcount(0) {}
00042 Result(const Result &rhs) :
00043 m_Result(0), m_Refcount(0) { MakeRef(rhs); }
00044 ~Result() { LoseRef(); }
00045
00046 Result &operator=(const Result &);
00047
00048 typedef Result_size_type size_type;
00049 class Field;
00050
00051
00052
00054
00062 class PQXX_LIBEXPORT Tuple
00063 {
00064 public:
00065 typedef Tuple_size_type size_type;
00066 Tuple(const Result *r, Result::size_type i) : m_Home(r), m_Index(i) {}
00067 ~Tuple() {}
00068
00069 inline Field operator[](size_type) const;
00070 Field operator[](const char[]) const;
00071 Field operator[](PGSTD::string s) const
00072 { return operator[](s.c_str()); }
00073 Field at(size_type) const;
00074 Field at(const char[]) const;
00075 Field at(PGSTD::string s) const { return at(s.c_str()); }
00076
00077 inline size_type size() const;
00078
00079 Result::size_type Row() const { return m_Index; }
00080
00081 protected:
00082 const Result *m_Home;
00083 Result::size_type m_Index;
00084
00085
00086 Tuple();
00087 };
00088
00089
00091
00094 class PQXX_LIBEXPORT Field : private Tuple
00095 {
00096 public:
00097 typedef size_t size_type;
00098
00099 Field(const Tuple &R, Tuple::size_type C) : Tuple(R), m_Col(C) {}
00100
00102 const char *c_str() const {return m_Home->GetValue(m_Index,m_Col);}
00103
00105 inline const char *Name() const;
00106
00108 template<typename T> bool to(T &Obj) const
00109 {
00110 if (is_null())
00111 return false;
00112
00113 try
00114 {
00115 FromString(c_str(), Obj);
00116 }
00117 catch (const PGSTD::exception &e)
00118 {
00119 throw PGSTD::runtime_error("Error reading field " +
00120 PGSTD::string(Name()) +
00121 ": " +
00122 e.what());
00123 }
00124 return true;
00125 }
00126
00127 #ifdef NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00128
00129 template<> bool to(PGSTD::string &Obj) const
00130 {
00131 if (is_null())
00132 return false;
00133 Obj = c_str();
00134 return true;
00135 }
00136
00138
00141 template<> bool to(const char *&Obj) const
00142 {
00143 if (is_null())
00144 return false;
00145 Obj = c_str();
00146 return true;
00147 }
00148 #endif
00149
00150
00152 template<typename T> bool to(T &Obj, const T &Default) const
00153 {
00154 const bool NotNull = to(Obj);
00155 if (!NotNull)
00156 Obj = Default;
00157 return NotNull;
00158 }
00159
00160 bool is_null() const { return m_Home->GetIsNull(m_Index,m_Col); }
00161
00162 int size() const { return m_Home->GetLength(m_Index,m_Col); }
00163
00164 private:
00165
00166 Tuple::size_type m_Col;
00167 };
00168
00169
00171
00175 class PQXX_LIBEXPORT const_iterator :
00176 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00177 const Tuple,
00178 Result::size_type>,
00179 public Tuple
00180 {
00181 public:
00182
00189 pointer operator->() const { return this; }
00190 reference operator*() const { return *operator->(); }
00191
00192 const_iterator operator++(int);
00193 const_iterator &operator++() { ++m_Index; return *this; }
00194 const_iterator operator--(int);
00195 const_iterator &operator--() { --m_Index; return *this; }
00196
00197 const_iterator &operator+=(difference_type i)
00198 { m_Index+=i; return *this; }
00199 const_iterator &operator-=(difference_type i)
00200 { m_Index-=i; return *this; }
00201
00202 bool operator==(const const_iterator &i) const
00203 {return m_Index==i.m_Index;}
00204 bool operator!=(const const_iterator &i) const
00205 {return m_Index!=i.m_Index;}
00206 bool operator<(const const_iterator &i) const
00207 {return m_Index<i.m_Index;}
00208 bool operator<=(const const_iterator &i) const
00209 {return m_Index<=i.m_Index;}
00210 bool operator>(const const_iterator &i) const
00211 {return m_Index>i.m_Index;}
00212 bool operator>=(const const_iterator &i) const
00213 {return m_Index>=i.m_Index;}
00214
00215 inline const_iterator operator+(difference_type o) const;
00216
00217 friend const_iterator operator+(difference_type o,
00218 const_iterator i);
00219
00220 inline const_iterator operator-(difference_type o) const;
00221
00222 inline difference_type operator-(const_iterator i) const;
00223
00224 Result::size_type num() const { return Row(); }
00225
00226 private:
00227 friend class Result;
00228 const_iterator(const Result *r, Result::size_type i) : Tuple(r, i) {}
00229 };
00230
00231 const_iterator begin() const { return const_iterator(this, 0); }
00232 inline const_iterator end() const;
00233
00234
00235 size_type size() const { return m_Result ? PQntuples(m_Result) : 0; }
00236 bool empty() const { return !m_Result || !PQntuples(m_Result); }
00237 size_type capacity() const { return size(); }
00238
00239 const Tuple operator[](size_type i) const { return Tuple(this, i); }
00240 const Tuple at(size_type) const;
00241
00242 void clear() { LoseRef(); }
00243
00244 Tuple::size_type Columns() const { return PQnfields(m_Result); }
00245
00247 Tuple::size_type ColumnNumber(const char Name[]) const
00248 {return PQfnumber(m_Result,Name);}
00250 Tuple::size_type ColumnNumber(std::string Name) const
00251 {return ColumnNumber(Name.c_str());}
00252 const char *ColumnName(Tuple::size_type Number) const
00253 {return PQfname(m_Result,Number);}
00254
00256
00257 Oid InsertedOid() const { return PQoidValue(m_Result); }
00258
00260
00261 size_type AffectedRows() const;
00262
00263 private:
00264 PGresult *m_Result;
00265 mutable int *m_Refcount;
00266
00267 friend class Result::Field;
00268 const char *GetValue(size_type Row, Tuple::size_type Col) const;
00269 bool GetIsNull(size_type Row, Tuple::size_type Col) const;
00270 Field::size_type GetLength(size_type Row, Tuple::size_type Col) const;
00271
00272 friend class Connection;
00273 explicit Result(PGresult *rhs) : m_Result(rhs), m_Refcount(0) {MakeRef(rhs);}
00274 Result &operator=(PGresult *);
00275 bool operator!() const { return !m_Result; }
00276 operator bool() const { return m_Result != 0; }
00277 void CheckStatus() const;
00278
00279
00280 void MakeRef(PGresult *);
00281 void MakeRef(const Result &);
00282 void LoseRef() throw ();
00283 };
00284
00285
00286 inline Result::Field
00287 Result::Tuple::operator[](Result::Tuple::size_type i) const
00288 {
00289 return Field(*this, i);
00290 }
00291
00292 inline Result::Tuple::size_type Result::Tuple::size() const
00293 {
00294 return m_Home->Columns();
00295 }
00296
00297 inline const char *Result::Field::Name() const
00298 {
00299 return m_Home->ColumnName(m_Col);
00300 }
00301
00302
00303 #ifndef NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00304
00305 template<> inline bool Result::Field::to(PGSTD::string &Obj) const
00306 {
00307 if (is_null())
00308 return false;
00309 Obj = c_str();
00310 return true;
00311 }
00312
00314
00317 template<> inline bool Result::Field::to(const char *&Obj) const
00318 {
00319 if (is_null())
00320 return false;
00321 Obj = c_str();
00322 return true;
00323 }
00324 #endif
00325
00326
00327
00328 inline Result::const_iterator
00329 Result::const_iterator::operator+(difference_type o) const
00330 {
00331 return const_iterator(m_Home, m_Index + o);
00332 }
00333
00334 inline Result::const_iterator
00335 operator+(Result::const_iterator::difference_type o,
00336 Result::const_iterator i)
00337 {
00338 return i + o;
00339 }
00340
00341 inline Result::const_iterator
00342 Result::const_iterator::operator-(difference_type o) const
00343 {
00344 return const_iterator(m_Home, m_Index - o);
00345 }
00346
00347 inline Result::const_iterator::difference_type
00348 Result::const_iterator::operator-(const_iterator i) const
00349 {
00350 return num()-i.num();
00351 }
00352
00353 inline Result::const_iterator Result::end() const
00354 {
00355 return const_iterator(this, size());
00356 }
00357
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 #endif
00380