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 enum { dist_next=1 };
00070
00071 public:
00072 typedef result::size_type size_type;
00073
00074 enum pos { pos_unknown = -1, pos_start = 0 };
00075
00077 struct PQXX_LIBEXPORT unknown_position : PGSTD::runtime_error
00078 {
00079 unknown_position(const PGSTD::string &cursorname) :
00080 PGSTD::runtime_error("Position for cursor '" + cursorname + "' "
00081 "is unknown")
00082 {
00083 }
00084 };
00085
00087
00095 template<typename TRANSACTION>
00096 Cursor(TRANSACTION &T,
00097 const char Query[],
00098 const PGSTD::string &BaseName="cur",
00099 size_type Count=dist_next) :
00100 m_Trans(T),
00101 m_Name(),
00102 m_Count(Count),
00103 m_Done(false),
00104 m_Pos(pos_start),
00105 m_Size(pos_unknown)
00106 {
00107
00108 error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00109 init(BaseName, Query);
00110 }
00111
00113
00143 template<typename TRANSACTION>
00144 Cursor(TRANSACTION &T,
00145 const result::field &Name,
00146 size_type Count=dist_next) :
00147 m_Trans(T),
00148 m_Name(Name.c_str()),
00149 m_Count(Count),
00150 m_Done(false),
00151 m_Pos(pos_unknown),
00152 m_Size(pos_unknown)
00153 {
00154
00155 error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00156 }
00157
00159 size_type SetCount(size_type);
00160
00162
00171 result Fetch(size_type Count);
00172
00174
00182 size_type Move(size_type Count);
00183
00184 void MoveTo(size_type);
00185
00187
00191 static size_type ALL() throw ();
00192
00194 static size_type NEXT() throw () { return dist_next; }
00195
00197 static size_type PRIOR() throw () { return -1; }
00198
00201
00205 static size_type BACKWARD_ALL() throw ();
00206
00208
00215 Cursor &operator>>(result &);
00216
00218 operator bool() const throw () { return !m_Done; }
00220 bool operator!() const throw () { return m_Done; }
00221
00223 Cursor &operator+=(size_type N) { Move(N); return *this;}
00225 Cursor &operator-=(size_type N) { Move(-N); return *this;}
00226
00228
00239 size_type size() const throw () { return m_Size; }
00240
00242
00249 size_type Pos() const throw (unknown_position)
00250 { if (m_Pos==pos_unknown) throw unknown_position(m_Name); return m_Pos; }
00251
00252
00253 private:
00254 static PGSTD::string OffsetString(size_type);
00255 void init(const PGSTD::string &BaseName, const char Query[]);
00256 PGSTD::string MakeFetchCmd(size_type) const;
00257 size_type NormalizedMove(size_type Intended, size_type Actual);
00258
00259 #ifndef PQXX_WORKAROUND_VC7
00260
00261
00265 template<typename ISOLATIONTAG>
00266 static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00267
00268 #if defined(__SUNPRO_CC)
00269
00270 template<> static void
00271 error_permitted_level(isolation_traits<serializable>) throw() {}
00272 #endif // __SUNPRO_CC
00273 #else
00274
00275 template<> static inline void
00276 error_permitted_isolation_level(isolation_traits<serializable>) throw ();
00277 #endif
00278
00279 transaction_base &m_Trans;
00280 PGSTD::string m_Name;
00281 size_type m_Count;
00282 bool m_Done;
00283 size_type m_Pos;
00284 size_type m_Size;
00285
00286
00287 Cursor(const Cursor &);
00288 Cursor &operator=(const Cursor &);
00289 };
00290
00291 template<> inline void
00292 Cursor::error_permitted_isolation_level(isolation_traits<serializable>) throw ()
00293 {}
00294
00295 }
00296
00297 #endif
00298