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 "pqxx/compiler-public.hxx"
00022
00023 #include <map>
00024
00025 #include "pqxx/cursor.h"
00026 #include "pqxx/result"
00027
00028 namespace pqxx
00029 {
00030
00055 class PQXX_LIBEXPORT cachedresult
00056 {
00057 public:
00058 typedef result::size_type size_type;
00059 typedef size_type blocknum;
00060
00062 typedef result::tuple tuple;
00063
00065 typedef tuple Tuple;
00066
00078 template<typename TRANSACTION> explicit
00079 cachedresult(TRANSACTION &T,
00080 const char Query[],
00081 const PGSTD::string &BaseName="query",
00082 size_type Granularity=100) :
00083 m_Granularity(Granularity),
00084 m_Cache(),
00085 m_Cursor(T, Query, BaseName, Granularity),
00086 m_EmptyResult(),
00087 m_HaveEmpty(false)
00088 {
00089
00090 error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00091 init();
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
00131
00136 static void
00137 error_permitted_isolation_level(isolation_traits<serializable>) throw () {}
00138
00139 void init();
00140
00141 blocknum BlockFor(size_type Row) const throw ()
00142 { return Row / m_Granularity; }
00143 size_type Offset(size_type Row) const throw ()
00144 { return Row % m_Granularity; }
00145 Cursor::size_type FirstRowOf(blocknum Block) const throw ()
00146 { return Block*m_Granularity; }
00147
00148 void MoveTo(blocknum) const;
00149
00151 const result &Fetch() const;
00152
00153 const result &GetBlock(blocknum b) const
00154 {
00155 CacheMap::const_iterator i = m_Cache.find(b);
00156 if (i != m_Cache.end()) return i->second;
00157
00158 MoveTo(b);
00159 return Fetch();
00160 }
00161
00163 size_type m_Granularity;
00164
00165 typedef PGSTD::map<blocknum, result> CacheMap;
00166 mutable CacheMap m_Cache;
00167
00168 mutable Cursor m_Cursor;
00169 mutable result m_EmptyResult;
00170 mutable bool m_HaveEmpty;
00171
00172
00173 cachedresult();
00174 cachedresult(const cachedresult &);
00175 cachedresult &operator=(const cachedresult &);
00176 };
00177
00179 typedef cachedresult CachedResult;
00180
00181 }
00182
00183 #endif
00184