Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

cursor.hxx

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------- 00002 * 00003 * FILE 00004 * pqxx/cursor.hxx 00005 * 00006 * DESCRIPTION 00007 * definition of the iterator/container-style cursor classes 00008 * C++-style wrappers for SQL cursors 00009 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead. 00010 * 00011 * Copyright (c) 2004, Jeroen T. Vermeulen <jtv@xs4all.nl> 00012 * 00013 * See COPYING for copyright license. If you did not receive a file called 00014 * COPYING with this source code, please notify the distributor of this mistake, 00015 * or contact the author. 00016 * 00017 *------------------------------------------------------------------------- 00018 */ 00019 #include "pqxx/libcompiler.h" 00020 00021 #include <limits> 00022 #include <string> 00023 00024 #include "pqxx/result" 00025 00026 00027 namespace pqxx 00028 { 00029 class transaction_base; 00030 00032 00036 class PQXX_LIBEXPORT cursor_base 00037 { 00038 public: 00039 typedef result::size_type size_type; 00040 00041 operator void *() const { return m_done ? 0 : &s_dummy; } //[t81] 00042 bool operator!() const { return m_done; } //[t81] 00043 00044 static size_type all() throw (); //[t81] 00045 static size_type next() throw () { return 1; } //[t81] 00046 static size_type prior() throw () { return -1; } //[] 00047 static size_type backward_all() throw (); //[] 00048 00049 const PGSTD::string &name() const throw () { return m_name; } //[t81] 00050 00051 protected: 00052 cursor_base(transaction_base *context, const PGSTD::string &cname) : 00053 m_context(context), m_done(false), m_name(cname) 00054 { 00055 m_name += "_"; 00056 m_name += to_string(get_unique_cursor_num()); 00057 } 00058 00059 transaction_base *m_context; 00060 bool m_done; 00061 00062 private: 00063 int get_unique_cursor_num(); 00064 00065 PGSTD::string m_name; 00066 00068 static unsigned char s_dummy; 00069 00071 cursor_base(); 00073 cursor_base(const cursor_base &); 00075 cursor_base &operator=(const cursor_base &); 00076 }; 00077 00078 00079 inline cursor_base::size_type cursor_base::all() throw () 00080 { 00081 #ifdef _MSC_VER 00082 // Microsoft's compiler defines max() and min() macros! Others may as well 00083 return INT_MAX; 00084 #else 00085 return PGSTD::numeric_limits<size_type>::max(); 00086 #endif 00087 } 00088 00089 inline cursor_base::size_type cursor_base::backward_all() throw () 00090 { 00091 #ifdef _MSC_VER 00092 // Microsoft's compiler defines max() and min() macros! Others may as well 00093 return INT_MIN + 1; 00094 #else 00095 return PGSTD::numeric_limits<size_type>::min() + 1; 00096 #endif 00097 } 00098 00100 00108 class PQXX_LIBEXPORT icursorstream : public cursor_base 00109 { 00110 public: 00112 00123 icursorstream(transaction_base &context, 00124 const PGSTD::string &query, 00125 const PGSTD::string &basename, 00126 size_type stride=1); //[t81] 00127 00129 00133 icursorstream &get(result &res) { res = fetch(); return *this; } //[] 00135 00139 icursorstream &operator>>(result &res) { return get(res); } //[t81] 00141 icursorstream &ignore(PGSTD::streamsize n=1); //[] 00142 00144 00147 void set_stride(size_type stride); //[t81] 00148 00149 private: 00150 void declare(const PGSTD::string &query); 00151 result fetch(); 00152 00153 size_type m_stride; 00154 }; 00155 00156 00158 00175 class PQXX_LIBEXPORT icursor_iterator : 00176 public PGSTD::iterator<PGSTD::input_iterator_tag, 00177 result, 00178 cursor_base::size_type, 00179 const result *, 00180 const result &> 00181 { 00182 public: 00183 typedef icursorstream istream_type; 00184 typedef istream_type::size_type size_type; 00185 00186 icursor_iterator() : m_stream(0), m_here(), m_fresh(true), m_pos(0){} //[] 00187 icursor_iterator(istream_type &s) : //[] 00188 m_stream(&s), m_here(), m_fresh(false), m_pos(0) {} 00189 icursor_iterator(const icursor_iterator &rhs) : //[] 00190 m_stream(rhs.m_stream), 00191 m_here(rhs.m_here), 00192 m_fresh(rhs.m_fresh), 00193 m_pos(rhs.m_pos) 00194 {} 00195 00196 const result &operator*() const { refresh(); return m_here; } //[] 00197 const result *operator->() const { refresh(); return &m_here; } //[] 00198 00199 icursor_iterator &operator++() { read(); return *this; } //[] 00200 00201 icursor_iterator operator++(int) //[] 00202 { icursor_iterator old(*this); read(); return old; } 00203 00204 icursor_iterator &operator+=(size_type n) //[] 00205 { 00206 m_stream->ignore(n); 00207 m_fresh = false; 00208 m_pos += n; 00209 return *this; 00210 } 00211 00212 icursor_iterator &operator=(const icursor_iterator &rhs) //[] 00213 { 00214 m_here = rhs.m_here; // (Already protected against self-assignment) 00215 m_stream = rhs.m_stream; // (Does not throw, so we're exception-safe) 00216 m_fresh = rhs.m_fresh; 00217 m_pos = rhs.m_pos; 00218 return *this; 00219 } 00220 00221 bool operator==(const icursor_iterator &rhs) const throw () //[] 00222 { 00223 return (m_stream==rhs.m_stream && m_pos==rhs.m_pos) || 00224 (m_here.empty() && rhs.m_here.empty()); 00225 } 00226 bool operator!=(const icursor_iterator &rhs) const throw () //[] 00227 { return !operator==(rhs); } 00228 00229 private: 00230 void read() const 00231 { 00232 m_stream->get(m_here); 00233 m_fresh = true; 00234 ++m_pos; 00235 } 00236 void refresh() const { if (!m_fresh) read(); } 00237 icursorstream *m_stream; 00238 mutable result m_here; 00239 mutable bool m_fresh; 00240 mutable result::size_type m_pos; 00241 }; 00242 00243 00244 } // namespace pqxx 00245

Generated on Mon Aug 9 01:47:22 2004 for libpqxx by doxygen 1.3.8