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 typedef result::size_type size_type;
00071
00072 enum pos { pos_unknown = -1, pos_start = 0 };
00073
00075 struct PQXX_LIBEXPORT unknown_position : PGSTD::runtime_error
00076 {
00077 unknown_position(const PGSTD::string &cursorname) :
00078 PGSTD::runtime_error("Position for cursor '" + cursorname + "' "
00079 "is unknown")
00080 {
00081 }
00082 };
00083
00085
00093 template<typename TRANSACTION>
00094 Cursor(TRANSACTION &T,
00095 const char Query[],
00096 const PGSTD::string &BaseName="cur",
00097 size_type Count=NEXT()) :
00098 m_Trans(T),
00099 m_Name(),
00100 m_Count(Count),
00101 m_Done(false),
00102 m_Pos(pos_start),
00103 m_Size(pos_unknown)
00104 {
00105
00106 error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00107 init(BaseName, Query);
00108 }
00109
00111
00141 template<typename TRANSACTION>
00142 Cursor(TRANSACTION &T,
00143 const result::field &Name,
00144 size_type Count=NEXT()) :
00145 m_Trans(T),
00146 m_Name(Name.c_str()),
00147 m_Count(Count),
00148 m_Done(false),
00149 m_Pos(pos_unknown),
00150 m_Size(pos_unknown)
00151 {
00152
00153 error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00154 }
00155
00157 size_type SetCount(size_type);
00158
00160
00169 result Fetch(size_type Count);
00170
00172
00180 size_type Move(size_type Count);
00181
00182 void MoveTo(size_type);
00183
00185
00189 static size_type ALL() throw ();
00190
00192 static size_type NEXT() throw () { return 1; }
00193
00195 static size_type PRIOR() throw () { return -1; }
00196
00199
00203 static size_type BACKWARD_ALL() throw ();
00204
00206
00213 Cursor &operator>>(result &);
00214
00216 operator bool() const throw () { return !m_Done; }
00218 bool operator!() const throw () { return m_Done; }
00219
00221 Cursor &operator+=(size_type N) { Move(N); return *this;}
00223 Cursor &operator-=(size_type N) { Move(-N); return *this;}
00224
00226
00237 size_type size() const throw () { return m_Size; }
00238
00240
00247 size_type Pos() const throw (unknown_position)
00248 { if (m_Pos==pos_unknown) throw unknown_position(m_Name); return m_Pos; }
00249
00250
00251 private:
00252 static PGSTD::string OffsetString(size_type);
00253 void init(const PGSTD::string &BaseName, const char Query[]);
00254 PGSTD::string MakeFetchCmd(size_type) const;
00255 size_type NormalizedMove(size_type Intended, size_type Actual);
00256
00257 #ifndef PQXX_WORKAROUND_VC7
00258
00259
00263 template<typename ISOLATIONTAG>
00264 static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00265 #else
00266
00267 template<> static inline void
00268 error_permitted_isolation_level(isolation_traits<serializable>) throw ();
00269 #endif
00270
00271 transaction_base &m_Trans;
00272 PGSTD::string m_Name;
00273 size_type m_Count;
00274 bool m_Done;
00275 size_type m_Pos;
00276 size_type m_Size;
00277
00278
00279 Cursor(const Cursor &);
00280 Cursor &operator=(const Cursor &);
00281 };
00282
00283 template<> inline void
00284 Cursor::error_permitted_isolation_level(isolation_traits<serializable>) throw ()
00285 {}
00286
00287 }
00288
00289 #endif
00290