Main Page | 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 #ifdef _WIN32
00025 #include <winsock2.h>   // for fd_set
00026 #endif  // _WIN32
00027 
00028 #include "pqxx/except"
00029 #include "pqxx/util"
00030 
00031 
00032 /* Use of the libpqxx library starts here.
00033  *
00034  * Everything that can be done with a database through libpqxx must go through
00035  * a connection object derived from connection_base.
00036  */
00037 
00038 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00039  */
00040 
00041 namespace pqxx
00042 {
00043 class result;
00044 class transaction_base;
00045 class trigger;
00046 
00047 
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 };
00067 
00068 
00070 
00090 class PQXX_LIBEXPORT connection_base
00091 {
00092 public:
00094 
00104   explicit connection_base(const PGSTD::string &ConnInfo);              //[t2]
00105 
00107 
00111   explicit connection_base(const char ConnInfo[]);                      //[t2]
00112 
00114   virtual ~connection_base() =0;                                        //[t1]
00115 
00117   void disconnect() throw ();                                           //[t2]
00118 
00120 
00124   bool is_open() const throw ();                                        //[t1]
00125 
00127 
00135   template<typename TRANSACTOR>
00136   void perform(const TRANSACTOR &T, int Attempts);                      //[t4]
00137 
00139 
00146   template<typename TRANSACTOR>
00147   void perform(const TRANSACTOR &T) { perform(T, 3); }
00148 
00149   // TODO: Define a default noticer (mainly to help out Windows users)
00151 
00163   PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N)
00164     throw ();                                                           //[t14]
00165   noticer *get_noticer() const throw () { return m_Noticer.get(); }     //[t14]
00166 
00168   void process_notice(const char[]) throw ();                           //[t14]
00170   void process_notice(const PGSTD::string &) throw ();                  //[t14]
00171 
00173   void trace(FILE *) throw ();                                          //[t3]
00174 
00176 
00180   int get_notifs();                                                     //[t4]
00181 
00182   // Miscellaneous query functions (probably not needed very often)
00183 
00185   const char *dbname();                                                 //[t1]
00186 
00188   const char *username();                                               //[t1]
00189 
00191   const char *hostname();                                               //[t1]
00192 
00194   const char *port();                                                   //[t1]
00195 
00197   const char *options() const throw ()                                  //[t1]
00198         { return m_ConnInfo.c_str(); }
00199 
00200 
00202 
00211   int backendpid() const throw ();                                      //[t1]
00212 
00214 
00224   void activate();                                                      //[t12]
00225 
00227 
00235   void deactivate();                                                    //[t12]
00236 
00238 
00244   void set_client_encoding(const PGSTD::string &Encoding)               //[t7]
00245         { set_variable("CLIENT_ENCODING", Encoding); }
00246 
00248 
00264   void set_variable(const PGSTD::string &Var,
00265                     const PGSTD::string &Value);                        //[t60]
00266 
00268 
00275   PGSTD::string get_variable(const PGSTD::string &);                    //[t60]
00276 
00278 
00281   int await_notification();                                             //[t78]
00282 
00284 
00288   int await_notification(long seconds, long microseconds);              //[t79]
00289 
00291 
00309   void prepare(const PGSTD::string &name, const PGSTD::string &def)     //[t85]
00310         { pq_prepare(name, def, ""); }
00311 
00313 
00331   template<typename ITER>
00332     void prepare(const PGSTD::string &name,
00333         const PGSTD::string &def,
00334         ITER beginparms,
00335         ITER endparms)                                                  //[t85]
00336   {
00337     pq_prepare(name, def, 
00338         (beginparms==endparms) ? 
00339                 "" : ("("+separated_list(",",beginparms,endparms)+")"));
00340   }
00341 
00343 
00361   template<typename CNTNR>
00362     void prepare(const PGSTD::string &name,
00363         const PGSTD::string &def,
00364         const CNTNR &params)                                            //[t85]
00365         { prepare(name, def, params.begin(), params.end()); }
00366 
00368   void unprepare(const PGSTD::string &name);                            //[t85]
00369 
00370 #ifdef PQXX_DEPRECATED_HEADERS
00371 
00372   void Disconnect() throw () { disconnect(); }
00374   template<typename TRANSACTOR> void Perform(const TRANSACTOR &T, int A=3)
00375         { return perform(T,A); }
00377   PGSTD::auto_ptr<noticer> SetNoticer(PGSTD::auto_ptr<noticer> N)
00378         { return set_noticer(N); }
00380   noticer *GetNoticer() const throw ()
00381         { return get_noticer(); }
00383   void ProcessNotice(const char msg[]) throw () { return process_notice(msg); }
00385   void ProcessNotice(const PGSTD::string &msg) throw ()
00386         { return process_notice(msg); }
00388   void Trace(FILE *F) { trace(F); }
00390   void GetNotifs() { get_notifs(); }
00392   const char *DbName() { return dbname(); }
00394   const char *UserName() { return username(); }
00396   const char *HostName() { return hostname(); }
00398   const char *Port() { return port(); }
00400   const char *Options() const throw () { return options(); }
00402   int BackendPID() const { return backendpid(); }
00404   void Activate() { activate(); }
00406   void Deactivate() { deactivate(); }
00408   void SetClientEncoding(const PGSTD::string &E) { set_client_encoding(E); }
00410   void SetVariable(const PGSTD::string &Var, const PGSTD::string &Val)
00411         { set_variable(Var, Val); }
00412 #endif
00413 
00414 
00415 protected:
00417 
00418   virtual void startconnect() =0;
00419 
00421 
00422   virtual void completeconnect() =0;
00423 
00425 
00426   virtual void dropconnect() throw () {}
00427 
00429   internal::pq::PGconn *get_conn() const throw () { return m_Conn; }
00430 
00432   void set_conn(internal::pq::PGconn *C) throw () { m_Conn = C; }
00433 
00434   void close() throw ();
00435   void wait_read() const;
00436   void wait_read(long seconds, long microseconds) const;
00437   void wait_write() const;
00438 
00439 private:
00440   void PQXX_PRIVATE SetupState();
00441 
00442   void PQXX_PRIVATE InternalSetTrace() throw ();
00443   int PQXX_PRIVATE Status() const throw ();
00444   const char *ErrMsg() const throw ();
00445   void PQXX_PRIVATE Reset();
00446   void PQXX_PRIVATE RestoreVars();
00447   int PQXX_PRIVATE set_fdmask() const;
00448   void PQXX_PRIVATE clear_fdmask() throw ();
00449   PGSTD::string PQXX_PRIVATE RawGetVar(const PGSTD::string &);
00450   void PQXX_PRIVATE process_notice_raw(const char msg[]) throw ();
00451 
00452 
00454   PGSTD::string m_ConnInfo;
00455 
00457   internal::pq::PGconn *m_Conn;
00459   internal::unique<transaction_base> m_Trans;
00460 
00462   PGSTD::auto_ptr<noticer> m_Noticer;
00464   FILE *m_Trace;
00465 
00466   typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00468   TriggerList m_Triggers;
00469 
00471   PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00472 
00474   struct PQXX_PRIVATE prepared_def
00475   {
00477     PGSTD::string definition;
00479     PGSTD::string parameters;
00481     bool registered;
00482 
00483     prepared_def() : definition(), parameters(), registered(false) {}
00484     prepared_def(const PGSTD::string &def, const PGSTD::string &params) :
00485       definition(def), parameters(params), registered(false) {}
00486   };
00487 
00488   typedef PGSTD::map<PGSTD::string, prepared_def> PSMap;
00489 
00491   PSMap m_prepared;
00492 
00493   mutable fd_set m_fdmask;
00494 
00495   friend class transaction_base;
00496   result PQXX_PRIVATE Exec(const char[], int Retries);
00497   void pq_prepare(const PGSTD::string &name,
00498       const PGSTD::string &def,
00499       const PGSTD::string &params);
00500   result pq_exec_prepared(const PGSTD::string &, int, const char *const *);
00501   void PQXX_PRIVATE RegisterTransaction(transaction_base *);
00502   void PQXX_PRIVATE UnregisterTransaction(transaction_base *) throw ();
00503   void PQXX_PRIVATE MakeEmpty(result &);
00504   bool PQXX_PRIVATE ReadCopyLine(PGSTD::string &);
00505   void PQXX_PRIVATE WriteCopyLine(const PGSTD::string &);
00506   void PQXX_PRIVATE EndCopyWrite();
00507   void PQXX_PRIVATE start_exec(const PGSTD::string &);
00508   internal::pq::PGresult *get_result();
00509 
00510   void PQXX_PRIVATE RawSetVar(const PGSTD::string &, const PGSTD::string &);
00511   void PQXX_PRIVATE AddVariables(const PGSTD::map<PGSTD::string,
00512       PGSTD::string> &);
00513 
00514   friend class largeobject;
00515   internal::pq::PGconn *RawConnection() const { return m_Conn; }
00516 
00517   friend class trigger;
00518   void AddTrigger(trigger *);
00519   void RemoveTrigger(trigger *) throw ();
00520 
00521   friend class pipeline;
00522   void PQXX_PRIVATE consume_input() throw ();
00523   bool PQXX_PRIVATE is_busy() const throw ();
00524 
00525   // Not allowed:
00526   connection_base(const connection_base &);
00527   connection_base &operator=(const connection_base &);
00528 };
00529 
00530 
00531 // Put this here so on Windows, any noticers can be deleted in caller's context
00532 inline connection_base::~connection_base()
00533 {
00534   // Visual C++ seems to have a problem with output during destructors!
00535 #ifdef PQXX_QUIET_DESTRUCTORS
00536   set_noticer(PGSTD::auto_ptr<noticer>(new nonnoticer()));
00537 #endif
00538 }
00539 
00540 
00541 namespace internal
00542 {
00543 
00545 
00551 class PQXX_LIBEXPORT scoped_noticer
00552 {
00553 public:
00555 
00559   scoped_noticer(connection_base &c, PGSTD::auto_ptr<noticer> t) throw () :
00560     m_c(c), m_org(c.set_noticer(t)) { }
00561 
00562   ~scoped_noticer() { m_c.set_noticer(m_org); }
00563 
00564 private:
00565   connection_base &m_c;
00566   PGSTD::auto_ptr<noticer> m_org;
00567 
00569   scoped_noticer();
00570   scoped_noticer(const scoped_noticer &);
00571   scoped_noticer operator=(const scoped_noticer &);
00572 };
00573 
00574 
00576 class PQXX_LIBEXPORT disable_noticer : scoped_noticer
00577 {
00578 public:
00579   explicit disable_noticer(connection_base &c) :
00580     scoped_noticer(c, PGSTD::auto_ptr<noticer>(new nonnoticer)) {}
00581 };
00582 
00583 
00584 } // namespace pqxx::internal
00585 
00586 
00587 } // namespace pqxx
00588 

Generated on Fri Jul 1 14:36:19 2005 for libpqxx by  doxygen 1.4.2