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