00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef PQXX_HAVE_IOS
00020 #include <ios>
00021 #endif
00022
00023 #include <stdexcept>
00024
00025 #include "pqxx/util"
00026
00027
00028
00029
00030
00031
00032
00033 namespace pqxx
00034 {
00036
00043 class PQXX_LIBEXPORT result : private internal::PQAlloc<internal::pq::PGresult>
00044 {
00045 typedef internal::PQAlloc<internal::pq::PGresult> super;
00046 public:
00047 class const_iterator;
00048 class const_fielditerator;
00049 class const_reverse_fielditerator;
00050 class tuple;
00051 class field;
00052 typedef unsigned long size_type;
00053 typedef signed long difference_type;
00054 typedef tuple reference;
00055 typedef const_iterator pointer;
00056
00058
00067 class PQXX_LIBEXPORT tuple
00068 {
00069 public:
00070 typedef unsigned int size_type;
00071 typedef signed int difference_type;
00072 typedef const_fielditerator const_iterator;
00073 typedef field reference;
00074 typedef const_fielditerator pointer;
00075 typedef const_reverse_fielditerator const_reverse_iterator;
00076
00077 tuple(const result *r, result::size_type i) throw () :
00078 m_Home(r), m_Index(i) {}
00079 ~tuple() throw () {}
00080
00081 bool operator==(const tuple &) const throw ();
00082 bool operator!=(const tuple &rhs) const throw ()
00083 { return !operator==(rhs); }
00084
00085 const_iterator begin() const throw ()
00086 { return const_iterator(*this, 0); }
00087 const_iterator end() const throw ()
00088 { return const_iterator(*this, size()); }
00089
00090 reference front() const throw () { return field(*this, 0); }
00091 reference back() const throw () { return field(*this, size()-1); }
00092
00093 const_reverse_fielditerator rbegin() const;
00094 const_reverse_fielditerator rend() const;
00095
00096 reference operator[](size_type i) const throw ()
00097 { return field(*this, i); }
00098 reference operator[](int i) const throw ()
00099 { return operator[](size_type(i)); }
00100 reference operator[](const char[]) const;
00101 reference operator[](const PGSTD::string &s) const
00102 { return operator[](s.c_str()); }
00103 reference at(size_type) const throw (PGSTD::out_of_range);
00104 reference at(int i) const throw (PGSTD::out_of_range)
00105 { return at(size_type(i)); }
00106 reference at(const char[]) const;
00107 reference at(const PGSTD::string &s) const
00108 { return at(s.c_str()); }
00109
00110 size_type size() const throw () { return m_Home->columns(); }
00111
00112 void swap(tuple &rhs) throw ()
00113 {
00114 const result *const h(m_Home);
00115 const result::size_type i(m_Index);
00116 m_Home = rhs.m_Home;
00117 m_Index = rhs.m_Index;
00118 rhs.m_Home = h;
00119 rhs.m_Index = i;
00120 }
00121
00122 result::size_type rownumber() const throw () { return m_Index; }
00123
00125 size_type column_number(const PGSTD::string &ColName) const
00126 { return m_Home->column_number(ColName); }
00127
00129 size_type column_number(const char ColName[]) const
00130 { return m_Home->column_number(ColName); }
00131
00133 oid column_type(size_type ColNum) const
00134 { return m_Home->column_type(ColNum); }
00135
00137 oid column_type(int ColNum) const
00138 { return column_type(size_type(ColNum)); }
00139
00141 oid column_type(const PGSTD::string &ColName) const
00142 { return column_type(column_number(ColName)); }
00143
00145 oid column_type(const char ColName[]) const
00146 { return column_type(column_number(ColName)); }
00147
00148 result::size_type num() const { return rownumber(); }
00149
00150 #ifdef PQXX_HAVE_PQFTABLE
00151 oid column_table(size_type ColNum) const
00152 { return m_Home->column_table(ColNum); }
00153 oid column_table(int ColNum) const
00154 { return column_table(size_type(ColNum)); }
00155 oid column_table(const PGSTD::string &ColName) const
00156 { return column_table(column_number(ColName)); }
00157 #endif
00158
00159
00160 #ifdef PQXX_DEPRECATED_HEADERS
00161
00162 result::size_type Row() const { return rownumber(); }
00163
00165 size_type ColumnNumber(const PGSTD::string &ColName) const
00166 { return column_number(ColName); }
00167
00169 size_type ColumnNumber(const char ColName[]) const
00170 { return column_number(ColName); }
00171 #endif
00172
00173 protected:
00174 friend class field;
00175 const result *m_Home;
00176 result::size_type m_Index;
00177
00178
00179 tuple();
00180 };
00181
00183
00186 class PQXX_LIBEXPORT field
00187 {
00188 public:
00189 typedef size_t size_type;
00190
00192
00196 field(const tuple &T, tuple::size_type C) throw () :
00197 m_tup(T), m_col(C) {}
00198
00200
00215 bool operator==(const field &) const;
00216
00218
00220 bool operator!=(const field &rhs) const {return !operator==(rhs);}
00221
00223
00228 const char *c_str() const { return home()->GetValue(idx(),col()); }
00229
00231 const char *name() const { return home()->column_name(col()); }
00232
00234 oid type() const { return home()->column_type(col()); }
00235
00236 #ifdef PQXX_HAVE_PQFTABLE
00237
00238
00240 oid table() const { return home()->column_table(col()); }
00241 #endif
00242
00244
00253 template<typename T> bool to(T &Obj) const
00254 {
00255 if (is_null())
00256 return false;
00257
00258 try
00259 {
00260 from_string(c_str(), Obj);
00261 }
00262 catch (const PGSTD::exception &e)
00263 {
00264 throw PGSTD::domain_error("Error reading field " +
00265 PGSTD::string(name()) + ": " +
00266 e.what());
00267 }
00268 return true;
00269 }
00270
00272 template<typename T> bool operator>>(T &Obj) const
00273 { return to(Obj); }
00274
00275 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00276
00277 template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00278
00280
00283 template<> bool to<const char *>(const char *&Obj) const;
00284 #endif
00285
00287 template<typename T> bool to(T &Obj, const T &Default) const
00288 {
00289 const bool NotNull = to(Obj);
00290 if (!NotNull) Obj = Default;
00291 return NotNull;
00292 }
00293
00295
00298 template<typename T> T as(const T &Default) const
00299 {
00300 T Obj;
00301 to(Obj, Default);
00302 return Obj;
00303 }
00304
00306 template<typename T> T as() const
00307 {
00308 T Obj;
00309 const bool NotNull = to(Obj);
00310 if (!NotNull) throw PGSTD::domain_error("Attempt to read null field");
00311 return Obj;
00312 }
00313
00314 bool is_null() const { return home()->GetIsNull(idx(), col()); }
00315 size_type size() const throw ()
00316 { return home()->GetLength(idx(),col()); }
00317 tuple::size_type num() const { return col(); }
00318
00319 #ifdef PQXX_DEPRECATED_HEADERS
00320
00321 const char *Name() const {return name();}
00322 #endif
00323
00324 private:
00325 const result *home() const throw () { return m_tup.m_Home; }
00326 result::size_type idx() const throw () { return m_tup.m_Index; }
00327
00328 protected:
00329 const tuple::size_type col() const throw () { return m_col; }
00330 tuple m_tup;
00331 tuple::size_type m_col;
00332 };
00333
00334 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00335 const tuple,
00336 result::difference_type,
00337 const_iterator,
00338 tuple> const_iterator_base;
00339
00341
00345 class PQXX_LIBEXPORT const_iterator :
00346 public const_iterator_base,
00347 public tuple
00348 {
00349 public:
00350 typedef const tuple *pointer;
00351 typedef tuple reference;
00352 typedef result::size_type size_type;
00353 typedef result::difference_type difference_type;
00354
00355 const_iterator() throw () : tuple(0,0) {}
00356 const_iterator(const tuple &t) throw () : tuple(t) {}
00357
00364 pointer operator->() const { return this; }
00365 reference operator*() const { return tuple(*this); }
00366
00367 const_iterator operator++(int);
00368 const_iterator &operator++() { ++m_Index; return *this; }
00369 const_iterator operator--(int);
00370 const_iterator &operator--() { --m_Index; return *this; }
00371
00372 const_iterator &operator+=(difference_type i)
00373 { m_Index+=i; return *this; }
00374 const_iterator &operator-=(difference_type i)
00375 { m_Index-=i; return *this; }
00376
00377 bool operator==(const const_iterator &i) const
00378 {return m_Index==i.m_Index;}
00379 bool operator!=(const const_iterator &i) const
00380 {return m_Index!=i.m_Index;}
00381 bool operator<(const const_iterator &i) const
00382 {return m_Index<i.m_Index;}
00383 bool operator<=(const const_iterator &i) const
00384 {return m_Index<=i.m_Index;}
00385 bool operator>(const const_iterator &i) const
00386 {return m_Index>i.m_Index;}
00387 bool operator>=(const const_iterator &i) const
00388 {return m_Index>=i.m_Index;}
00389
00390 inline const_iterator operator+(difference_type) const;
00391 friend const_iterator
00392 operator+(difference_type, const_iterator);
00393 inline const_iterator operator-(difference_type) const;
00394 inline difference_type operator-(const_iterator) const;
00395
00396 private:
00397 friend class pqxx::result;
00398 const_iterator(const pqxx::result *r, result::size_type i) throw () :
00399 tuple(r, i) {}
00400 };
00401
00402 class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00403 {
00404 public:
00405 typedef const_iterator iterator_type;
00406 using iterator_type::iterator_category;
00407 using iterator_type::value_type;
00408 using iterator_type::difference_type;
00409 using iterator_type::pointer;
00410 using iterator_type::reference;
00411 using iterator_type::operator=;
00412
00413 const_reverse_iterator(const const_reverse_iterator &rhs) :
00414 const_iterator(rhs), m_tmp(rhs) {}
00415 explicit const_reverse_iterator(const const_iterator &rhs) :
00416 const_iterator(rhs), m_tmp() {}
00417
00418 iterator_type base() const throw () { return *this; }
00419
00420 pointer operator->() const throw ()
00421 { m_tmp=*this; --m_tmp; return &m_tmp; }
00422 reference operator*() const throw () { return *operator->(); }
00423 const_reverse_iterator operator++()
00424 { iterator_type::operator--(); return *this; }
00425 const_reverse_iterator operator++(int)
00426 {
00427 const const_reverse_iterator tmp(*this);
00428 iterator_type::operator--();
00429 return tmp;
00430 }
00431 const_reverse_iterator &operator--()
00432 { iterator_type::operator++(); return *this; }
00433 const_reverse_iterator operator--(int)
00434 {
00435 const_reverse_iterator tmp(*this);
00436 iterator_type::operator++();
00437 return tmp;
00438 }
00439 const_reverse_iterator operator+(difference_type i) const
00440 { return const_reverse_iterator(iterator_type(*this)-i); }
00441 const_reverse_iterator &operator+=(difference_type i)
00442 { iterator_type::operator-=(i); return *this; }
00443 const_reverse_iterator operator-(difference_type i)
00444 { return const_reverse_iterator(iterator_type(*this)+i); }
00445 const_reverse_iterator &operator-=(difference_type i)
00446 { iterator_type::operator+=(i); return *this; }
00447
00448 using iterator_type::operator==;
00449 using iterator_type::operator!=;
00450 bool operator==(const const_reverse_iterator &rhs) const throw ()
00451 { return iterator_type::operator==(rhs); }
00452 bool operator!=(const const_reverse_iterator &rhs) const throw ()
00453 { return !operator==(rhs); }
00454
00455 bool operator<(const const_reverse_iterator &rhs) const
00456 { return iterator_type::operator>(rhs); }
00457 bool operator<=(const const_reverse_iterator &rhs) const
00458 { return iterator_type::operator>=(rhs); }
00459 bool operator>(const const_reverse_iterator &rhs) const
00460 { return iterator_type::operator<(rhs); }
00461 bool operator>=(const const_reverse_iterator &rhs) const
00462 { return iterator_type::operator<=(rhs); }
00463 difference_type operator-(const const_reverse_iterator &rhs) const
00464 { return rhs.base() - base(); }
00465
00466 private:
00468
00473 mutable iterator_type m_tmp;
00474 };
00475
00476 class PQXX_LIBEXPORT const_fielditerator :
00477 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00478 const field,
00479 tuple::size_type>,
00480 public field
00481 {
00482 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00483 const field,
00484 tuple::size_type> it;
00485 public:
00486 using it::pointer;
00487 typedef tuple::size_type size_type;
00488 typedef tuple::difference_type difference_type;
00489 typedef field reference;
00490
00491 const_fielditerator(const tuple &T, tuple::size_type C) throw () :
00492 field(T, C) {}
00493 const_fielditerator(const field &F) throw () : field(F) {}
00494
00495 pointer operator->() const { return this; }
00496 reference operator*() const { return field(*this); }
00497
00498 const_fielditerator operator++(int);
00499 const_fielditerator &operator++() { ++m_col; return *this; }
00500 const_fielditerator operator--(int);
00501 const_fielditerator &operator--() { --m_col; return *this; }
00502
00503 const_fielditerator &operator+=(difference_type i)
00504 { m_col+=i; return *this; }
00505 const_fielditerator &operator-=(difference_type i)
00506 { m_col-=i; return *this; }
00507
00508 bool operator==(const const_fielditerator &i) const
00509 {return col()==i.col();}
00510 bool operator!=(const const_fielditerator &i) const
00511 {return col()!=i.col();}
00512 bool operator<(const const_fielditerator &i) const
00513 {return col()<i.col();}
00514 bool operator<=(const const_fielditerator &i) const
00515 {return col()<=i.col();}
00516 bool operator>(const const_fielditerator &i) const
00517 {return col()>i.col();}
00518 bool operator>=(const const_fielditerator &i) const
00519 {return col()>=i.col();}
00520
00521 inline const_fielditerator operator+(difference_type) const;
00522
00523 friend const_fielditerator operator+(difference_type,
00524 const_fielditerator);
00525
00526 inline const_fielditerator operator-(difference_type) const;
00527 inline difference_type operator-(const_fielditerator) const;
00528 };
00529
00530 class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00531 {
00532 public:
00533 typedef const_fielditerator iterator_type;
00534 using iterator_type::iterator_category;
00535 using iterator_type::value_type;
00536 using iterator_type::difference_type;
00537 using iterator_type::pointer;
00538 using iterator_type::reference;
00539 using iterator_type::operator=;
00540
00541 iterator_type base() const throw () { return *this; }
00542 const_reverse_fielditerator(const const_reverse_fielditerator &rhs)
00543 : const_fielditerator(rhs), m_tmp(rhs.m_tmp) {}
00544 explicit
00545 const_reverse_fielditerator(const const_fielditerator &rhs) :
00546 const_fielditerator(rhs), m_tmp(rhs) {}
00547
00548 pointer operator->() const throw ()
00549 { m_tmp = *this; --m_tmp; return &m_tmp; }
00550 reference operator*() const throw () { return *operator->(); }
00551 const_reverse_fielditerator operator++()
00552 { iterator_type::operator--(); return *this; }
00553 const_reverse_fielditerator operator++(int)
00554 {
00555 const const_reverse_fielditerator tmp(*this);
00556 iterator_type::operator--();
00557 return tmp;
00558 }
00559 const_reverse_fielditerator &operator--()
00560 { iterator_type::operator++(); return *this; }
00561 const_reverse_fielditerator operator--(int)
00562 {
00563 const_reverse_fielditerator tmp(*this);
00564 iterator_type::operator++();
00565 return tmp;
00566 }
00567 const_reverse_fielditerator operator+(difference_type i) const
00568 { return const_reverse_fielditerator(iterator_type(*this)-i); }
00569 const_reverse_fielditerator &operator+=(difference_type i)
00570 { iterator_type::operator-=(i); return *this; }
00571 const_reverse_fielditerator operator-(difference_type i)
00572 { return const_reverse_fielditerator(iterator_type(*this)+i); }
00573 const_reverse_fielditerator &operator-=(difference_type i)
00574 { iterator_type::operator+=(i); return *this; }
00575
00576 using iterator_type::operator==;
00577 using iterator_type::operator!=;
00578 bool
00579 operator==(const const_reverse_fielditerator &rhs) const throw ()
00580 { return iterator_type::operator==(rhs); }
00581 bool
00582 operator!=(const const_reverse_fielditerator &rhs) const throw ()
00583 { return !operator==(rhs); }
00584
00585
00586 bool operator<(const const_reverse_fielditerator &rhs) const
00587 { return iterator_type::operator>(rhs); }
00588 bool operator<=(const const_reverse_fielditerator &rhs) const
00589 { return iterator_type::operator>=(rhs); }
00590 bool operator>(const const_reverse_fielditerator &rhs) const
00591 { return iterator_type::operator<(rhs); }
00592 bool operator>=(const const_reverse_fielditerator &rhs) const
00593 { return iterator_type::operator<=(rhs); }
00594 difference_type
00595 operator-(const const_reverse_fielditerator &rhs) const
00596 { return rhs.base() - base(); }
00597
00598 private:
00600
00605 mutable iterator_type m_tmp;
00606 };
00607
00608
00609 result() throw () : super() {}
00610 result(const result &rhs) throw () : super(rhs) {}
00611
00612 result &operator=(const result &rhs) throw ()
00613 { super::operator=(rhs); return *this; }
00614
00615 bool operator==(const result &) const throw ();
00616 bool operator!=(const result &rhs) const throw ()
00617 { return !operator==(rhs); }
00618
00619 const_reverse_iterator rbegin() const
00620 { return const_reverse_iterator(end()); }
00621 const_reverse_iterator rend() const
00622 { return const_reverse_iterator(begin()); }
00623
00624 const_iterator begin() const throw ()
00625 { return const_iterator(this, 0); }
00626 inline const_iterator end() const throw ();
00627
00628 reference front() const throw () { return tuple(this,0); }
00629 reference back() const throw () {return tuple(this,size()-1);}
00630
00631 size_type size() const throw ()
00632 { return c_ptr() ? PQXXPQ::PQntuples(c_ptr()) : 0; }
00633 bool empty() const
00634 { return !c_ptr() || !PQXXPQ::PQntuples(c_ptr()); }
00635 size_type capacity() const throw () { return size(); }
00636
00637 void swap(result &) throw ();
00638
00639 const tuple operator[](size_type i) const throw ()
00640 { return tuple(this, i); }
00641 const tuple at(size_type) const throw (PGSTD::out_of_range);
00642
00643 using super::clear;
00644
00646 tuple::size_type columns() const throw ()
00647 { return PQnfields(c_ptr()); }
00648
00650 tuple::size_type column_number(const char ColName[]) const;
00651
00653 tuple::size_type column_number(const PGSTD::string &Name) const
00654 {return column_number(Name.c_str());}
00655
00657 const char *column_name(tuple::size_type Number) const;
00658
00660 inline oid column_type(tuple::size_type ColNum) const;
00662 inline oid column_type(int ColNum) const
00663 { return column_type(tuple::size_type(ColNum)); }
00664
00666 oid column_type(const PGSTD::string &ColName) const
00667 { return column_type(column_number(ColName)); }
00668
00670 oid column_type(const char ColName[]) const
00671 { return column_type(column_number(ColName)); }
00672
00673 #ifdef PQXX_HAVE_PQFTABLE
00674
00675 oid column_table(tuple::size_type ColNum) const;
00677 oid column_table(int ColNum) const
00678 { return column_table(tuple::size_type(ColNum)); }
00679
00681 oid column_table(const PGSTD::string &ColName) const
00682 { return column_table(column_number(ColName)); }
00683 #endif
00684
00686
00688 oid inserted_oid() const { return PQoidValue(c_ptr()); }
00689
00690
00692
00693 size_type affected_rows() const;
00694
00695
00696 #ifdef PQXX_DEPRECATED_HEADERS
00697
00698 typedef tuple Tuple;
00700 typedef field Field;
00702 oid InsertedOid() const { return inserted_oid(); }
00704 size_type AffectedRows() const { return affected_rows(); }
00706 tuple::size_type Columns() const { return columns(); }
00708 tuple::size_type ColumnNumber(const char Name[]) const
00709 {return PQfnumber(c_ptr(),Name);}
00711 tuple::size_type ColumnNumber(const PGSTD::string &Name) const
00712 {return ColumnNumber(Name.c_str());}
00714 const char *ColumnName(tuple::size_type Number) const
00715 {return PQfname(c_ptr(),Number);}
00716 #endif
00717
00718
00719 private:
00720 friend class pqxx::result::field;
00721 const char *GetValue(size_type Row, tuple::size_type Col) const;
00722 bool GetIsNull(size_type Row, tuple::size_type Col) const;
00723 field::size_type GetLength(size_type Row, tuple::size_type Col) const;
00724
00725 friend class connection_base;
00726 friend class pipeline;
00727 explicit result(PQXXPQ::PGresult *rhs) throw () : super(rhs) {}
00728 result &operator=(PQXXPQ::PGresult *rhs) throw ()
00729 { super::operator=(rhs); return *this; }
00730 bool operator!() const throw () { return !c_ptr(); }
00731 operator bool() const throw () { return c_ptr() != 0; }
00732 void CheckStatus(const PGSTD::string &Query) const;
00733 void CheckStatus(const char Query[]) const;
00734 int errorposition() const throw ();
00735 PGSTD::string StatusError() const;
00736
00737 friend class Cursor;
00738 const char *CmdStatus() const throw () { return PQcmdStatus(c_ptr()); }
00739 };
00740
00741
00743
00760 template<typename STREAM>
00761 inline STREAM &operator<<(STREAM &S, const pqxx::result::field &F)
00762 {
00763 S.write(F.c_str(), F.size());
00764 return S;
00765 }
00766
00767
00769 template<typename T>
00770 inline void from_string(const result::field &F, T &Obj)
00771 { from_string(F.c_str(), Obj); }
00772
00774 template<>
00775 inline PGSTD::string to_string(const result::field &Obj)
00776 { return to_string(Obj.c_str()); }
00777
00778
00780 template<>
00781 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
00782 {
00783 if (is_null()) return false;
00784 Obj = c_str();
00785 return true;
00786 }
00787
00789
00792 template<>
00793 inline bool result::field::to<const char *>(const char *&Obj) const
00794 {
00795 if (is_null()) return false;
00796 Obj = c_str();
00797 return true;
00798 }
00799
00800
00801 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
00802 { return const_reverse_fielditerator(end()); }
00803 inline result::tuple::const_reverse_iterator result::tuple::rend() const
00804 { return const_reverse_fielditerator(begin()); }
00805
00806 inline result::const_iterator
00807 result::const_iterator::operator+(difference_type o) const
00808 {
00809 return const_iterator(m_Home, m_Index + o);
00810 }
00811
00812 inline result::const_iterator
00813 operator+(result::const_iterator::difference_type o, result::const_iterator i)
00814 {
00815 return i + o;
00816 }
00817
00818 inline result::const_iterator
00819 result::const_iterator::operator-(difference_type o) const
00820 {
00821 return const_iterator(m_Home, m_Index - o);
00822 }
00823
00824 inline result::const_iterator::difference_type
00825 result::const_iterator::operator-(const_iterator i) const
00826 {
00827 return num()-i.num();
00828 }
00829
00830 inline result::const_iterator result::end() const throw ()
00831 {
00832 return const_iterator(this, size());
00833 }
00834
00835
00836 inline result::const_reverse_iterator
00837 operator+(result::const_reverse_iterator::difference_type n,
00838 const result::const_reverse_iterator &i)
00839 {
00840 return result::const_reverse_iterator(i.base() - n);
00841 }
00842
00843 inline result::const_fielditerator
00844 result::const_fielditerator::operator+(difference_type o) const
00845 {
00846 return const_fielditerator(m_tup, col() + o);
00847 }
00848
00849 inline result::const_fielditerator
00850 operator+(result::const_fielditerator::difference_type o,
00851 result::const_fielditerator i)
00852 {
00853 return i + o;
00854 }
00855
00856 inline result::const_fielditerator
00857 result::const_fielditerator::operator-(difference_type o) const
00858 {
00859 return const_fielditerator(m_tup, col() - o);
00860 }
00861
00862 inline result::const_fielditerator::difference_type
00863 result::const_fielditerator::operator-(const_fielditerator i) const
00864 {
00865 return num()-i.num();
00866 }
00867
00868
00869 inline oid result::column_type(tuple::size_type ColNum) const
00870 {
00871 const oid T = PQftype(c_ptr(), ColNum);
00872 if (T == oid_none)
00873 throw PGSTD::invalid_argument(
00874 "Attempt to retrieve type of nonexistant column " +
00875 to_string(ColNum) + " "
00876 "of query result");
00877 return T;
00878 }
00879
00880
00881
00882 #ifdef PQXX_HAVE_PQFTABLE
00883 inline oid result::column_table(tuple::size_type ColNum) const
00884 {
00885 const oid T = PQftable(c_ptr(), ColNum);
00886
00887
00888
00889
00890
00891 if ((T == oid_none) &&
00892 (ColNum >= columns()))
00893 throw PGSTD::invalid_argument("Attempt to retrieve table ID for column " +
00894 to_string(ColNum) + " "
00895 "out of " + to_string(columns()));
00896 return T;
00897 }
00898 #endif
00899
00900
00901 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00902 class field_streambuf :
00903 #ifdef PQXX_HAVE_STREAMBUF
00904 public PGSTD::basic_streambuf<CHAR, TRAITS>
00905 #else
00906 public PGSTD::streambuf
00907 #endif
00908 {
00909 public:
00910 typedef CHAR char_type;
00911 typedef TRAITS traits_type;
00912 typedef typename traits_type::int_type int_type;
00913 #ifdef PQXX_HAVE_STREAMBUF
00914 typedef typename traits_type::pos_type pos_type;
00915 typedef typename traits_type::off_type off_type;
00916 #else
00917 typedef streamoff off_type;
00918 typedef streampos pos_type;
00919 #endif
00920 typedef PGSTD::ios::openmode openmode;
00921 typedef PGSTD::ios::seekdir seekdir;
00922
00923 explicit field_streambuf(const result::field &F) :
00924 m_Field(F)
00925 {
00926 initialize();
00927 }
00928
00929 #ifdef PQXX_HAVE_STREAMBUF
00930 protected:
00931 #endif
00932 virtual int sync() { return traits_type::eof(); }
00933
00934 protected:
00935 virtual pos_type seekoff(off_type, seekdir, openmode)
00936 {
00937 return traits_type::eof();
00938 }
00939
00940 virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
00941
00942 virtual int_type overflow(int_type) { return traits_type::eof(); }
00943
00944 virtual int_type underflow() { return traits_type::eof(); }
00945
00946 private:
00947 const result::field &m_Field;
00948
00949 int_type initialize()
00950 {
00951 char_type *G =
00952 reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
00953 setg(G, G, G + m_Field.size());
00954 return m_Field.size();
00955 }
00956 };
00957
00958
00960
00974 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00975 class basic_fieldstream :
00976 #ifdef PQXX_HAVE_STREAMBUF
00977 public PGSTD::basic_istream<CHAR, TRAITS>
00978 #else
00979 public PGSTD::istream
00980 #endif
00981 {
00982 #ifdef PQXX_HAVE_STREAMBUF
00983 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00984 #else
00985 typedef PGSTD::istream super;
00986 #endif
00987
00988 public:
00989 typedef CHAR char_type;
00990 typedef TRAITS traits_type;
00991 typedef typename traits_type::int_type int_type;
00992 typedef typename traits_type::pos_type pos_type;
00993 typedef typename traits_type::off_type off_type;
00994
00995 basic_fieldstream(const result::field &F) : super(&m_Buf), m_Buf(F) { }
00996
00997 private:
00998 field_streambuf<CHAR, TRAITS> m_Buf;
00999 };
01000
01001 typedef basic_fieldstream<char> fieldstream;
01002
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025