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-2004, 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 
00020 #include <map>
00021 #include <memory>
00022 
00023 #ifdef _WIN32
00024 #include <winsock2.h>   // for fd_set
00025 #endif  // _WIN32
00026 
00027 #include "pqxx/except"
00028 #include "pqxx/util"
00029 
00030 
00031 /* Use of the libpqxx library starts here.
00032  *
00033  * Everything that can be done with a database through libpqxx must go through
00034  * a connection object derived from connection_base.
00035  */
00036 
00037 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00038  */
00039 
00040 namespace pqxx
00041 {
00042 class result;
00043 class transaction_base;
00044 class trigger;
00045 
00046 
00048 
00052 struct PQXX_LIBEXPORT noticer : PGSTD::unary_function<const char[], void>
00053 {
00054   virtual ~noticer() throw () {}  
00055   virtual void operator()(const char Msg[]) throw () =0;
00056 };
00057 
00058 
00060 
00080 class PQXX_LIBEXPORT connection_base
00081 {
00082 public:
00084 
00094   explicit connection_base(const PGSTD::string &ConnInfo);              //[t2]
00095 
00097 
00101   explicit connection_base(const char ConnInfo[]);                      //[t2]
00102 
00104   virtual ~connection_base() =0;                                        //[t1]
00105 
00107   void disconnect() throw ();                                           //[t2]
00108 
00110 
00114   bool is_open() const throw ();                                        //[t1]
00115 
00117 
00125   template<typename TRANSACTOR> 
00126   void perform(const TRANSACTOR &T, int Attempts=3);                    //[t4]
00127 
00128 #ifdef PQXX_BROKEN_MEMBER_TEMPLATE_DEFAULT_ARG
00129   template<typename TRANSACTOR> void perform(TRANSACTOR &T, int Attempts);
00130   template<typename TRANSACTOR>
00131   void perform(const TRANSACTOR &T) { perform(T, 3); }
00132 #endif
00133 
00134   // TODO: Define a default noticer (mainly to help out Windows users)
00136 
00148   PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N) 
00149     throw ();                                                           //[t14]
00150   noticer *get_noticer() const throw () { return m_Noticer.get(); }     //[t14]
00151 
00153   void process_notice(const char[]) throw ();                           //[t14]
00155   void process_notice(const PGSTD::string &) throw ();                  //[t14]
00156 
00158   void trace(FILE *) throw ();                                          //[t3]
00159 
00161 
00165   int get_notifs();                                                     //[t4]
00166 
00167   // Miscellaneous query functions (probably not needed very often)
00168  
00170   const char *dbname()                                                  //[t1]
00171         { halfconnect(); return PQdb(m_Conn); }
00172 
00174   const char *username()                                                //[t1]
00175         { halfconnect(); return  PQuser(m_Conn); }
00176 
00178   const char *hostname()                                                //[t1]
00179         { halfconnect(); return PQhost(m_Conn); }
00180 
00182   const char *port()                                                    //[t1]
00183         { halfconnect(); return PQport(m_Conn); }
00184 
00186   const char *options() const throw ()                                  //[t1]
00187         { return m_ConnInfo.c_str(); }
00188 
00189 
00191 
00200   int backendpid() const throw ()                                       //[t1]
00201         { return m_Conn ? PQbackendPID(m_Conn) : 0; }
00202 
00204 
00214   void activate() { Connect(); }                                        //[t12]
00215 
00217 
00225   void deactivate();                                                    //[t12]
00226 
00228 
00234   void set_client_encoding(const PGSTD::string &Encoding)               //[t7]
00235         { set_variable("CLIENT_ENCODING", Encoding); }
00236 
00238 
00254   void set_variable(const PGSTD::string &Var, 
00255                     const PGSTD::string &Value);                        //[t60]
00256 
00258 
00265   PGSTD::string get_variable(const PGSTD::string &);                    //[t60]
00266 
00268 
00271   int await_notification();                                             //[t78]
00272 
00274 
00278   int await_notification(long seconds, long microseconds);              //[t79]
00279 
00280 #ifdef PQXX_DEPRECATED_HEADERS
00281 
00282   void Disconnect() throw () { disconnect(); }
00284   template<typename TRANSACTOR> void Perform(const TRANSACTOR &T, int A=3)
00285         { return perform(T,A); }
00287   PGSTD::auto_ptr<noticer> SetNoticer(PGSTD::auto_ptr<noticer> N)
00288         { return set_noticer(N); }
00290   noticer *GetNoticer() const throw () 
00291         { return get_noticer(); }
00293   void ProcessNotice(const char msg[]) throw () { return process_notice(msg); }
00295   void ProcessNotice(const PGSTD::string &msg) throw () 
00296         { return process_notice(msg); }
00298   void Trace(FILE *F) { trace(F); }
00300   void GetNotifs() { get_notifs(); }
00302   const char *DbName() { return dbname(); }
00304   const char *UserName() { return username(); }
00306   const char *HostName() { return hostname(); }
00308   const char *Port() { return port(); }
00310   const char *Options() const throw () { return options(); }
00312   int BackendPID() const { return backendpid(); }
00314   void Activate() { activate(); }
00316   void Deactivate() { deactivate(); }
00318   void SetClientEncoding(const PGSTD::string &E) { set_client_encoding(E); }
00320   void SetVariable(const PGSTD::string &Var, const PGSTD::string &Val)
00321         { set_variable(Var, Val); }
00322 #endif
00323 
00324 
00325 protected:
00327 
00328   virtual void startconnect() =0;
00329 
00331 
00332   virtual void completeconnect() =0;
00333 
00335 
00336   virtual void dropconnect() throw () {}
00337 
00339   internal::pq::PGconn *get_conn() const throw () { return m_Conn; }
00340 
00342   void set_conn(internal::pq::PGconn *C) throw () { m_Conn = C; }
00343 
00344   void close() throw ();
00345   void wait_read() const;
00346   void wait_read(long seconds, long microseconds) const;
00347   void wait_write() const;
00348 
00349 private:
00351   void Connect();
00352   void SetupState();
00353 
00354   void InternalSetTrace() throw ();
00355   int Status() const throw () { return PQXXPQ::PQstatus(m_Conn); }
00356   const char *ErrMsg() const throw ();
00357   void Reset();
00358   void RestoreVars();
00359   void halfconnect();
00360   int set_fdmask() const;
00361   void clear_fdmask() throw ();
00362   PGSTD::string RawGetVar(const PGSTD::string &);
00363   void process_notice_raw(const char msg[]) throw ();
00364 
00365 
00367   PGSTD::string m_ConnInfo;
00368 
00370   internal::pq::PGconn *m_Conn;
00372   internal::unique<transaction_base> m_Trans;
00373 
00375   PGSTD::auto_ptr<noticer> m_Noticer;
00377   FILE *m_Trace;
00378 
00379   typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00381   TriggerList m_Triggers;
00382 
00384   PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00385 
00386   mutable fd_set m_fdmask;
00387 
00388   friend class transaction_base;
00389   result Exec(const char[], int Retries);
00390   result exec_prepared(const char[], 
00391       int NumParams,
00392       const char *const *Params,
00393       int Retries);
00394   void RegisterTransaction(transaction_base *);
00395   void UnregisterTransaction(transaction_base *) throw ();
00396   void MakeEmpty(result &);
00397   bool ReadCopyLine(PGSTD::string &);
00398   void WriteCopyLine(const PGSTD::string &);
00399   void EndCopyWrite();
00400   void start_exec(const PGSTD::string &);
00401   internal::pq::PGresult *get_result();
00402 
00403   void RawSetVar(const PGSTD::string &Var, const PGSTD::string &Value);
00404   void AddVariables(const PGSTD::map<PGSTD::string, PGSTD::string> &);
00405 
00406   friend class largeobject;
00407   internal::pq::PGconn *RawConnection() const { return m_Conn; }
00408 
00409   friend class trigger;
00410   void AddTrigger(trigger *);
00411   void RemoveTrigger(trigger *) throw ();
00412 
00413   friend class pipeline;
00414   void consume_input() throw () { PQconsumeInput(m_Conn); }
00415   bool is_busy() const throw () { return PQisBusy(m_Conn); }
00416 
00417   // Not allowed:
00418   connection_base(const connection_base &);
00419   connection_base &operator=(const connection_base &);
00420 };
00421 
00422 
00423 }
00424 
00425 
00426 // Put this here so on Windows, any noticer will be deleted in caller's context
00427 inline pqxx::connection_base::~connection_base()
00428 {
00429 }
00430 
00431 

Generated on Mon Nov 15 11:27:59 2004 for libpqxx by  doxygen 1.3.9.1