Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

cachedresult.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/cachedresult.h
00005  *
00006  *   DESCRIPTION
00007  *      definitions for the pqxx::cachedresult class and support classes.
00008  *   pqxx::cachedresult is a lazy-fetching, transparently-cached result set
00009  *
00010  * Copyright (c) 2001-2003, Jeroen T. Vermeulen <jtv@xs4all.nl>
00011  *
00012  * See COPYING for copyright license.  If you did not receive a file called
00013  * COPYING with this source code, please notify the distributor of this mistake,
00014  * or contact the author.
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 
00029 // TODO: Forward-only mode of operation?  Or write separate stream class?
00030 
00052 class PQXX_LIBEXPORT cachedresult
00053 {
00054 public:
00055   typedef result::size_type size_type;
00056   typedef size_type blocknum;
00057 
00059   typedef result::tuple tuple;
00060 
00062   typedef tuple Tuple;
00063 
00075   template<typename TRANSACTION> explicit
00076     cachedresult(TRANSACTION &T,
00077                  const char Query[],
00078                  const PGSTD::string &BaseName="query",
00079                  size_type Granularity=100) :                           //[t40]
00080       m_Granularity(Granularity),
00081       m_Cache(),
00082       m_Cursor(T, Query, BaseName, Granularity),
00083       m_EmptyResult(),
00084       m_HaveEmpty(false)
00085   {
00086     // Trigger build error if T has insufficient isolation level
00087     error_permitted_isolation_level(PQXX_TYPENAME TRANSACTION::isolation_tag());
00088     init();
00089   }
00090 
00091 
00093 
00101   const tuple operator[](size_type i) const                             //[t41]
00102         { return GetBlock(BlockFor(i))[Offset(i)]; }
00103 
00105 
00116    const tuple at(size_type i) const                                    //[t40]
00117         { return GetBlock(BlockFor(i)).at(Offset(i)); }
00118 
00120   size_type size() const;                                               //[t40]
00121   
00123   bool empty() const;                                                   //[t47]
00124 
00125 private:
00126   typedef Cursor::pos pos;
00127 
00128 #ifndef PQXX_WORKAROUND_VC7
00129 
00130 
00135   template<typename ISOLATIONTAG>
00136     static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00137 #else
00138   // Incorrect, but needed to compile with Visual C++ 7
00139   template<> static inline void
00140     error_permitted_isolation_level(isolation_traits<serializable>) throw ();
00141 #endif
00142 
00143   void init();
00144 
00145   blocknum BlockFor(size_type Row) const throw () 
00146         { return Row / m_Granularity; }
00147   size_type Offset(size_type Row) const throw ()
00148         { return Row % m_Granularity; }
00149   Cursor::size_type FirstRowOf(blocknum Block) const throw ()
00150         { return Block*m_Granularity; }
00151 
00152   void MoveTo(blocknum) const;
00153 
00155   const result &Fetch() const;
00156 
00157   const result &GetBlock(blocknum b) const
00158   {
00159     CacheMap::const_iterator i = m_Cache.find(b);
00160     if (i != m_Cache.end()) return i->second;
00161 
00162     MoveTo(b);
00163     return Fetch();
00164   }
00165 
00167   size_type m_Granularity;
00168 
00169   typedef PGSTD::map<blocknum, result> CacheMap;
00170   mutable CacheMap m_Cache;
00171 
00172   mutable Cursor m_Cursor;
00173   mutable result m_EmptyResult;
00174   mutable bool   m_HaveEmpty;
00175 
00176   // Not allowed:
00177   cachedresult();
00178   cachedresult(const cachedresult &);
00179   cachedresult &operator=(const cachedresult &);
00180 };
00181 
00183 typedef cachedresult CachedResult;
00184 
00185 template<> inline void
00186 cachedresult::error_permitted_isolation_level(isolation_traits<serializable>)
00187   throw () {}
00188 
00189 } // namespace pqxx
00190 
00191 #endif
00192 

Generated on Fri Nov 21 19:50:07 2003 for libpqxx by doxygen 1.3.4