00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
#include <map>
00021 
#include <memory>
00022 
00023 
#ifdef _WIN32
00024 
#include <winsock2.h>   
00025 
#endif  // _WIN32
00026 
00027 
#include "pqxx/except"
00028 
#include "pqxx/util"
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
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);              
00095 
00097 
00101   
explicit connection_base(
const char ConnInfo[]);                      
00102 
00104   
virtual ~connection_base() =0;                                        
00105 
00107   
void disconnect() 
throw ();                                           
00108 
00110   
bool is_open() 
const throw ();                                        
00111 
00113 
00121   
template<
typename TRANSACTOR> 
00122   
void perform(
const TRANSACTOR &T, 
int Attempts=3);                    
00123 
00124 
#ifdef PQXX_BROKEN_MEMBER_TEMPLATE_DEFAULT_ARG
00125 
  template<
typename TRANSACTOR> 
void perform(TRANSACTOR &T, 
int Attempts);
00126   
template<
typename TRANSACTOR>
00127   
void perform(
const TRANSACTOR &T) { perform(T, 3); }
00128 
#endif
00129 
00130   
00132 
00141   PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N) 
00142     
throw ();                                                           
00143   noticer *get_noticer() const throw () { 
return m_Noticer.get(); }     
00144 
00146   
void process_notice(
const char[]) throw ();                           
00148   
void process_notice(const PGSTD::string &msg) throw ();               
00149 
00151   
void trace(FILE *) throw ();                                          
00152 
00154 
00158   
int get_notifs();                                                     
00159 
00160   
00161  
00163   const 
char *dbname()                                                  
00164         { halfconnect(); 
return PQdb(m_Conn); }
00165 
00167   const char *username()                                                
00168         { halfconnect(); 
return  PQuser(m_Conn); }
00169 
00171   const char *hostname()                                                
00172         { halfconnect(); 
return PQhost(m_Conn); }
00173 
00175   const char *port()                                                    
00176         { halfconnect(); 
return PQport(m_Conn); }
00177 
00179   const char *options() const throw ()                                  
00180         { 
return m_ConnInfo.c_str(); }
00181 
00182 
00184 
00191   int backendpid() const throw ()                                       
00192         { 
return m_Conn ? PQbackendPID(m_Conn) : 0; }
00193 
00195 
00205   void activate() { Connect(); }                                        
00206 
00208 
00216   
void deactivate();                                                    
00217 
00219 
00225   void set_client_encoding(
const PGSTD::string &Encoding)               
00226         { set_variable(
"CLIENT_ENCODING", Encoding); }
00227 
00229 
00243   
void set_variable(
const PGSTD::string &Var, 
00244                     
const PGSTD::string &Value);                        
00245 
00247 
00253   PGSTD::string get_variable(
const PGSTD::string &);                    
00254 
00256 
00259   
int await_notification();                                             
00260 
00262 
00265   
int await_notification(
long seconds, 
long microseconds);              
00266 
00267 
#ifdef PQXX_DEPRECATED_HEADERS
00268 
00269   
void Disconnect() throw () { disconnect(); }
00271   
template<
typename TRANSACTOR> 
void Perform(
const TRANSACTOR &T, 
int A=3)
00272         { 
return perform(T,A); }
00274   PGSTD::auto_ptr<noticer> SetNoticer(PGSTD::auto_ptr<noticer> N)
00275         { 
return set_noticer(N); }
00277   noticer *GetNoticer() const throw () 
00278         { 
return get_noticer(); }
00280   
void ProcessNotice(
const char msg[]) 
throw () { 
return process_notice(msg); }
00282   
void ProcessNotice(
const PGSTD::string &msg) 
throw () 
00283         { 
return process_notice(msg); }
00285   
void Trace(FILE *F) { trace(F); }
00287   
void GetNotifs() { get_notifs(); }
00289   
const char *DbName() { 
return dbname(); }
00291   
const char *UserName() { 
return username(); }
00293   
const char *HostName() { 
return hostname(); }
00295   
const char *Port() { 
return port(); }
00297   
const char *Options() const throw () { 
return options(); }
00299   
int BackendPID()
 const { 
return backendpid(); }
00301   
void Activate() { activate(); }
00303   
void Deactivate() { deactivate(); }
00305   
void SetClientEncoding(
const PGSTD::string &E) { set_client_encoding(E); }
00307   
void SetVariable(
const PGSTD::string &Var, 
const PGSTD::string &Val)
00308         { set_variable(Var, Val); }
00309 
#endif
00310 
00311 
00312 
protected:
00314   
void Connect();
00315 
00317   
virtual void startconnect() =0;
00318 
00320   
virtual void completeconnect() =0;
00321 
00323   virtual void dropconnect() throw () {}
00324 
00326   internal::pq::PGconn *get_conn() const throw () { 
return m_Conn; }
00327 
00329   void set_conn(internal::pq::PGconn *C) 
throw () { m_Conn = C; }
00330 
00331   
void wait_read() const;
00332   
void wait_read(
long seconds, 
long microseconds) const;
00333   
void wait_write() const;
00334 
00335 private:
00336   
void SetupState();
00337   
void InternalSetTrace() throw ();
00338   
int Status()
 const { 
return internal::pq::PQstatus(m_Conn); }
00339   
const char *ErrMsg() const;
00340   
void Reset();
00341   
void close() throw ();
00342   
void RestoreVars();
00343   
void halfconnect();
00344   
int set_fdmask() const;
00345   
void clear_fdmask() throw ();
00346   PGSTD::string RawGetVar(const PGSTD::string &);
00347   
void process_notice_raw(const 
char msg[]) throw ();
00348 
00349 
00351   PGSTD::string m_ConnInfo;
00352 
00354   internal::pq::PGconn *m_Conn;
00356   internal::unique<transaction_base> m_Trans;
00357 
00359   PGSTD::auto_ptr<noticer> m_Noticer;
00361   FILE *m_Trace;
00362 
00363   typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00365   TriggerList m_Triggers;
00366 
00368   PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00369 
00370   mutable fd_set m_fdmask;
00371 
00372   friend class transaction_base;
00373   result Exec(const 
char[], 
int Retries);
00374   result exec_prepared(const 
char[], 
00375       
int NumParams,
00376       const 
char *const *Params,
00377       
int Retries);
00378   
void RegisterTransaction(transaction_base *);
00379   
void UnregisterTransaction(transaction_base *) throw ();
00380   
void MakeEmpty(result &);
00381   
bool ReadCopyLine(PGSTD::string &);
00382   
void WriteCopyLine(const PGSTD::string &);
00383   
void EndCopyWrite();
00384   
void start_exec(const PGSTD::string &);
00385   internal::pq::PGresult *get_result();
00386 
00387   
void RawSetVar(const PGSTD::string &Var, const PGSTD::string &Value);
00388   
void AddVariables(const PGSTD::map<PGSTD::string, PGSTD::string> &);
00389 
00390   friend class largeobject;
00391   internal::pq::PGconn *RawConnection()
 const { 
return m_Conn; }
00392 
00393   
friend class trigger;
00394   
void AddTrigger(trigger *);
00395   
void RemoveTrigger(trigger *) throw ();
00396 
00397   friend class pipeline;
00398   
void consume_input() throw () { PQconsumeInput(m_Conn); }
00399   
bool is_busy() const throw () { 
return PQisBusy(m_Conn); }
00400 
00401   
00402   connection_base(
const connection_base &);
00403   connection_base &operator=(
const connection_base &);
00404 };
00405 
00406 
00407 }
00408 
00409 
00410 
00411 inline pqxx::connection_base::~connection_base()
00412 {
00413   close();
00414 }
00415 
00416