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
00032
00033
00034 #ifdef __MWERKS__
00035 #pragma defer_defarg_parsing on
00036 #endif
00037
00038
00040
00067 class PQXX_LIBEXPORT Cursor
00068 {
00069 public:
00070
00071
00072
00073 typedef result::size_type size_type;
00074
00075 enum pos { pos_unknown = -1, pos_start = 0 };
00076
00078 struct PQXX_LIBEXPORT unknown_position : PGSTD::runtime_error
00079 {
00080 unknown_position(const PGSTD::string &cursorname) :
00081 PGSTD::runtime_error("Position for cursor '" + cursorname + "' "
00082 "is unknown")
00083 {
00084 }
00085 };
00086
00087
00089
00097 template<typename TRANSACTION>
00098 Cursor(TRANSACTION &T,
00099 const char Query[],
00100 const PGSTD::string &BaseName="cur",
00101 size_type Count=NEXT()) :
00102 m_Trans(T),
00103 m_Name(),
00104 m_Count(Count),
00105 m_Done(false),
00106 m_Pos(pos_start),
00107 m_Size(pos_unknown)
00108 {
00109
00110 error_permitted_isolation_level(typename TRANSACTION::isolation_tag());
00111 init(BaseName, Query);
00112 }
00113
00115
00145 template<typename TRANSACTION>
00146 Cursor(TRANSACTION &T,
00147 const result::field &Name,
00148 size_type Count=NEXT()) :
00149 m_Trans(T),
00150 m_Name(Name.c_str()),
00151 m_Count(Count),
00152 m_Done(false),
00153 m_Pos(pos_unknown),
00154 m_Size(pos_unknown)
00155 {
00156
00157 error_permitted_isolation_level(typename TRANSACTION::isolation_tag());
00158 }
00159
00161 size_type SetCount(size_type);
00162
00164
00173 result Fetch(size_type Count);
00174
00176
00184 size_type Move(size_type Count);
00185
00186 void MoveTo(size_type);
00187
00189
00193 static size_type ALL() throw ();
00194
00196 static size_type NEXT() throw () { return 1; }
00197
00199 static size_type PRIOR() throw () { return -1; }
00200
00203
00207 static size_type BACKWARD_ALL() throw ();
00208
00210
00217 Cursor &operator>>(result &);
00218
00220 operator bool() const throw () { return !m_Done; }
00222 bool operator!() const throw () { return m_Done; }
00223
00225 Cursor &operator+=(size_type N) { Move(N); return *this;}
00227 Cursor &operator-=(size_type N) { Move(-N); return *this;}
00228
00230
00241 size_type size() const throw () { return m_Size; }
00242
00244
00251 size_type Pos() const throw (unknown_position)
00252 { if (m_Pos==pos_unknown) throw unknown_position(m_Name); return m_Pos; }
00253
00254
00255 private:
00256 static PGSTD::string OffsetString(size_type);
00257 void init(const PGSTD::string &BaseName, const char Query[]);
00258 PGSTD::string MakeFetchCmd(size_type) const;
00259 size_type NormalizedMove(size_type Intended, size_type Actual);
00260
00262
00266 template<typename ISOLATIONTAG>
00267 static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00268
00269 transaction_base &m_Trans;
00270 PGSTD::string m_Name;
00271 size_type m_Count;
00272 bool m_Done;
00273 size_type m_Pos;
00274 size_type m_Size;
00275
00276
00277 Cursor(const Cursor &);
00278 Cursor &operator=(const Cursor &);
00279 };
00280
00281 template<> inline void
00282 Cursor::error_permitted_isolation_level(isolation_traits<serializable>) throw ()
00283 {}
00284
00285 }
00286
00287 #endif
00288