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

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-2005, 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 #include "pqxx/libcompiler.h"
00020 
00021 #include <map>
00022 #include <memory>
00023 
00024 #include "pqxx/except"
00025 #include "pqxx/util"
00026 
00027 
00028 /* Use of the libpqxx library starts here.
00029  *
00030  * Everything that can be done with a database through libpqxx must go through
00031  * a connection object derived from connection_base.
00032  */
00033 
00034 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00035  */
00036 
00037 namespace pqxx
00038 {
00039 class result;
00040 class transaction_base;
00041 class trigger;
00042 
00043 
00048 
00049 
00053 struct PQXX_LIBEXPORT noticer : PGSTD::unary_function<const char[], void>
00054 {
00055   noticer(){}           // Silences bogus warning in some gcc versions
00056   virtual ~noticer() throw () {}
00057   virtual void operator()(const char Msg[]) throw () =0;
00058 };
00059 
00060 
00062 struct PQXX_LIBEXPORT nonnoticer : noticer
00063 {
00064   nonnoticer(){}        // Silences bogus warning in some gcc versions
00065   virtual void operator()(const char []) throw () {}
00066 };
00068 
00069 
00074 
00075 
00095 class PQXX_LIBEXPORT connection_base
00096 {
00097 public:
00099 
00109   explicit connection_base(const PGSTD::string &ConnInfo);              //[t2]
00110 
00112 
00116   explicit connection_base(const char ConnInfo[]);                      //[t2]
00117 
00119   virtual ~connection_base() =0;                                        //[t1]
00120 
00125 
00126   void disconnect() throw ();                                           //[t2]
00127 
00129 
00139   void activate();                                                      //[t12]
00140 
00142 
00150   void deactivate();                                                    //[t12]
00151 
00153 
00197   void inhibit_reactivation(bool inhibit)                               //[t86]
00198         { m_inhibit_reactivation=inhibit; }
00199 
00201 
00205   bool is_open() const throw ();                                        //[t1]
00207 
00212   // TODO: Define a default noticer (mainly to help out Windows users)
00214 
00226   PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N)
00227     throw ();                                                           //[t14]
00228   noticer *get_noticer() const throw () { return m_Noticer.get(); }     //[t14]
00229 
00231   void process_notice(const char[]) throw ();                           //[t14]
00233   void process_notice(const PGSTD::string &) throw ();                  //[t14]
00235 
00237   void trace(FILE *) throw ();                                          //[t3]
00238 
00247 
00248   const char *dbname();                                                 //[t1]
00249 
00251   const char *username();                                               //[t1]
00252 
00254   const char *hostname();                                               //[t1]
00255 
00257   const char *port();                                                   //[t1]
00258 
00260   const char *options() const throw ()                                  //[t1]
00261         { return m_ConnInfo.c_str(); }
00262 
00263 
00265 
00274   int backendpid() const throw ();                                      //[t1]
00275 
00277 
00291   int sock() const throw ();                                            //[t87]
00292 
00294 
00300   enum capability
00301   {
00303     cap_create_table_with_oids,
00304 
00306     cap_cursor_scroll,
00308     cap_cursor_with_hold,
00310     cap_cursor_update,
00311 
00313     cap_end
00314   };
00315 
00316 
00318 
00331   bool supports(capability c) const throw () { return m_caps[c]; }      //[]
00332 
00334 
00340   void set_client_encoding(const PGSTD::string &Encoding)               //[t7]
00341         { set_variable("CLIENT_ENCODING", Encoding); }
00342 
00344 
00360   void set_variable(const PGSTD::string &Var,
00361                     const PGSTD::string &Value);                        //[t60]
00362 
00364 
00371   PGSTD::string get_variable(const PGSTD::string &);                    //[t60]
00373 
00374 
00379 
00380 
00391   int get_notifs();                                                     //[t4]
00392 
00393 
00395 
00401   int await_notification();                                             //[t78]
00402 
00404 
00410   int await_notification(long seconds, long microseconds);              //[t79]
00412 
00413 
00443 
00444   void prepare(const PGSTD::string &name, const PGSTD::string &def)     //[t85]
00445         { pq_prepare(name, def, ""); }
00446 
00448   template<typename ITER>
00449     void prepare(const PGSTD::string &name,
00450         const PGSTD::string &def,
00451         ITER beginparms,
00452         ITER endparms)                                                  //[t85]
00453   {
00454     pq_prepare(name, def, 
00455         (beginparms==endparms) ? 
00456                 "" : ("("+separated_list(",",beginparms,endparms)+")"));
00457   }
00458 
00460   template<typename CNTNR>
00461     void prepare(const PGSTD::string &name,
00462         const PGSTD::string &def,
00463         const CNTNR &params)                                            //[t85]
00464         { prepare(name, def, params.begin(), params.end()); }
00465 
00467   void unprepare(const PGSTD::string &name);                            //[t85]
00469 
00470 
00487 
00488 
00492   template<typename TRANSACTOR>
00493   void perform(const TRANSACTOR &T, int Attempts);                      //[t4]
00494 
00496 
00499   template<typename TRANSACTOR>
00500   void perform(const TRANSACTOR &T) { perform(T, 3); }
00502 
00503 #ifdef PQXX_DEPRECATED_HEADERS
00504 
00511 
00512   void Disconnect() throw () { disconnect(); }
00514   template<typename TRANSACTOR> void Perform(const TRANSACTOR &T, int A=3)
00515         { perform(T,A); }
00517   PGSTD::auto_ptr<noticer> SetNoticer(PGSTD::auto_ptr<noticer> N)
00518         { return set_noticer(N); }
00520   noticer *GetNoticer() const throw ()
00521         { return get_noticer(); }
00523   void ProcessNotice(const char msg[]) throw () { return process_notice(msg); }
00525   void ProcessNotice(const PGSTD::string &msg) throw ()
00526         { return process_notice(msg); }
00528   void Trace(FILE *F) { trace(F); }
00530   void GetNotifs() { get_notifs(); }
00532   const char *DbName() { return dbname(); }
00534   const char *UserName() { return username(); }
00536   const char *HostName() { return hostname(); }
00538   const char *Port() { return port(); }
00540   const char *Options() const throw () { return options(); }
00542   int BackendPID() const { return backendpid(); }
00544   void Activate() { activate(); }
00546   void Deactivate() { deactivate(); }
00548   void SetClientEncoding(const PGSTD::string &E) { set_client_encoding(E); }
00550   void SetVariable(const PGSTD::string &Var, const PGSTD::string &Val)
00551         { set_variable(Var, Val); }
00553 #endif
00554 
00555 
00556 protected:
00558 
00559   virtual void startconnect() =0;
00560 
00562 
00563   virtual void completeconnect() =0;
00564 
00566 
00567   virtual void dropconnect() throw () {}
00568 
00570   internal::pq::PGconn *get_conn() const throw () { return m_Conn; }
00571 
00573   void set_conn(internal::pq::PGconn *C) throw () { m_Conn = C; }
00574 
00575   void close() throw ();
00576   void wait_read() const;
00577   void wait_read(long seconds, long microseconds) const;
00578   void wait_write() const;
00579 
00580 private:
00581   void PQXX_PRIVATE SetupState();
00582   void PQXX_PRIVATE check_result(const result &, const char Query[]);
00583 
00584   void PQXX_PRIVATE InternalSetTrace() throw ();
00585   int PQXX_PRIVATE Status() const throw ();
00586   const char *ErrMsg() const throw ();
00587   void PQXX_PRIVATE Reset();
00588   void PQXX_PRIVATE RestoreVars();
00589   PGSTD::string PQXX_PRIVATE RawGetVar(const PGSTD::string &);
00590   void PQXX_PRIVATE process_notice_raw(const char msg[]) throw ();
00591 
00592   void read_capabilities() throw ();
00593 
00595   PGSTD::string m_ConnInfo;
00596 
00598   internal::pq::PGconn *m_Conn;
00600   internal::unique<transaction_base> m_Trans;
00601 
00603   PGSTD::auto_ptr<noticer> m_Noticer;
00605   FILE *m_Trace;
00606 
00607   typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00609   TriggerList m_Triggers;
00610 
00612   PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00613 
00615   struct PQXX_PRIVATE prepared_def
00616   {
00618     PGSTD::string definition;
00620     PGSTD::string parameters;
00622     bool registered;
00623 
00624     prepared_def() : definition(), parameters(), registered(false) {}
00625     prepared_def(const PGSTD::string &def, const PGSTD::string &params) :
00626       definition(def), parameters(params), registered(false) {}
00627   };
00628 
00629   typedef PGSTD::map<PGSTD::string, prepared_def> PSMap;
00630 
00632   PSMap m_prepared;
00633 
00635   bool m_caps[cap_end];
00636 
00638   bool m_inhibit_reactivation;
00639 
00641   int m_reactivation_avoidance;
00642 
00643   friend class transaction_base;
00644   result PQXX_PRIVATE Exec(const char[], int Retries);
00645   void pq_prepare(const PGSTD::string &name,
00646       const PGSTD::string &def,
00647       const PGSTD::string &params);
00648   result pq_exec_prepared(const PGSTD::string &, int, const char *const *);
00649   void PQXX_PRIVATE RegisterTransaction(transaction_base *);
00650   void PQXX_PRIVATE UnregisterTransaction(transaction_base *) throw ();
00651   void PQXX_PRIVATE MakeEmpty(result &);
00652   bool PQXX_PRIVATE ReadCopyLine(PGSTD::string &);
00653   void PQXX_PRIVATE WriteCopyLine(const PGSTD::string &);
00654   void PQXX_PRIVATE EndCopyWrite();
00655   void PQXX_PRIVATE start_exec(const PGSTD::string &);
00656   internal::pq::PGresult *get_result();
00657 
00658   void PQXX_PRIVATE RawSetVar(const PGSTD::string &, const PGSTD::string &);
00659   void PQXX_PRIVATE AddVariables(const PGSTD::map<PGSTD::string,
00660       PGSTD::string> &);
00661 
00662   friend class largeobject;
00663   internal::pq::PGconn *RawConnection() const { return m_Conn; }
00664 
00665   friend class trigger;
00666   void AddTrigger(trigger *);
00667   void RemoveTrigger(trigger *) throw ();
00668 
00669   friend class pipeline;
00670   bool PQXX_PRIVATE consume_input() throw ();
00671   bool PQXX_PRIVATE is_busy() const throw ();
00672 
00673   friend class cursor_base;
00674   void reactivation_avoidance_add(int) throw ();
00675   void reactivation_avoidance_dec() throw ();
00676 
00677   // Not allowed:
00678   connection_base(const connection_base &);
00679   connection_base &operator=(const connection_base &);
00680 };
00681 
00683 
00684 
00685 // Put this here so on Windows, any noticers can be deleted in caller's context
00686 inline connection_base::~connection_base()
00687 {
00688   // Visual C++ seems to have a problem with output during destructors!
00689 #ifdef PQXX_QUIET_DESTRUCTORS
00690   PGSTD::auto_ptr<noticer> n(new nonnoticer());
00691   set_noticer(n);
00692 #endif
00693 }
00694 
00695 
00696 namespace internal
00697 {
00698 
00700 
00706 class PQXX_LIBEXPORT scoped_noticer
00707 {
00708 public:
00710 
00714   scoped_noticer(connection_base &c, PGSTD::auto_ptr<noticer> t) throw () :
00715     m_c(c), m_org(c.set_noticer(t)) { }
00716 
00717   ~scoped_noticer() { m_c.set_noticer(m_org); }
00718 
00719 protected:
00721 
00725   scoped_noticer(connection_base &c, noticer *t) throw () :
00726     m_c(c),
00727     m_org()
00728   {
00729     PGSTD::auto_ptr<noticer> x(t);
00730     PGSTD::auto_ptr<noticer> y(c.set_noticer(x));
00731     m_org = y;
00732   }
00733 
00734 private:
00735   connection_base &m_c;
00736   PGSTD::auto_ptr<noticer> m_org;
00737 
00739   scoped_noticer();
00740   scoped_noticer(const scoped_noticer &);
00741   scoped_noticer operator=(const scoped_noticer &);
00742 };
00743 
00744 
00746 class PQXX_LIBEXPORT disable_noticer : scoped_noticer
00747 {
00748 public:
00749   explicit disable_noticer(connection_base &c) :
00750     scoped_noticer(c, new nonnoticer) {}
00751 };
00752 
00753 
00754 } // namespace pqxx::internal
00755 
00756 
00757 } // namespace pqxx
00758 

Generated on Mon Oct 3 20:28:58 2005 for libpqxx by  doxygen 1.4.2