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
00114 bool is_open() const throw ();
00115
00116 #ifndef PQXX_BROKEN_MEMBER_TEMPLATE_DEFAULT_ARG
00117
00118
00125 template<typename TRANSACTOR>
00126 void perform(const TRANSACTOR &T, int Attempts=3);
00127 #else
00128 template<typename TRANSACTOR> void perform(TRANSACTOR &T, int Attempts);
00129 template<typename TRANSACTOR>
00130 void perform(const TRANSACTOR &T) { perform(T, 3); }
00131 #endif
00132
00133
00135
00147 PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N)
00148 throw ();
00149 noticer *get_noticer() const throw () { return m_Noticer.get(); }
00150
00152 void process_notice(const char[]) throw ();
00154 void process_notice(const PGSTD::string &) throw ();
00155
00157 void trace(FILE *) throw ();
00158
00160
00164 int get_notifs();
00165
00166
00167
00169 const char *dbname()
00170 { halfconnect(); return PQdb(m_Conn); }
00171
00173 const char *username()
00174 { halfconnect(); return PQuser(m_Conn); }
00175
00177 const char *hostname()
00178 { halfconnect(); return PQhost(m_Conn); }
00179
00181 const char *port()
00182 { halfconnect(); return PQport(m_Conn); }
00183
00185 const char *options() const throw ()
00186 { return m_ConnInfo.c_str(); }
00187
00188
00190
00199 int backendpid() const throw ()
00200 { return m_Conn ? PQbackendPID(m_Conn) : 0; }
00201
00203
00213 void activate() { Connect(); }
00214
00216
00224 void deactivate();
00225
00227
00233 void set_client_encoding(const PGSTD::string &Encoding)
00234 { set_variable("CLIENT_ENCODING", Encoding); }
00235
00237
00253 void set_variable(const PGSTD::string &Var,
00254 const PGSTD::string &Value);
00255
00257
00264 PGSTD::string get_variable(const PGSTD::string &);
00265
00267
00270 int await_notification();
00271
00273
00277 int await_notification(long seconds, long microseconds);
00278
00279 #ifdef PQXX_DEPRECATED_HEADERS
00280
00281 void Disconnect() throw () { disconnect(); }
00283 template<typename TRANSACTOR> void Perform(const TRANSACTOR &T, int A=3)
00284 { return perform(T,A); }
00286 PGSTD::auto_ptr<noticer> SetNoticer(PGSTD::auto_ptr<noticer> N)
00287 { return set_noticer(N); }
00289 noticer *GetNoticer() const throw ()
00290 { return get_noticer(); }
00292 void ProcessNotice(const char msg[]) throw () { return process_notice(msg); }
00294 void ProcessNotice(const PGSTD::string &msg) throw ()
00295 { return process_notice(msg); }
00297 void Trace(FILE *F) { trace(F); }
00299 void GetNotifs() { get_notifs(); }
00301 const char *DbName() { return dbname(); }
00303 const char *UserName() { return username(); }
00305 const char *HostName() { return hostname(); }
00307 const char *Port() { return port(); }
00309 const char *Options() const throw () { return options(); }
00311 int BackendPID() const { return backendpid(); }
00313 void Activate() { activate(); }
00315 void Deactivate() { deactivate(); }
00317 void SetClientEncoding(const PGSTD::string &E) { set_client_encoding(E); }
00319 void SetVariable(const PGSTD::string &Var, const PGSTD::string &Val)
00320 { set_variable(Var, Val); }
00321 #endif
00322
00323
00324 protected:
00326
00327 virtual void startconnect() =0;
00328
00330
00331 virtual void completeconnect() =0;
00332
00334
00335 virtual void dropconnect() throw () {}
00336
00338 internal::pq::PGconn *get_conn() const throw () { return m_Conn; }
00339
00341 void set_conn(internal::pq::PGconn *C) throw () { m_Conn = C; }
00342
00343 void close() throw ();
00344 void wait_read() const;
00345 void wait_read(long seconds, long microseconds) const;
00346 void wait_write() const;
00347
00348 private:
00350 void Connect();
00351 void SetupState();
00352
00353 void InternalSetTrace() throw ();
00354 int Status() const throw () { return PQXXPQ::PQstatus(m_Conn); }
00355 const char *ErrMsg() const throw ();
00356 void Reset();
00357 void RestoreVars();
00358 void halfconnect();
00359 int set_fdmask() const;
00360 void clear_fdmask() throw ();
00361 PGSTD::string RawGetVar(const PGSTD::string &);
00362 void process_notice_raw(const char msg[]) throw ();
00363
00364
00366 PGSTD::string m_ConnInfo;
00367
00369 internal::pq::PGconn *m_Conn;
00371 internal::unique<transaction_base> m_Trans;
00372
00374 PGSTD::auto_ptr<noticer> m_Noticer;
00376 FILE *m_Trace;
00377
00378 typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00380 TriggerList m_Triggers;
00381
00383 PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00384
00385 mutable fd_set m_fdmask;
00386
00387 friend class transaction_base;
00388 result Exec(const char[], int Retries);
00389 result exec_prepared(const char[],
00390 int NumParams,
00391 const char *const *Params,
00392 int Retries);
00393 void RegisterTransaction(transaction_base *);
00394 void UnregisterTransaction(transaction_base *) throw ();
00395 void MakeEmpty(result &);
00396 bool ReadCopyLine(PGSTD::string &);
00397 void WriteCopyLine(const PGSTD::string &);
00398 void EndCopyWrite();
00399 void start_exec(const PGSTD::string &);
00400 internal::pq::PGresult *get_result();
00401
00402 void RawSetVar(const PGSTD::string &Var, const PGSTD::string &Value);
00403 void AddVariables(const PGSTD::map<PGSTD::string, PGSTD::string> &);
00404
00405 friend class largeobject;
00406 internal::pq::PGconn *RawConnection() const { return m_Conn; }
00407
00408 friend class trigger;
00409 void AddTrigger(trigger *);
00410 void RemoveTrigger(trigger *) throw ();
00411
00412 friend class pipeline;
00413 void consume_input() throw () { PQconsumeInput(m_Conn); }
00414 bool is_busy() const throw () { return PQisBusy(m_Conn); }
00415
00416
00417 connection_base(const connection_base &);
00418 connection_base &operator=(const connection_base &);
00419 };
00420
00421
00422 }
00423
00424
00425
00426 inline pqxx::connection_base::~connection_base()
00427 {
00428 }
00429
00430