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
00130
00135 static void
00136 error_permitted_isolation_level(isolation_traits<serializable>) throw () {}
00137
00138 void init();
00139
00140 blocknum BlockFor(size_type Row) const throw ()
00141 { return Row / m_Granularity; }
00142 size_type Offset(size_type Row) const throw ()
00143 { return Row % m_Granularity; }
00144 Cursor::size_type FirstRowOf(blocknum Block) const throw ()
00145 { return Block*m_Granularity; }
00146
00147 void MoveTo(blocknum) const;
00148
00150 const result &Fetch() const;
00151
00152 const result &GetBlock(blocknum b) const
00153 {
00154 CacheMap::const_iterator i = m_Cache.find(b);
00155 if (i != m_Cache.end()) return i->second;
00156
00157 MoveTo(b);
00158 return Fetch();
00159 }
00160
00162 size_type m_Granularity;
00163
00164 typedef PGSTD::map<blocknum, result> CacheMap;
00165 mutable CacheMap m_Cache;
00166
00167 mutable Cursor m_Cursor;
00168 mutable result m_EmptyResult;
00169 mutable bool m_HaveEmpty;
00170
00171
00172 cachedresult();
00173 cachedresult(const cachedresult &);
00174 cachedresult &operator=(const cachedresult &);
00175 };
00176
00178 typedef cachedresult CachedResult;
00179
00180 }
00181
00182 #endif
00183