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
00029
00030
00051 class PQXX_LIBEXPORT cachedresult
00052 {
00053 public:
00054 typedef result::size_type size_type;
00055 typedef size_type blocknum;
00056
00058 typedef result::tuple tuple;
00059
00061 typedef tuple Tuple;
00062
00074 template<typename TRANSACTION> explicit
00075 cachedresult(TRANSACTION &T,
00076 const char Query[],
00077 const PGSTD::string &BaseName="query",
00078 size_type Granularity=100) :
00079 m_Granularity(Granularity),
00080 m_Cache(),
00081 m_Cursor(T, Query, BaseName, Granularity),
00082 m_EmptyResult(),
00083 m_HaveEmpty(false)
00084 {
00085
00086 error_permitted_isolation_level(typename TRANSACTION::isolation_tag());
00087 init();
00088 }
00089
00090
00091
00092
00093
00094
00096
00104 const tuple operator[](size_type i) const
00105 { return GetBlock(BlockFor(i))[Offset(i)]; }
00106
00108
00119 const tuple at(size_type i) const
00120 { return GetBlock(BlockFor(i)).at(Offset(i)); }
00121
00123 size_type size() const;
00124
00126 bool empty() const;
00127
00128 private:
00129 typedef Cursor::pos pos;
00130
00132
00137 template<typename ISOLATIONTAG>
00138 static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00139
00140 void init();
00141
00142 blocknum BlockFor(size_type Row) const throw ()
00143 { return Row / m_Granularity; }
00144 size_type Offset(size_type Row) const throw ()
00145 { return Row % m_Granularity; }
00146 Cursor::size_type FirstRowOf(blocknum Block) const throw ()
00147 { return Block*m_Granularity; }
00148
00149 void MoveTo(blocknum) const;
00150
00152 const result &Fetch() const;
00153
00154 const result &GetBlock(blocknum b) const
00155 {
00156 CacheMap::const_iterator i = m_Cache.find(b);
00157 if (i != m_Cache.end()) return i->second;
00158
00159 MoveTo(b);
00160 return Fetch();
00161 }
00162
00164 size_type m_Granularity;
00165
00166 typedef PGSTD::map<blocknum, const result> CacheMap;
00167 mutable CacheMap m_Cache;
00168
00169 mutable Cursor m_Cursor;
00170 mutable result m_EmptyResult;
00171 mutable bool m_HaveEmpty;
00172
00173
00174 cachedresult();
00175 cachedresult(const cachedresult &);
00176 cachedresult &operator=(const cachedresult &);
00177 };
00178
00180 typedef cachedresult CachedResult;
00181
00182 template<> inline void
00183 cachedresult::error_permitted_isolation_level(isolation_traits<serializable>)
00184 throw () {}
00185
00186 }
00187
00188 #endif
00189