connection_base.hxx

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/connection_base.hxx
00005  *
00006  *   DESCRIPTION
00007  *      definition of the pqxx::connection_base abstract base class.
00008  *   pqxx::connection_base encapsulates a frontend to backend connection
00009  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection_base instead.
00010  *
00011  * Copyright (c) 2001-2009, 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_CONNECTION_BASE
00020 #define PQXX_H_CONNECTION_BASE
00021 
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024 
00025 #include <bitset>
00026 #include <map>
00027 #include <memory>
00028 
00029 #include "pqxx/except"
00030 #include "pqxx/prepared_statement"
00031 #include "pqxx/strconv"
00032 #include "pqxx/util"
00033 
00034 
00035 /* Use of the libpqxx library starts here.
00036  *
00037  * Everything that can be done with a database through libpqxx must go through
00038  * a connection object derived from connection_base.
00039  */
00040 
00041 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00042  */
00043 
00044 namespace pqxx
00045 {
00046 class result;
00047 class transaction_base;
00048 class notify_listener;
00049 class connectionpolicy;
00050 
00051 namespace internal
00052 {
00053 class reactivation_avoidance_exemption;
00054 class sql_cursor;
00055 
00056 class reactivation_avoidance_counter
00057 {
00058 public:
00059   reactivation_avoidance_counter() : m_counter(0) {}
00060 
00061   void add(int n) throw () { m_counter += n; }
00062   void clear() throw () { m_counter = 0; }
00063   int get() const throw () { return m_counter; }
00064 
00065 private:
00066   int m_counter;
00067 };
00068 
00069 }
00070 
00076 
00077 
00082 struct PQXX_LIBEXPORT PQXX_NOVTABLE noticer :
00083   PGSTD::unary_function<const char[], void>
00084 {
00085   noticer(){}           // Silences bogus warning in some gcc versions
00086   virtual ~noticer() throw () {}
00087   virtual void operator()(const char Msg[]) throw () =0;
00088 };
00089 
00090 
00092 struct PQXX_LIBEXPORT nonnoticer : noticer
00093 {
00094   nonnoticer(){}        // Silences bogus warning in some gcc versions
00095   virtual void operator()(const char []) throw () {}
00096 };
00097 
00102 
00103 
00121 PGSTD::string PQXX_LIBEXPORT encrypt_password(                          //[t0]
00122         const PGSTD::string &user,
00123         const PGSTD::string &password);
00124 
00125 
00126 namespace internal
00127 {
00128 namespace gate
00129 {
00130 class connection_dbtransaction;
00131 class connection_largeobject;
00132 class connection_notify_listener;
00133 class connection_parameterized_invocation;
00134 class connection_pipeline;
00135 class connection_prepare_declaration;
00136 class connection_prepare_invocation;
00137 class connection_reactivation_avoidance_exemption;
00138 class connection_sql_cursor;
00139 class connection_transaction;
00140 } // namespace pqxx::internal::gate
00141 } // namespace pqxx::internal
00142 
00143 
00145 
00178 class PQXX_LIBEXPORT connection_base
00179 {
00180 public:
00182   void disconnect() throw ();                                           //[t2]
00183 
00185 
00189   bool is_open() const throw ();                                        //[t1]
00190 
00201 
00202 
00212   void activate();                                                      //[t12]
00213 
00215 
00223   void deactivate();                                                    //[t12]
00224 
00226 
00270   void inhibit_reactivation(bool inhibit)                               //[t86]
00271         { m_inhibit_reactivation=inhibit; }
00272 
00274 
00279   void simulate_failure();                                              //[t94]
00281 
00291 
00293 
00305   PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N)
00306     throw ();                                                           //[t14]
00307   noticer *get_noticer() const throw () { return m_Noticer.get(); }     //[t14]
00308 
00310   void process_notice(const char[]) throw ();                           //[t14]
00312   void process_notice(const PGSTD::string &) throw ();                  //[t14]
00313 
00315 
00317   void trace(FILE *) throw ();                                          //[t3]
00318 
00327 
00328 
00331   const char *dbname();                                                 //[t1]
00332 
00334 
00337   const char *username();                                               //[t1]
00338 
00340 
00343   const char *hostname();                                               //[t1]
00344 
00346 
00349   const char *port();                                                   //[t1]
00350 
00352 
00361   int backendpid() const throw ();                                      //[t1]
00362 
00364 
00378   int sock() const throw ();                                            //[t87]
00379 
00390  
00392   enum capability
00393   {
00395     cap_prepared_statements,
00396 
00398     cap_create_table_with_oids,
00399 
00401     cap_nested_transactions,
00402 
00404     cap_cursor_scroll,
00406     cap_cursor_with_hold,
00408     cap_cursor_update,
00410     cap_cursor_fetch_0,
00411 
00413     cap_table_column,
00414 
00416     cap_read_only_transactions,
00417 
00419     cap_statement_varargs,
00420 
00422     cap_prepare_unnamed_statement,
00423 
00425     cap_parameterized_statements,
00426 
00428     cap_end
00429   };
00430 
00431 
00433 
00449   bool supports(capability c) const throw () { return m_caps.test(c); } //[t88]
00450 
00452 
00464   int protocol_version() const throw ();                                //[t1]
00465 
00467 
00479   int server_version() const throw ();                                  //[t1]
00481 
00483 
00489   void set_client_encoding(const PGSTD::string &Encoding)               //[t7]
00490         { set_variable("CLIENT_ENCODING", Encoding); }
00491 
00493 
00509   void set_variable(const PGSTD::string &Var,
00510                     const PGSTD::string &Value);                        //[t60]
00511 
00513 
00520   PGSTD::string get_variable(const PGSTD::string &);                    //[t60]
00522 
00523 
00528 
00529 
00541   int get_notifs();                                                     //[t4]
00542 
00543 
00545 
00551   int await_notification();                                             //[t78]
00552 
00554 
00560   int await_notification(long seconds, long microseconds);              //[t79]
00562 
00563 
00600 
00601 
00643   prepare::declaration prepare(const PGSTD::string &name,
00644         const PGSTD::string &definition);
00645 
00647 
00653   prepare::declaration prepare(const PGSTD::string &definition);
00654 
00656   void unprepare(const PGSTD::string &name);
00657 
00659 
00669   void prepare_now(const PGSTD::string &name);
00670 
00700 
00701 
00709   template<typename TRANSACTOR>
00710   void perform(const TRANSACTOR &T, int Attempts);                      //[t4]
00711 
00713 
00716   template<typename TRANSACTOR>
00717   void perform(const TRANSACTOR &T) { perform(T, 3); }
00718 
00723 
00724 
00727   PGSTD::string adorn_name(const PGSTD::string &);                      //[90]
00728 
00797 
00798   PGSTD::string esc(const char str[]);
00799 
00801   PGSTD::string esc(const char str[], size_t maxlen);
00802 
00804   PGSTD::string esc(const PGSTD::string &str);
00805 
00807   PGSTD::string esc_raw(const unsigned char str[], size_t len);
00808 
00810 
00811   template<typename T>
00812   PGSTD::string quote(const T &t)
00813   {
00814     if (string_traits<T>::is_null(t)) return "NULL";
00815     return "'" + this->esc(to_string(t)) + "'";
00816   }
00818 
00820   void cancel_query();
00821 
00822 protected:
00823   explicit connection_base(connectionpolicy &);
00824   void init();
00825 
00826   void close() throw ();
00827   void wait_read() const;
00828   void wait_read(long seconds, long microseconds) const;
00829   void wait_write() const;
00830 
00831 private:
00832   result make_result(internal::pq::PGresult *rhs, const PGSTD::string &query);
00833 
00834   void PQXX_PRIVATE clearcaps() throw ();
00835   void PQXX_PRIVATE SetupState();
00836   void PQXX_PRIVATE check_result(const result &);
00837 
00838   void PQXX_PRIVATE InternalSetTrace() throw ();
00839   int PQXX_PRIVATE Status() const throw ();
00840   const char *ErrMsg() const throw ();
00841   void PQXX_PRIVATE Reset();
00842   void PQXX_PRIVATE RestoreVars();
00843   PGSTD::string PQXX_PRIVATE RawGetVar(const PGSTD::string &);
00844   void PQXX_PRIVATE process_notice_raw(const char msg[]) throw ();
00845   void switchnoticer(const PGSTD::auto_ptr<noticer> &) throw ();
00846 
00847   void read_capabilities() throw ();
00848 
00849   prepare::internal::prepared_def &find_prepared(const PGSTD::string &);
00850 
00851   friend class internal::gate::connection_prepare_declaration;
00852   void prepare_param_declare(
00853         const PGSTD::string &statement,
00854         const PGSTD::string &sqltype,
00855         prepare::param_treatment);
00856   void prepare_param_declare_varargs(
00857         const PGSTD::string &statement,
00858         prepare::param_treatment);
00859 
00860   prepare::internal::prepared_def &register_prepared(const PGSTD::string &);
00861 
00862   friend class internal::gate::connection_prepare_invocation;
00863   result prepared_exec(const PGSTD::string &,
00864         const char *const[],
00865         const int[],
00866         int);
00867   bool prepared_exists(const PGSTD::string &) const;
00868 
00870   internal::pq::PGconn *m_Conn;
00871 
00872   connectionpolicy &m_policy;
00873 
00875   internal::unique<transaction_base> m_Trans;
00876 
00878   PGSTD::auto_ptr<noticer> m_Noticer;
00879 
00881 
00885   internal::pq::PQnoticeProcessor m_defaultNoticeProcessor;
00886 
00888   FILE *m_Trace;
00889 
00890   typedef PGSTD::multimap<PGSTD::string, pqxx::notify_listener *> listenerlist;
00892   listenerlist m_listeners;
00893 
00895   PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00896 
00897   typedef PGSTD::map<PGSTD::string, prepare::internal::prepared_def> PSMap;
00898 
00900   PSMap m_prepared;
00901 
00903   int m_serverversion;
00904 
00906   internal::reactivation_avoidance_counter m_reactivation_avoidance;
00907 
00909   int m_unique_id;
00910 
00912   bool m_Completed;
00913 
00915   bool m_inhibit_reactivation;
00916 
00918   PGSTD::bitset<cap_end> m_caps;
00919 
00920   friend class internal::gate::connection_transaction;
00921   result PQXX_PRIVATE Exec(const char[], int Retries);
00922   void PQXX_PRIVATE RegisterTransaction(transaction_base *);
00923   void PQXX_PRIVATE UnregisterTransaction(transaction_base *) throw ();
00924   bool PQXX_PRIVATE ReadCopyLine(PGSTD::string &);
00925   void PQXX_PRIVATE WriteCopyLine(const PGSTD::string &);
00926   void PQXX_PRIVATE EndCopyWrite();
00927   void PQXX_PRIVATE RawSetVar(const PGSTD::string &, const PGSTD::string &);
00928   void PQXX_PRIVATE AddVariables(const PGSTD::map<PGSTD::string,
00929       PGSTD::string> &);
00930 
00931   friend class internal::gate::connection_largeobject;
00932   internal::pq::PGconn *RawConnection() const { return m_Conn; }
00933 
00934   friend class internal::gate::connection_notify_listener;
00935   void add_listener(notify_listener *);
00936   void remove_listener(notify_listener *) throw ();
00937 
00938   friend class internal::gate::connection_pipeline;
00939   void PQXX_PRIVATE start_exec(const PGSTD::string &);
00940   bool PQXX_PRIVATE consume_input() throw ();
00941   bool PQXX_PRIVATE is_busy() const throw ();
00942   int PQXX_PRIVATE encoding_code() throw ();
00943   internal::pq::PGresult *get_result();
00944 
00945   friend class internal::gate::connection_dbtransaction;
00946 
00947   friend class internal::gate::connection_sql_cursor;
00948   void add_reactivation_avoidance_count(int);
00949 
00950   friend class internal::gate::connection_reactivation_avoidance_exemption;
00951 
00952   friend class internal::gate::connection_parameterized_invocation;
00953   result parameterized_exec(
00954         const PGSTD::string &query,
00955         const char *const params[],
00956         const int paramlengths[],
00957         int nparams);
00958 
00959   // Not allowed:
00960   connection_base(const connection_base &);
00961   connection_base &operator=(const connection_base &);
00962 };
00963 
00964 
00965 
00967 
00973 class PQXX_LIBEXPORT scoped_noticer
00974 {
00975 public:
00977 
00981   scoped_noticer(connection_base &c, PGSTD::auto_ptr<noticer> t) throw () :
00982     m_c(c), m_org(c.set_noticer(t)) { }
00983 
00984   ~scoped_noticer() { m_c.set_noticer(m_org); }
00985 
00986 protected:
00988 
00992   scoped_noticer(connection_base &c, noticer *t) throw () :
00993     m_c(c),
00994     m_org()
00995   {
00996     PGSTD::auto_ptr<noticer> x(t);
00997     PGSTD::auto_ptr<noticer> y(c.set_noticer(x));
00998     m_org = y;
00999   }
01000 
01001 private:
01002   connection_base &m_c;
01003   PGSTD::auto_ptr<noticer> m_org;
01004 
01006   scoped_noticer();
01007   scoped_noticer(const scoped_noticer &);
01008   scoped_noticer operator=(const scoped_noticer &);
01009 };
01010 
01011 
01013 class PQXX_LIBEXPORT disable_noticer : scoped_noticer
01014 {
01015 public:
01016   explicit disable_noticer(connection_base &c) :
01017     scoped_noticer(c, new nonnoticer) {}
01018 };
01019 
01020 
01021 namespace internal
01022 {
01023 
01025 class PQXX_LIBEXPORT reactivation_avoidance_exemption
01026 {
01027 public:
01028   explicit reactivation_avoidance_exemption(connection_base &C);
01029   ~reactivation_avoidance_exemption();
01030 
01031   void close_connection() throw () { m_open = false; }
01032 
01033 private:
01034   connection_base &m_home;
01035   int m_count;
01036   bool m_open;
01037 };
01038 
01039 
01040 void wait_read(const internal::pq::PGconn *);
01041 void wait_read(const internal::pq::PGconn *, long seconds, long microseconds);
01042 void wait_write(const internal::pq::PGconn *);
01043 } // namespace pqxx::internal
01044 
01045 
01046 } // namespace pqxx
01047 
01048 #include "pqxx/compiler-internal-post.hxx"
01049 
01050 #endif
01051 

Generated on Mon Feb 15 18:22:41 2010 for libpqxx by  doxygen 1.5.5