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
virtual void startconnect() =0;
00315
00317
virtual void completeconnect() =0;
00318
00320 virtual void dropconnect() throw () {}
00321
00323 internal::pq::PGconn *get_conn() const throw () {
return m_Conn; }
00324
00326 void set_conn(
internal::pq::PGconn *C)
throw () { m_Conn = C; }
00327
00328
void wait_read() const;
00329
void wait_read(
long seconds,
long microseconds) const;
00330
void wait_write() const;
00331
00332 private:
00334
void Connect();
00335
void close() throw ();
00336
void SetupState();
00337
00338
void InternalSetTrace() throw ();
00339
int Status() const throw () {
return PQXXPQ::PQstatus(m_Conn); }
00340
const char *ErrMsg() const throw ();
00341
void Reset();
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