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
00041 class PQXX_LIBEXPORT CachedResult
00042 {
00043 public:
00044 typedef Result::size_type size_type;
00045 typedef size_type blocknum;
00046 typedef Result::Tuple Tuple;
00047
00049 explicit CachedResult(pqxx::TransactionItf &,
00050 const char Query[],
00051 PGSTD::string BaseName="query",
00052 size_type Granularity=100);
00053
00054
00055
00056
00057
00058
00059 const Tuple operator[](size_type i) const
00060 {
00061 return GetBlock(BlockFor(i))[Offset(i)];
00062 }
00063
00064 const Tuple at(size_type i) const
00065 {
00066 return GetBlock(BlockFor(i)).at(Offset(i));
00067 }
00068
00069 size_type size() const
00070 {
00071 if (m_Size == -1) DetermineSize();
00072 return m_Size;
00073 }
00074
00075 void clear();
00076
00077 private:
00078
00079 class CacheEntry
00080 {
00081 int m_RefCount;
00082 Result m_Data;
00083
00084 public:
00085 CacheEntry() : m_RefCount(0), m_Data() {}
00086 explicit CacheEntry(const Result &R) : m_RefCount(0), m_Data(R) {}
00087
00088 const Result &Data() const { return m_Data; }
00089 int RefCount() const { return m_RefCount; }
00090 };
00091
00092
00093 blocknum BlockFor(size_type Row) const { return Row / m_Granularity; }
00094 size_type Offset(size_type Row) const { return Row % m_Granularity; }
00095
00096 void MoveTo(blocknum) const;
00097
00099 Result Fetch() const;
00100
00101 Result GetBlock(blocknum b) const
00102 {
00103 CacheMap::const_iterator i = m_Cache.find(b);
00104 if (i != m_Cache.end()) return i->second.Data();
00105
00106 MoveTo(b);
00107 return Fetch();
00108 }
00109
00116 void DetermineSize() const;
00117
00119 size_type m_Granularity;
00120
00121 typedef PGSTD::map<blocknum, CacheEntry> CacheMap;
00122 mutable CacheMap m_Cache;
00123
00124 mutable Cursor m_Cursor;
00125
00127 mutable blocknum m_Pos;
00128
00130 mutable size_type m_Size;
00131
00133 mutable blocknum m_Upper;
00134
00135
00136 CachedResult(const CachedResult &);
00137 CachedResult &operator=(const CachedResult &);
00138 };
00139
00140
00141 }
00142
00143 #endif
00144