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