00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #include "pqxx/libcompiler.h"
00020 
00021 #include <map>
00022 #include <string>
00023 
00024 #include "pqxx/transaction_base"
00025 
00026 
00027 
00028 
00029 
00030 namespace pqxx
00031 {
00032 
00034 
00057 class PQXX_LIBEXPORT pipeline : public internal::transactionfocus
00058 {
00059 public:
00060   typedef long query_id;
00061 
00062   explicit pipeline(transaction_base &, const PGSTD::string &PName=""); 
00063 
00064   ~pipeline() throw ();
00065 
00067 
00073   query_id insert(const PGSTD::string &);                               
00074 
00076   void complete();                                                      
00077 
00079 
00086   void flush();                                                         
00087 
00089   bool is_finished(query_id) const;                                     
00090 
00092 
00098   result retrieve(query_id qid)                                         
00099         { return retrieve(m_queries.find(qid)).second; }
00100 
00102 
00103   PGSTD::pair<query_id, result> retrieve();                             
00104 
00105   bool empty() const throw () { return m_queries.empty(); }             
00106 
00108 
00119   int retain(int retain_max=2);                                         
00120 
00121 
00123   void resume();                                                        
00124 
00125 private:
00127   void invariant() const;
00128 
00129   class Query
00130   {
00131   public:
00132     explicit Query(const PGSTD::string &q) : m_query(q), m_res() {}
00133 
00134     const result &get_result() const throw () { return m_res; }
00135     void set_result(const result &r) throw () { m_res = r; }
00136     const PGSTD::string &get_query() const throw () { return m_query; }
00137 
00138   private:
00139     PGSTD::string m_query;
00140     result m_res;
00141   };
00142 
00143   typedef PGSTD::map<query_id,Query> QueryMap;
00144 
00146   static query_id qid_limit() throw ()
00147   {
00148 #if defined(PQXX_HAVE_LIMITS) && !defined(_MSC_VER)
00149     return PGSTD::numeric_limits<query_id>::max();
00150 #else
00151     return LONG_MAX;
00152 #endif
00153   }
00154 
00156   query_id generate_id();
00157     
00158   bool have_pending() const throw () 
00159         { return m_issuedrange.second != m_issuedrange.first; }
00160 
00161   void issue();
00162 
00164   void set_error_at(query_id qid) throw () { if (qid < m_error) m_error = qid; }
00165 
00166   void internal_error(const PGSTD::string &err) throw (PGSTD::logic_error);
00167 
00168   bool obtain_result(bool expect_none=false);
00169 
00170   void obtain_dummy();
00171   void get_further_available_results();
00172   void check_end_results();
00173 
00175   void receive_if_available();
00176 
00178   void receive(QueryMap::const_iterator stop);
00179   PGSTD::pair<query_id, result> retrieve(QueryMap::iterator);
00180 
00181   QueryMap m_queries;
00182   PGSTD::pair<QueryMap::iterator,QueryMap::iterator> m_issuedrange;
00183   int m_retain;
00184   int m_num_waiting;
00185   query_id m_q_id;
00186 
00188   bool m_dummy_pending;
00189 
00191   query_id m_error;
00192 
00194   pipeline(const pipeline &);
00196   pipeline &operator=(const pipeline &);
00197 };
00198 
00199 
00200 } 
00201 
00202