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
00070 class PQXX_LIBEXPORT Cursor
00071 {
00072 enum { dist_next=1 };
00073
00074 public:
00075 typedef result::size_type size_type;
00076
00077 enum pos { pos_unknown = -1, pos_start = 0 };
00078
00080 struct PQXX_LIBEXPORT unknown_position : PGSTD::runtime_error
00081 {
00082 unknown_position(const PGSTD::string &cursorname) :
00083 PGSTD::runtime_error("Position for cursor '" + cursorname + "' "
00084 "is unknown")
00085 {
00086 }
00087 };
00088
00090
00098 template<typename TRANSACTION>
00099 Cursor(TRANSACTION &T,
00100 const char Query[],
00101 const PGSTD::string &BaseName="cur",
00102 size_type Count=dist_next) :
00103 m_Trans(T),
00104 m_Name(),
00105 m_Count(Count),
00106 m_Done(false),
00107 m_Pos(pos_start),
00108 m_Size(pos_unknown)
00109 {
00110
00111 error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00112 init(BaseName, Query);
00113 }
00114
00116
00146 template<typename TRANSACTION>
00147 Cursor(TRANSACTION &T,
00148 const result::field &Name,
00149 size_type Count=dist_next) :
00150 m_Trans(T),
00151 m_Name(Name.c_str()),
00152 m_Count(Count),
00153 m_Done(false),
00154 m_Pos(pos_unknown),
00155 m_Size(pos_unknown)
00156 {
00157
00158 error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00159 }
00160
00162 size_type SetCount(size_type);
00163
00165
00174 result Fetch(size_type Count);
00175
00177
00185 size_type Move(size_type Count);
00186
00187 void MoveTo(size_type);
00188
00190
00194 static size_type ALL() throw ();
00195
00197 static size_type NEXT() throw () { return dist_next; }
00198
00200 static size_type PRIOR() throw () { return -1; }
00201
00204
00208 static size_type BACKWARD_ALL() throw ();
00209
00211
00218 Cursor &operator>>(result &);
00219
00221 operator bool() const throw () { return !m_Done; }
00223 bool operator!() const throw () { return m_Done; }
00224
00226 Cursor &operator+=(size_type N) { Move(N); return *this;}
00228 Cursor &operator-=(size_type N) { Move(-N); return *this;}
00229
00231
00242 size_type size() const throw () { return m_Size; }
00243
00245
00252 size_type Pos() const throw (unknown_position)
00253 { if (m_Pos==pos_unknown) throw unknown_position(m_Name); return m_Pos; }
00254
00255
00256 private:
00257 static PGSTD::string OffsetString(size_type);
00258 void init(const PGSTD::string &BaseName, const char Query[]);
00259 PGSTD::string MakeFetchCmd(size_type) const;
00260 size_type NormalizedMove(size_type Intended, size_type Actual);
00261
00262 #ifndef PQXX_WORKAROUND_VC7
00263
00264
00268 template<typename ISOLATIONTAG>
00269 static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00270
00271 #if defined(__SUNPRO_CC)
00272
00273 template<> static void
00274 error_permitted_level(isolation_traits<serializable>) throw() {}
00275 #endif // __SUNPRO_CC
00276 #else
00277
00278 template<> static inline void
00279 error_permitted_isolation_level(isolation_traits<serializable>) throw ();
00280 #endif
00281
00282 transaction_base &m_Trans;
00283 PGSTD::string m_Name;
00284 size_type m_Count;
00285 bool m_Done;
00286 size_type m_Pos;
00287 size_type m_Size;
00288
00289
00290 Cursor(const Cursor &);
00291 Cursor &operator=(const Cursor &);
00292 };
00293
00294 template<> inline void
00295 Cursor::error_permitted_isolation_level(isolation_traits<serializable>) throw ()
00296 {}
00297
00298 }
00299
00300 #endif
00301