# pipeline.hxx

    00001 /*-------------------------------------------------------------------------
    00002  *
    00003  *   FILE
    00004  *      pqxx/pipeline.hxx
    00005  *
    00006  *   DESCRIPTION
    00007  *      definition of the pqxx::pipeline class.
    00008  *   Throughput-optimized query manager
    00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead.
    00010  *
    00011  * Copyright (c) 2003-2008, Jeroen T. Vermeulen <jtv@xs4all.nl>
    00012  *
    00013  * See COPYING for copyright license.  If you did not receive a file called
    00014  * COPYING with this source code, please notify the distributor of this mistake,
    00015  * or contact the author.
    00016  *
    00017  *-------------------------------------------------------------------------
    00018  */
    00019 #ifndef PQXX_H_PIPELINE
    00020 #define PQXX_H_PIPELINE
    00021
    00022 #include "pqxx/compiler-public.hxx"
    00023 #include "pqxx/compiler-internal-pre.hxx"
    00024
    00025 #ifdef PQXX_HAVE_LIMITS
    00026 #include <limits>
    00027 #endif
    00028
    00029 #include <map>
    00030 #include <string>
    00031
    00032 #include "pqxx/transaction_base"
    00033
    00034
    00035 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
    00036  */
    00037
    00038 namespace pqxx
    00039 {
    00040
    00042
    00058 class PQXX_LIBEXPORT pipeline : public internal::transactionfocus
    00059 {
    00060 public:
    00061   typedef long query_id;
    00062
    00063   explicit pipeline(transaction_base &,
    00064       const PGSTD::string &Name=PGSTD::string());                       //[t69]
    00065
    00066   ~pipeline() throw ();
    00067
    00069
    00075   query_id insert(const PGSTD::string &);                               //[t69]
    00076
    00078
    00079   void complete();                                                      //[t71]
    00080
    00082
    00091   void flush();                                                         //[t70]
    00092
    00094
    00102   void cancel();
    00103
    00105   bool is_finished(query_id) const;                                     //[t71]
    00106
    00108
    00114   result retrieve(query_id qid)                                         //[t71]
    00115         { return retrieve(m_queries.find(qid)).second; }
    00116
    00118
    00119   PGSTD::pair<query_id, result> retrieve();                             //[t69]
    00120
    00121   bool empty() const throw () { return m_queries.empty(); }             //[t69]
    00122
    00124
    00135   int retain(int retain_max=2);                                         //[t70]
    00136
    00137
    00139   void resume();                                                        //[t70]
    00140
    00141 private:
    00142   class PQXX_PRIVATE Query
    00143   {
    00144   public:
    00145     explicit Query(const PGSTD::string &q) : m_query(q), m_res() {}
    00146
    00147     const result &get_result() const throw () { return m_res; }
    00148     void set_result(const result &r) throw () { m_res = r; }
    00149     const PGSTD::string &get_query() const throw () { return m_query; }
    00150
    00151   private:
    00152     PGSTD::string m_query;
    00153     result m_res;
    00154   };
    00155
    00156   typedef PGSTD::map<query_id,Query> QueryMap;
    00157
    00158   struct getquery:PGSTD::unary_function<QueryMap::const_iterator,PGSTD::string>
    00159   {
    00160     getquery(){}        // Silences bogus warning in some gcc versions
    00161     PGSTD::string operator()(QueryMap::const_iterator i) const
    00162         { return i->second.get_query(); }
    00163   };
    00164
    00165   void attach();
    00166   void detach();
    00167
    00169   static query_id qid_limit() throw ()
    00170   {
    00171 #if defined(PQXX_HAVE_LIMITS)
    00172     return PGSTD::numeric_limits<query_id>::max();
    00173 #else
    00174     return LONG_MAX;
    00175 #endif
    00176   }
    00177
    00179   query_id PQXX_PRIVATE generate_id();
    00180
    00181   bool have_pending() const throw ()
    00182         { return m_issuedrange.second != m_issuedrange.first; }
    00183
    00184   void PQXX_PRIVATE issue();
    00185
    00187   void set_error_at(query_id qid) throw () { if (qid < m_error) m_error = qid; }
    00188
    00189   void PQXX_PRIVATE internal_error(const PGSTD::string &err)
    00190     throw (PGSTD::logic_error);
    00191
    00192   bool PQXX_PRIVATE obtain_result(bool expect_none=false);
    00193
    00194   void PQXX_PRIVATE obtain_dummy();
    00195   void PQXX_PRIVATE get_further_available_results();
    00196   void PQXX_PRIVATE check_end_results();
    00197
    00199   void PQXX_PRIVATE receive_if_available();
    00200
    00202   void PQXX_PRIVATE receive(pipeline::QueryMap::const_iterator stop);
    00203   PGSTD::pair<pipeline::query_id, result>
    00204     retrieve(pipeline::QueryMap::iterator);
    00205
    00206   QueryMap m_queries;
    00207   PGSTD::pair<QueryMap::iterator,QueryMap::iterator> m_issuedrange;
    00208   int m_retain;
    00209   int m_num_waiting;
    00210   query_id m_q_id;
    00211
    00213   bool m_dummy_pending;
    00214
    00216   query_id m_error;
    00217
    00219   pipeline(const pipeline &);
    00221   pipeline &operator=(const pipeline &);
    00222 };
    00223
    00224
    00225 } // namespace
    00226
    00227
    00228 #include "pqxx/compiler-internal-post.hxx"
    00229
    00230 #endif
    00231