00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef PQXX_CURSOR_H
00019 #define PQXX_CURSOR_H
00020
00021 #include "pqxx/result.h"
00022 #include "pqxx/transaction_base.h"
00023 #include "pqxx/util.h"
00024
00025
00026
00027
00028 namespace pqxx
00029 {
00030 class result;
00031
00033
00059 class PQXX_LIBEXPORT Cursor
00060 {
00061 public:
00062
00063
00064
00065 typedef result::size_type size_type;
00066
00067 enum pos { pos_unknown = -1, pos_start = 0 };
00068
00070 struct PQXX_LIBEXPORT unknown_position : PGSTD::runtime_error
00071 {
00072 unknown_position(const PGSTD::string &cursorname) :
00073 PGSTD::runtime_error("Position for cursor '" + cursorname + "' "
00074 "is unknown")
00075 {
00076 }
00077 };
00078
00079
00081
00082 * @param T is the transaction that this cursor lives in.
00083 * @param Query defines a data set that the cursor should traverse.
00084 * @param BaseName optional name for the cursor, must begin with a letter
00085 * and contain letters and digits only.
00086 * @param Count the stride of the cursor, ie. the number of rows fetched at a
00087 * time. This defaults to 1.
00088 */
00089 template<typename TRANSACTION>
00090 Cursor(TRANSACTION &T,
00091 const char Query[],
00092 const PGSTD::string &BaseName="cur",
00093 size_type Count=NEXT()) :
00094 m_Trans(T),
00095 m_Name(),
00096 m_Count(Count),
00097 m_Done(false),
00098 m_Pos(pos_start),
00099 m_Size(pos_unknown)
00100 {
00101
00102 error_permitted_isolation_level(typename TRANSACTION::isolation_tag());
00103 init(BaseName, Query);
00104 }
00105
00107
00137 template<typename TRANSACTION>
00138 Cursor(TRANSACTION &T,
00139 const result::field &Name,
00140 size_type Count=NEXT()) :
00141 m_Trans(T),
00142 m_Name(Name.c_str()),
00143 m_Count(Count),
00144 m_Done(false),
00145 m_Pos(pos_unknown),
00146 m_Size(pos_unknown)
00147 {
00148
00149 error_permitted_isolation_level(typename TRANSACTION::isolation_tag());
00150 }
00151
00153 size_type SetCount(size_type);
00154
00156
00165 result Fetch(size_type Count);
00166
00168
00176 size_type Move(size_type Count);
00177
00178 void MoveTo(size_type);
00179
00181
00185 static size_type ALL() throw ()
00186 { return PGSTD::numeric_limits<result::size_type>::max(); }
00187
00189 static size_type NEXT() throw () { return 1; }
00190
00192 static size_type PRIOR() throw () { return -1; }
00193
00196
00200 static size_type BACKWARD_ALL() throw ()
00201 { return PGSTD::numeric_limits<result::size_type>::min() + 1; }
00202
00204
00211 Cursor &operator>>(result &);
00212
00214 operator bool() const throw () { return !m_Done; }
00216
00217
00219 Cursor &operator+=(size_type N) { Move(N); return *this;}
00221
00222
00224
00235 size_type size() const throw () { return m_Size; }
00236
00238
00245 size_type Pos() const throw (unknown_position)
00246 { if (m_Pos==pos_unknown) throw unknown_position(m_Name); return m_Pos; }
00247
00248
00249 private:
00250 static PGSTD::string OffsetString(size_type);
00251 void init(const PGSTD::string &BaseName, const char Query[]);
00252 PGSTD::string MakeFetchCmd(size_type) const;
00253 size_type NormalizedMove(size_type Intended, size_type Actual);
00254
00256
00260 template<typename ISOLATIONTAG>
00261 static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00262
00263 transaction_base &m_Trans;
00264 PGSTD::string m_Name;
00265 size_type m_Count;
00266 bool m_Done;
00267 size_type m_Pos;
00268 size_type m_Size;
00269
00270
00271 Cursor(const Cursor &);
00272 Cursor &operator=(const Cursor &);
00273 };
00274
00275 template<> inline void
00276 Cursor::error_permitted_isolation_level(isolation_traits<serializable>) throw ()
00277 {}
00278
00279 }
00280
00281 #endif
00282