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 #ifdef PQXX_HAVE_IOS
00026 #include <ios>
00027 #endif
00028
00029 #include <stdexcept>
00030
00031 #include "pqxx/except"
00032 #include "pqxx/strconv"
00033 #include "pqxx/util"
00034
00035
00036
00037
00038
00039
00040 namespace pqxx
00041 {
00042 class result;
00043
00044 namespace internal
00045 {
00046 class sql_cursor;
00047
00049 struct PQXX_PRIVATE result_data
00050 {
00052
00055 pqxx::internal::pq::PGresult *data;
00056
00058 int protocol;
00059
00061 PGSTD::string query;
00062
00063 int encoding_code;
00064
00065
00066
00067 result_data();
00068 result_data(pqxx::internal::pq::PGresult *,
00069 int protocol,
00070 const PGSTD::string &,
00071 int encoding_code);
00072 ~result_data();
00073 };
00074
00075 void PQXX_LIBEXPORT freemem_result_data(const result_data *) throw ();
00076 }
00077
00078
00079 namespace internal
00080 {
00081 namespace gate
00082 {
00083 class result_connection;
00084 class result_creation;
00085 class result_sql_cursor;
00086 }
00087 }
00088
00089
00091
00111 class PQXX_LIBEXPORT result :
00112 private internal::PQAlloc<
00113 const internal::result_data, internal::freemem_result_data>
00114 {
00115 typedef internal::PQAlloc<
00116 const internal::result_data, internal::freemem_result_data> super;
00117 public:
00118 class const_iterator;
00119 class const_fielditerator;
00120 class const_reverse_fielditerator;
00121 class tuple;
00122 class field;
00123 typedef unsigned long size_type;
00124 typedef signed long difference_type;
00125 typedef tuple reference;
00126 typedef const_iterator pointer;
00127
00129
00140 class PQXX_LIBEXPORT tuple
00141 {
00142 public:
00143 typedef unsigned int size_type;
00144 typedef signed int difference_type;
00145 typedef const_fielditerator const_iterator;
00146 typedef const_iterator iterator;
00147 typedef field reference;
00148 typedef const_fielditerator pointer;
00149 typedef const_reverse_fielditerator const_reverse_iterator;
00150 typedef const_reverse_iterator reverse_iterator;
00151
00153 tuple(const result *r, result::size_type i) throw () :
00154 m_Home(r), m_Index(i), m_Begin(0), m_End(r ? r->columns() : 0) {}
00155
00156 ~tuple() throw () {}
00157
00162 bool operator==(const tuple &) const throw ();
00163 bool operator!=(const tuple &rhs) const throw ()
00164 { return !operator==(rhs); }
00166
00167 const_iterator begin() const throw ()
00168 { return const_iterator(*this, m_Begin); }
00169 const_iterator end() const throw ()
00170 { return const_iterator(*this, m_End); }
00171
00176 reference front() const throw () { return field(*this, m_Begin); }
00177 reference back() const throw () { return field(*this, m_End-1); }
00178
00179 const_reverse_fielditerator rbegin() const;
00180 const_reverse_fielditerator rend() const;
00181
00182 reference operator[](size_type i) const throw ()
00183 { return field(*this, m_Begin+i); }
00184 reference operator[](int i) const throw ()
00185 { return operator[](size_type(i)); }
00186 reference operator[](const char f[]) const
00187 { return at(f); }
00188 reference operator[](const PGSTD::string &s) const
00189 { return operator[](s.c_str()); }
00190 reference at(size_type) const throw (range_error);
00191 reference at(int i) const throw (range_error)
00192 { return at(size_type(i)); }
00193 reference at(const char[]) const;
00194 reference at(const PGSTD::string &s) const
00195 { return at(s.c_str()); }
00197
00198 size_type size() const throw () { return m_End-m_Begin; }
00199
00200 void swap(tuple &) throw ();
00201
00202 result::size_type rownumber() const throw () { return m_Index; }
00203
00208
00209 size_type column_number(const PGSTD::string &ColName) const
00210 { return column_number(ColName.c_str()); }
00211
00213 size_type column_number(const char[]) const;
00214
00216 oid column_type(size_type ColNum) const
00217 { return m_Home->column_type(m_Begin+ColNum); }
00218
00220 oid column_type(int ColNum) const
00221 { return column_type(size_type(ColNum)); }
00222
00224 oid column_type(const PGSTD::string &ColName) const
00225 { return column_type(column_number(ColName)); }
00226
00228 oid column_type(const char ColName[]) const
00229 { return column_type(column_number(ColName)); }
00230
00232
00239 oid column_table(size_type ColNum) const
00240 { return m_Home->column_table(m_Begin+ColNum); }
00242
00249 oid column_table(int ColNum) const
00250 { return column_table(size_type(ColNum)); }
00252
00259 oid column_table(const PGSTD::string &ColName) const
00260 { return column_table(column_number(ColName)); }
00261
00263
00273 size_type table_column(size_type ColNum) const
00274 { return m_Home->table_column(m_Begin+ColNum); }
00275
00277 size_type table_column(int ColNum) const
00278 { return table_column(size_type(ColNum)); }
00279
00281 size_type table_column(const PGSTD::string &ColName) const
00282 { return table_column(column_number(ColName)); }
00284
00285 result::size_type num() const { return rownumber(); }
00286
00299 tuple slice(size_type Begin, size_type End) const;
00300
00301
00302 bool empty() const throw ();
00303
00304 protected:
00305 friend class field;
00306 const result *m_Home;
00307 result::size_type m_Index;
00308 size_type m_Begin;
00309 size_type m_End;
00310
00311 private:
00312
00313 tuple();
00314 };
00315
00317
00320 class PQXX_LIBEXPORT field
00321 {
00322 public:
00323 typedef size_t size_type;
00324
00326
00330 field(const tuple &T, tuple::size_type C) throw () :
00331 m_tup(T), m_col(C) {}
00332
00337
00338
00354 bool operator==(const field &) const;
00355
00357
00359 bool operator!=(const field &rhs) const {return !operator==(rhs);}
00361
00366
00367 const char *name() const { return home()->column_name(col()); }
00368
00370 oid type() const { return home()->column_type(col()); }
00371
00373
00380 oid table() const { return home()->column_table(col()); }
00381
00382 tuple::size_type num() const { return col(); }
00383
00385 tuple::size_type table_column() const
00386 { return home()->table_column(col()); }
00388
00393
00394
00399 const char *c_str() const { return home()->GetValue(idx(),col()); }
00400
00402 template<typename T> bool to(T &Obj) const
00403 {
00404 const char *const bytes = c_str();
00405 if (!bytes[0] && is_null()) return false;
00406 from_string(bytes, Obj);
00407 return true;
00408 }
00409
00411 template<typename T> bool operator>>(T &Obj) const
00412 { return to(Obj); }
00413
00414 #ifdef PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
00416 template<> bool to<PGSTD::string>(PGSTD::string &Obj) const;
00417
00419
00422 template<> bool to<const char *>(const char *&Obj) const;
00423 #endif
00424
00426 template<typename T> bool to(T &Obj, const T &Default) const
00427 {
00428 const bool NotNull = to(Obj);
00429 if (!NotNull) Obj = Default;
00430 return NotNull;
00431 }
00432
00434
00437 template<typename T> T as(const T &Default) const
00438 {
00439 T Obj;
00440 to(Obj, Default);
00441 return Obj;
00442 }
00443
00445 template<typename T> T as() const
00446 {
00447 T Obj;
00448 const bool NotNull = to(Obj);
00449 if (!NotNull) Obj = string_traits<T>::null();
00450 return Obj;
00451 }
00452
00453 bool is_null() const { return home()->GetIsNull(idx(), col()); }
00454 size_type size() const throw ()
00455 { return home()->GetLength(idx(),col()); }
00457
00458
00459 private:
00460 const result *home() const throw () { return m_tup.m_Home; }
00461 result::size_type idx() const throw () { return m_tup.m_Index; }
00462
00463 protected:
00464 tuple::size_type col() const throw () { return m_col; }
00465 tuple m_tup;
00466 tuple::size_type m_col;
00467 };
00468
00469 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00470 const tuple,
00471 result::difference_type,
00472 const_iterator,
00473 tuple>
00474 const_iterator_base;
00475
00477
00481 class PQXX_LIBEXPORT const_iterator :
00482 public const_iterator_base,
00483 public tuple
00484 {
00485 public:
00486 typedef const tuple *pointer;
00487 typedef tuple reference;
00488 typedef result::size_type size_type;
00489 typedef result::difference_type difference_type;
00490
00491 const_iterator() throw () : tuple(0,0) {}
00492 const_iterator(const tuple &t) throw () : tuple(t) {}
00493
00509 pointer operator->() const { return this; }
00510 reference operator*() const { return tuple(*this); }
00512
00517 const_iterator operator++(int);
00518 const_iterator &operator++() { ++m_Index; return *this; }
00519 const_iterator operator--(int);
00520 const_iterator &operator--() { --m_Index; return *this; }
00521
00522 const_iterator &operator+=(difference_type i)
00523 { m_Index+=i; return *this; }
00524 const_iterator &operator-=(difference_type i)
00525 { m_Index-=i; return *this; }
00527
00532 bool operator==(const const_iterator &i) const
00533 {return m_Index==i.m_Index;}
00534 bool operator!=(const const_iterator &i) const
00535 {return m_Index!=i.m_Index;}
00536 bool operator<(const const_iterator &i) const
00537 {return m_Index<i.m_Index;}
00538 bool operator<=(const const_iterator &i) const
00539 {return m_Index<=i.m_Index;}
00540 bool operator>(const const_iterator &i) const
00541 {return m_Index>i.m_Index;}
00542 bool operator>=(const const_iterator &i) const
00543 {return m_Index>=i.m_Index;}
00545
00550 inline const_iterator operator+(difference_type) const;
00551 friend const_iterator
00552 operator+(difference_type, const_iterator);
00553 inline const_iterator operator-(difference_type) const;
00554 inline difference_type operator-(const_iterator) const;
00556
00557 private:
00558 friend class pqxx::result;
00559 const_iterator(const pqxx::result *r, result::size_type i) throw () :
00560 tuple(r, i) {}
00561 };
00562
00563 typedef const_iterator iterator;
00564
00565 class PQXX_LIBEXPORT const_reverse_iterator : private const_iterator
00566 {
00567 public:
00568 typedef pqxx::result::const_iterator super;
00569 typedef pqxx::result::const_iterator iterator_type;
00570 using iterator_type::iterator_category;
00571 using iterator_type::difference_type;
00572 using iterator_type::pointer;
00573 #ifndef _MSC_VER
00574 using iterator_type::value_type;
00575 using iterator_type::reference;
00576 #else
00577
00578 typedef const tuple &reference;
00579 typedef tuple value_type;
00580 #endif
00581
00582 const_reverse_iterator(const const_reverse_iterator &rhs) :
00583 const_iterator(rhs) {}
00584 explicit const_reverse_iterator(const const_iterator &rhs) :
00585 const_iterator(rhs) { super::operator--(); }
00586
00587 iterator_type base() const throw ();
00588
00593 using const_iterator::operator->;
00594 using const_iterator::operator*;
00596
00601 const_reverse_iterator &operator=(const const_reverse_iterator &r)
00602 { iterator_type::operator=(r); return *this; }
00603 const_reverse_iterator operator++()
00604 { iterator_type::operator--(); return *this; }
00605 const_reverse_iterator operator++(int);
00606 const_reverse_iterator &operator--()
00607 { iterator_type::operator++(); return *this; }
00608 const_reverse_iterator operator--(int);
00609 const_reverse_iterator &operator+=(difference_type i)
00610 { iterator_type::operator-=(i); return *this; }
00611 const_reverse_iterator &operator-=(difference_type i)
00612 { iterator_type::operator+=(i); return *this; }
00614
00619 const_reverse_iterator operator+(difference_type i) const
00620 { return const_reverse_iterator(base()-i); }
00621 const_reverse_iterator operator-(difference_type i)
00622 { return const_reverse_iterator(base()+i); }
00623 difference_type operator-(const const_reverse_iterator &rhs) const
00624 { return rhs.const_iterator::operator-(*this); }
00626
00631 bool operator==(const const_reverse_iterator &rhs) const throw ()
00632 { return iterator_type::operator==(rhs); }
00633 bool operator!=(const const_reverse_iterator &rhs) const throw ()
00634 { return !operator==(rhs); }
00635
00636 bool operator<(const const_reverse_iterator &rhs) const
00637 { return iterator_type::operator>(rhs); }
00638 bool operator<=(const const_reverse_iterator &rhs) const
00639 { return iterator_type::operator>=(rhs); }
00640 bool operator>(const const_reverse_iterator &rhs) const
00641 { return iterator_type::operator<(rhs); }
00642 bool operator>=(const const_reverse_iterator &rhs) const
00643 { return iterator_type::operator<=(rhs); }
00645 };
00646
00647 typedef const_reverse_iterator reverse_iterator;
00648
00649 class PQXX_LIBEXPORT const_fielditerator :
00650 public PGSTD::iterator<PGSTD::random_access_iterator_tag,
00651 const field,
00652 tuple::size_type>,
00653 public field
00654 {
00655 typedef PGSTD::iterator<PGSTD::random_access_iterator_tag,
00656 const field,
00657 tuple::size_type> it;
00658 public:
00659 using it::pointer;
00660 typedef tuple::size_type size_type;
00661 typedef tuple::difference_type difference_type;
00662 typedef field reference;
00663
00664 const_fielditerator(const tuple &T, tuple::size_type C) throw () :
00665 field(T, C) {}
00666 const_fielditerator(const field &F) throw () : field(F) {}
00667
00672 pointer operator->() const { return this; }
00673 reference operator*() const { return field(*this); }
00675
00680 const_fielditerator operator++(int);
00681 const_fielditerator &operator++() { ++m_col; return *this; }
00682 const_fielditerator operator--(int);
00683 const_fielditerator &operator--() { --m_col; return *this; }
00684
00685 const_fielditerator &operator+=(difference_type i)
00686 { m_col+=i; return *this; }
00687 const_fielditerator &operator-=(difference_type i)
00688 { m_col-=i; return *this; }
00690
00695 bool operator==(const const_fielditerator &i) const
00696 {return col()==i.col();}
00697 bool operator!=(const const_fielditerator &i) const
00698 {return col()!=i.col();}
00699 bool operator<(const const_fielditerator &i) const
00700 {return col()<i.col();}
00701 bool operator<=(const const_fielditerator &i) const
00702 {return col()<=i.col();}
00703 bool operator>(const const_fielditerator &i) const
00704 {return col()>i.col();}
00705 bool operator>=(const const_fielditerator &i) const
00706 {return col()>=i.col();}
00708
00713 inline const_fielditerator operator+(difference_type) const;
00714
00715 friend const_fielditerator operator+(difference_type,
00716 const_fielditerator);
00717
00718 inline const_fielditerator operator-(difference_type) const;
00719 inline difference_type operator-(const_fielditerator) const;
00721 };
00722
00723 class PQXX_LIBEXPORT const_reverse_fielditerator : private const_fielditerator
00724 {
00725 public:
00726 typedef const_fielditerator super;
00727 typedef const_fielditerator iterator_type;
00728 using iterator_type::iterator_category;
00729 using iterator_type::difference_type;
00730 using iterator_type::pointer;
00731 #ifndef _MSC_VER
00732 using iterator_type::value_type;
00733 using iterator_type::reference;
00734 #else
00735
00736 typedef field value_type;
00737 typedef const field &reference;
00738 #endif
00739
00740 const_reverse_fielditerator(const const_reverse_fielditerator &r) :
00741 const_fielditerator(r) {}
00742 explicit
00743 const_reverse_fielditerator(const super &rhs) throw() :
00744 const_fielditerator(rhs) { super::operator--(); }
00745
00746 iterator_type base() const throw ();
00747
00752 using iterator_type::operator->;
00753 using iterator_type::operator*;
00755
00760 const_reverse_fielditerator &
00761 operator=(const const_reverse_fielditerator &r)
00762 { iterator_type::operator=(r); return *this; }
00763 const_reverse_fielditerator operator++()
00764 { iterator_type::operator--(); return *this; }
00765 const_reverse_fielditerator operator++(int);
00766 const_reverse_fielditerator &operator--()
00767 { iterator_type::operator++(); return *this; }
00768 const_reverse_fielditerator operator--(int);
00769 const_reverse_fielditerator &operator+=(difference_type i)
00770 { iterator_type::operator-=(i); return *this; }
00771 const_reverse_fielditerator &operator-=(difference_type i)
00772 { iterator_type::operator+=(i); return *this; }
00774
00779 const_reverse_fielditerator operator+(difference_type i) const
00780 { return const_reverse_fielditerator(base()-i); }
00781 const_reverse_fielditerator operator-(difference_type i)
00782 { return const_reverse_fielditerator(base()+i); }
00783 difference_type
00784 operator-(const const_reverse_fielditerator &rhs) const
00785 { return rhs.const_fielditerator::operator-(*this); }
00787
00792 bool
00793 operator==(const const_reverse_fielditerator &rhs) const throw ()
00794 { return iterator_type::operator==(rhs); }
00795 bool
00796 operator!=(const const_reverse_fielditerator &rhs) const throw ()
00797 { return !operator==(rhs); }
00798
00799 bool operator<(const const_reverse_fielditerator &rhs) const
00800 { return iterator_type::operator>(rhs); }
00801 bool operator<=(const const_reverse_fielditerator &rhs) const
00802 { return iterator_type::operator>=(rhs); }
00803 bool operator>(const const_reverse_fielditerator &rhs) const
00804 { return iterator_type::operator<(rhs); }
00805 bool operator>=(const const_reverse_fielditerator &rhs) const
00806 { return iterator_type::operator<=(rhs); }
00808 };
00809
00810
00811 result() throw () : super(), m_data(0) {}
00812 result(const result &rhs) throw () :
00813 super(rhs), m_data(rhs.m_data) {}
00814
00815 result &operator=(const result &rhs) throw ()
00816 { super::operator=(rhs); m_data=rhs.m_data; return *this; }
00817
00822 bool operator==(const result &) const throw ();
00823 bool operator!=(const result &rhs) const throw ()
00824 { return !operator==(rhs); }
00826
00827 const_reverse_iterator rbegin() const
00828 { return const_reverse_iterator(end()); }
00829 const_reverse_iterator rend() const
00830 { return const_reverse_iterator(begin()); }
00831
00832 const_iterator begin() const throw ()
00833 { return const_iterator(this, 0); }
00834 inline const_iterator end() const throw ();
00835
00836 reference front() const throw () { return tuple(this,0); }
00837 reference back() const throw () {return tuple(this,size()-1);}
00838
00839 size_type size() const throw ();
00840 bool empty() const throw ();
00841 size_type capacity() const throw () { return size(); }
00842
00843 void swap(result &) throw ();
00844
00845 const tuple operator[](size_type i) const throw ()
00846 { return tuple(this, i); }
00847 const tuple at(size_type) const throw (range_error);
00848
00849 void clear() throw () { super::reset(); m_data = 0; }
00850
00855
00856 tuple::size_type columns() const throw ();
00857
00859 tuple::size_type column_number(const char ColName[]) const;
00860
00862 tuple::size_type column_number(const PGSTD::string &Name) const
00863 {return column_number(Name.c_str());}
00864
00866 const char *column_name(tuple::size_type Number) const;
00867
00869 oid column_type(tuple::size_type ColNum) const;
00871 oid column_type(int ColNum) const
00872 { return column_type(tuple::size_type(ColNum)); }
00873
00875 oid column_type(const PGSTD::string &ColName) const
00876 { return column_type(column_number(ColName)); }
00877
00879 oid column_type(const char ColName[]) const
00880 { return column_type(column_number(ColName)); }
00881
00883
00890 oid column_table(tuple::size_type ColNum) const;
00891
00893
00900 oid column_table(int ColNum) const
00901 { return column_table(tuple::size_type(ColNum)); }
00902
00904
00911 oid column_table(const PGSTD::string &ColName) const
00912 { return column_table(column_number(ColName)); }
00913
00915 tuple::size_type table_column(tuple::size_type ColNum) const;
00916
00918 tuple::size_type table_column(int ColNum) const
00919 { return table_column(tuple::size_type(ColNum)); }
00920
00922 tuple::size_type table_column(const PGSTD::string &ColName) const
00923 { return table_column(column_number(ColName)); }
00925
00927 const PGSTD::string &query() const throw ();
00928
00930
00933 oid inserted_oid() const;
00934
00935
00937
00940 size_type affected_rows() const;
00941
00942
00943 private:
00944 friend class pqxx::result::field;
00945 const char *GetValue(size_type Row, tuple::size_type Col) const;
00946 bool GetIsNull(size_type Row, tuple::size_type Col) const;
00947 field::size_type GetLength(size_type, tuple::size_type) const throw ();
00948
00949 friend class pqxx::internal::gate::result_creation;
00950 result(internal::pq::PGresult *rhs,
00951 int protocol,
00952 const PGSTD::string &Query,
00953 int encoding_code);
00954 void PQXX_PRIVATE CheckStatus() const;
00955
00956 friend class pqxx::internal::gate::result_connection;
00957 bool operator!() const throw () { return !m_data; }
00958 operator bool() const throw () { return m_data != 0; }
00959
00960 void PQXX_PRIVATE ThrowSQLError(const PGSTD::string &Err,
00961 const PGSTD::string &Query) const;
00962 int PQXX_PRIVATE errorposition() const throw ();
00963 PGSTD::string PQXX_PRIVATE StatusError() const;
00964
00965 friend class pqxx::internal::gate::result_sql_cursor;
00966 const char *CmdStatus() const throw ();
00967
00969 pqxx::internal::pq::PGresult *m_data;
00970
00971 static const PGSTD::string PQXX_PRIVATE s_empty_string;
00972 };
00973
00974
00976
00996 template<typename CHAR>
00997 inline PGSTD::basic_ostream<CHAR> &operator<<(
00998 PGSTD::basic_ostream<CHAR> &S, const pqxx::result::field &F)
00999 {
01000 S.write(F.c_str(), F.size());
01001 return S;
01002 }
01003
01004
01006 template<typename T>
01007 inline void from_string(const result::field &F, T &Obj)
01008 { from_string(F.c_str(), Obj, F.size()); }
01009
01011 template<>
01012 inline PGSTD::string to_string(const result::field &Obj)
01013 { return PGSTD::string(Obj.c_str(), Obj.size()); }
01014
01015
01017 template<>
01018 inline bool result::field::to<PGSTD::string>(PGSTD::string &Obj) const
01019 {
01020 const char *const bytes = c_str();
01021 if (!bytes[0] && is_null()) return false;
01022 Obj = PGSTD::string(bytes, size());
01023 return true;
01024 }
01025
01027
01032 template<>
01033 inline bool result::field::to<const char *>(const char *&Obj) const
01034 {
01035 if (is_null()) return false;
01036 Obj = c_str();
01037 return true;
01038 }
01039
01040
01041 inline result::tuple::const_reverse_iterator result::tuple::rbegin() const
01042 { return const_reverse_fielditerator(end()); }
01043 inline result::tuple::const_reverse_iterator result::tuple::rend() const
01044 { return const_reverse_fielditerator(begin()); }
01045
01046 inline result::const_iterator
01047 result::const_iterator::operator+(difference_type o) const
01048 { return const_iterator(m_Home, m_Index + o); }
01049
01050 inline result::const_iterator
01051 operator+(result::const_iterator::difference_type o, result::const_iterator i)
01052 { return i + o; }
01053
01054 inline result::const_iterator
01055 result::const_iterator::operator-(difference_type o) const
01056 { return const_iterator(m_Home, m_Index - o); }
01057
01058 inline result::const_iterator::difference_type
01059 result::const_iterator::operator-(const_iterator i) const
01060 { return num()-i.num(); }
01061
01062 inline result::const_iterator result::end() const throw ()
01063 { return const_iterator(this, size()); }
01064
01065
01066 inline result::const_reverse_iterator
01067 operator+(result::const_reverse_iterator::difference_type n,
01068 const result::const_reverse_iterator &i)
01069 { return result::const_reverse_iterator(i.base() - n); }
01070
01071 inline result::const_fielditerator
01072 result::const_fielditerator::operator+(difference_type o) const
01073 { return const_fielditerator(m_tup, col() + o); }
01074
01075 inline result::const_fielditerator
01076 operator+(result::const_fielditerator::difference_type o,
01077 result::const_fielditerator i)
01078 { return i + o; }
01079
01080 inline result::const_fielditerator
01081 result::const_fielditerator::operator-(difference_type o) const
01082 { return const_fielditerator(m_tup, col() - o); }
01083
01084 inline result::const_fielditerator::difference_type
01085 result::const_fielditerator::operator-(const_fielditerator i) const
01086 { return num()-i.num(); }
01087
01088
01089 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01090 class field_streambuf :
01091 #ifdef PQXX_HAVE_STREAMBUF
01092 public PGSTD::basic_streambuf<CHAR, TRAITS>
01093 #else
01094 public PGSTD::streambuf
01095 #endif
01096 {
01097 public:
01098 typedef CHAR char_type;
01099 typedef TRAITS traits_type;
01100 typedef typename traits_type::int_type int_type;
01101 #ifdef PQXX_HAVE_STREAMBUF
01102 typedef typename traits_type::pos_type pos_type;
01103 typedef typename traits_type::off_type off_type;
01104 #else
01105 typedef streamoff off_type;
01106 typedef streampos pos_type;
01107 #endif
01108 typedef PGSTD::ios::openmode openmode;
01109 typedef PGSTD::ios::seekdir seekdir;
01110
01111 explicit field_streambuf(const result::field &F) :
01112 m_Field(F)
01113 {
01114 initialize();
01115 }
01116
01117 #ifdef PQXX_HAVE_STREAMBUF
01118 protected:
01119 #endif
01120 virtual int sync() { return traits_type::eof(); }
01121
01122 protected:
01123 virtual pos_type seekoff(off_type, seekdir, openmode)
01124 { return traits_type::eof(); }
01125 virtual pos_type seekpos(pos_type, openmode) {return traits_type::eof();}
01126 virtual int_type overflow(int_type) { return traits_type::eof(); }
01127 virtual int_type underflow() { return traits_type::eof(); }
01128
01129 private:
01130 const result::field &m_Field;
01131
01132 int_type initialize()
01133 {
01134 char_type *G =
01135 reinterpret_cast<char_type *>(const_cast<char *>(m_Field.c_str()));
01136 setg(G, G, G + m_Field.size());
01137 return int_type(m_Field.size());
01138 }
01139 };
01140
01141
01143
01151 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
01152 class basic_fieldstream :
01153 #ifdef PQXX_HAVE_STREAMBUF
01154 public PGSTD::basic_istream<CHAR, TRAITS>
01155 #else
01156 public PGSTD::istream
01157 #endif
01158 {
01159 #ifdef PQXX_HAVE_STREAMBUF
01160 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
01161 #else
01162 typedef PGSTD::istream super;
01163 #endif
01164
01165 public:
01166 typedef CHAR char_type;
01167 typedef TRAITS traits_type;
01168 typedef typename traits_type::int_type int_type;
01169 typedef typename traits_type::pos_type pos_type;
01170 typedef typename traits_type::off_type off_type;
01171
01172 basic_fieldstream(const result::field &F) : super(0), m_Buf(F)
01173 { super::init(&m_Buf); }
01174
01175 private:
01176 field_streambuf<CHAR, TRAITS> m_Buf;
01177 };
01178
01179 typedef basic_fieldstream<char> fieldstream;
01180
01181 }
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199 #include "pqxx/compiler-internal-post.hxx"
01200
01201 #endif
01202