00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 #ifndef PQXX_CACHEDRESULT_H
00015 #define PQXX_CACHEDRESULT_H
00016 
00017 #include <map>
00018 
00019 #include "pqxx/cursor.h"
00020 #include "pqxx/result.h"
00021 
00022 namespace pqxx
00023 {
00024 
00025 class TransactionItf;
00026 
00027 
00028 
00046 class PQXX_LIBEXPORT CachedResult
00047 {
00048 public:
00049   typedef Result::size_type size_type;
00050   typedef size_type blocknum;
00051 
00053   typedef Result::Tuple Tuple;
00054 
00064   explicit CachedResult(pqxx::TransactionItf &T,
00065                         const char Query[],
00066                         const PGSTD::string &BaseName="query",
00067                         size_type Granularity=100);                     
00068 
00069   
00070   
00071   
00072 
00074 
00082   const Tuple operator[](size_type i) const                             
00083         { return GetBlock(BlockFor(i))[Offset(i)]; }
00084 
00086 
00097    const Tuple at(size_type i) const                                    
00098         { return GetBlock(BlockFor(i)).at(Offset(i)); }
00099 
00101   size_type size() const;                                               
00102   
00104   bool empty() const;                                                   
00105 
00107   class const_iterator
00108   {
00109     const CachedResult &m_Home;
00110     CachedResult::size_type m_Row;
00111   public:
00112     explicit const_iterator(const CachedResult &Home) : m_Home(Home), m_Row(0){}
00113 
00114   private:
00115     
00116     const_iterator();
00117   };
00118 
00119 private:
00120 
00121   typedef Cursor::pos pos;
00122 
00123   blocknum BlockFor(size_type Row) const throw () 
00124         { return Row / m_Granularity; }
00125   size_type Offset(size_type Row) const throw ()
00126         { return Row % m_Granularity; }
00127   Cursor::size_type FirstRowOf(blocknum Block) const throw ()
00128         { return Block*m_Granularity; }
00129 
00130   void MoveTo(blocknum) const;
00131 
00133   const Result &Fetch() const;
00134 
00135   const Result &GetBlock(blocknum b) const
00136   {
00137     CacheMap::const_iterator i = m_Cache.find(b);
00138     if (i != m_Cache.end()) return i->second;
00139 
00140     MoveTo(b);
00141     return Fetch();
00142   }
00143 
00145   size_type m_Granularity;
00146 
00147   typedef PGSTD::map<blocknum, const Result> CacheMap;
00148   mutable CacheMap m_Cache;
00149 
00150   mutable Cursor m_Cursor;
00151   mutable Result m_EmptyResult;
00152   mutable bool   m_HaveEmpty;
00153 
00154   
00155   CachedResult();
00156   CachedResult(const CachedResult &);
00157   CachedResult &operator=(const CachedResult &);
00158 };
00159 
00160 
00161 } 
00162 
00163 #endif
00164