00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
#ifndef PQXX_CACHEDRESULT_H
00019
#define PQXX_CACHEDRESULT_H
00020
00021
#include <map>
00022
00023
#include "pqxx/cursor.h"
00024
#include "pqxx/result.h"
00025
00026
namespace pqxx
00027 {
00028
00053 class PQXX_LIBEXPORT cachedresult
00054 {
00055
public:
00056 typedef result::size_type size_type;
00057 typedef size_type
blocknum;
00058
00060 typedef result::tuple tuple;
00061
00063 typedef tuple Tuple;
00064
00076
template<
typename TRANSACTION>
explicit
00077 cachedresult(TRANSACTION &T,
00078
const char Query[],
00079
const PGSTD::string &BaseName=
"query",
00080 size_type Granularity=100) :
00081 m_Granularity(Granularity),
00082 m_Cache(),
00083 m_Cursor(T, Query, BaseName, Granularity),
00084 m_EmptyResult(),
00085 m_HaveEmpty(false)
00086 {
00087
00088 error_permitted_isolation_level(
PQXX_TYPENAME TRANSACTION::isolation_tag());
00089 init();
00090 }
00091
00092
00094
00102 const tuple operator[](size_type i)
const
00103 {
return GetBlock(BlockFor(i))[Offset(i)]; }
00104
00106
00117 const tuple at(size_type i)
const
00118 {
return GetBlock(BlockFor(i)).at(Offset(i)); }
00119
00121 size_type size() const;
00122
00124
bool empty() const;
00125
00126 private:
00127 typedef
Cursor::pos pos;
00128
00129 #ifndef PQXX_WORKAROUND_VC7
00131
00136 template<typename ISOLATIONTAG>
00137 static inline
void error_permitted_isolation_level(ISOLATIONTAG) throw ();
00138
00139 #if defined(__SUNPRO_CC)
00140
00141 template<> static
void
00142 error_permitted_level(
isolation_traits<serializable>) throw() {}
00143
#endif // __SUNPRO_CC
00144
#else
00145
00146
template<>
static inline void
00147 error_permitted_isolation_level(isolation_traits<serializable>) throw ();
00148 #endif
00149
00150
void init();
00151
00152 blocknum BlockFor(size_type Row) const throw ()
00153 {
return Row / m_Granularity; }
00154 size_type Offset(size_type Row)
const throw ()
00155 {
return Row % m_Granularity; }
00156 Cursor::size_type FirstRowOf(blocknum Block)
const throw ()
00157 {
return Block*m_Granularity; }
00158
00159
void MoveTo(blocknum) const;
00160
00162 const result &Fetch() const;
00163
00164 const result &GetBlock(blocknum b)
const
00165
{
00166 CacheMap::const_iterator i = m_Cache.find(b);
00167
if (i != m_Cache.end())
return i->second;
00168
00169 MoveTo(b);
00170
return Fetch();
00171 }
00172
00174 size_type m_Granularity;
00175
00176
typedef PGSTD::map<blocknum, result> CacheMap;
00177
mutable CacheMap m_Cache;
00178
00179
mutable Cursor m_Cursor;
00180
mutable result m_EmptyResult;
00181
mutable bool m_HaveEmpty;
00182
00183
00184 cachedresult();
00185 cachedresult(
const cachedresult &);
00186 cachedresult &operator=(
const cachedresult &);
00187 };
00188
00190 typedef cachedresult
CachedResult;
00191
00192
template<>
inline void
00193 cachedresult::error_permitted_isolation_level(
isolation_traits<serializable>)
00194 throw () {}
00195
00196 }
00197
00198
#endif
00199