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
00078 class PQXX_LIBEXPORT connection_base
00079 {
00080
public:
00082
00087
explicit connection_base(
const PGSTD::string &ConnInfo);
00088
00090
00094
explicit connection_base(
const char ConnInfo[]);
00095
00097
virtual ~connection_base() =0;
00098
00100
void disconnect()
throw ();
00101
00103
bool is_open()
const throw ();
00104
00106
00114
template<
typename TRANSACTOR>
00115
void perform(
const TRANSACTOR &T,
int Attempts=3);
00116
00117
#ifdef PQXX_BROKEN_MEMBER_TEMPLATE_DEFAULT_ARG
00118
template<
typename TRANSACTOR>
void perform(TRANSACTOR &T,
int Attempts);
00119
template<
typename TRANSACTOR>
00120
void perform(
const TRANSACTOR &T) { perform(T, 3); }
00121
#endif
00122
00123
00125
00134 PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N)
00135
throw ();
00136 noticer *get_noticer() const throw () {
return m_Noticer.get(); }
00137
00139
void process_notice(
const char[]) throw ();
00141
void process_notice(const PGSTD::string &msg) throw ();
00142
00144
void trace(FILE *) throw ();
00145
00147
00151
int get_notifs();
00152
00153
00154
00156 const
char *dbname()
00157 { halfconnect();
return PQdb(m_Conn); }
00158
00160 const char *username()
00161 { halfconnect();
return PQuser(m_Conn); }
00162
00164 const char *hostname()
00165 { halfconnect();
return PQhost(m_Conn); }
00166
00168 const char *port()
00169 { halfconnect();
return PQport(m_Conn); }
00170
00172 const char *options() const throw ()
00173 {
return m_ConnInfo.c_str(); }
00174
00175
00177
00184 int backendpid() const throw ()
00185 {
return m_Conn ? PQbackendPID(m_Conn) : 0; }
00186
00188
00198 void activate() { Connect(); }
00199
00201
00209
void deactivate();
00210
00212
00218 void set_client_encoding(
const PGSTD::string &Encoding)
00219 { set_variable(
"CLIENT_ENCODING", Encoding); }
00220
00222
00236
void set_variable(
const PGSTD::string &Var,
00237
const PGSTD::string &Value);
00238
00240
00246 PGSTD::string get_variable(
const PGSTD::string &);
00247
00249
00252
int await_notification();
00253
00255
00258
int await_notification(
long seconds,
long microseconds);
00259
00260
#ifdef PQXX_DEPRECATED_HEADERS
00261
00262
void Disconnect() throw () { disconnect(); }
00264
template<
typename TRANSACTOR>
void Perform(
const TRANSACTOR &T,
int A=3)
00265 {
return perform(T,A); }
00267 PGSTD::auto_ptr<noticer> SetNoticer(PGSTD::auto_ptr<noticer> N)
00268 {
return set_noticer(N); }
00270 noticer *GetNoticer() const throw ()
00271 {
return get_noticer(); }
00273
void ProcessNotice(
const char msg[])
throw () {
return process_notice(msg); }
00275
void ProcessNotice(
const PGSTD::string &msg)
throw ()
00276 {
return process_notice(msg); }
00278
void Trace(FILE *F) { trace(F); }
00280
void GetNotifs() { get_notifs(); }
00282
const char *DbName() {
return dbname(); }
00284
const char *UserName() {
return username(); }
00286
const char *HostName() {
return hostname(); }
00288
const char *Port() {
return port(); }
00290
const char *Options() const throw () {
return options(); }
00292
int BackendPID()
const {
return backendpid(); }
00294
void Activate() { activate(); }
00296
void Deactivate() { deactivate(); }
00298
void SetClientEncoding(
const PGSTD::string &E) { set_client_encoding(E); }
00300
void SetVariable(
const PGSTD::string &Var,
const PGSTD::string &Val)
00301 { set_variable(Var, Val); }
00302
#endif
00303
00304
00305
protected:
00307
void Connect();
00308
00310
virtual void startconnect() =0;
00311
00313
virtual void completeconnect() =0;
00314
00316 virtual void dropconnect() throw () {}
00317
00319 PGconn *get_conn() const throw () {
return m_Conn; }
00320
00322 void set_conn(PGconn *C)
throw () { m_Conn = C; }
00323
00324
void wait_read() const;
00325
void wait_read(
long seconds,
long microseconds) const;
00326
void wait_write() const;
00327
00328 private:
00329
void SetupState();
00330
void InternalSetTrace() throw ();
00331
int Status()
const {
return PQstatus(m_Conn); }
00332
const char *ErrMsg() const;
00333
void Reset();
00334
void close() throw ();
00335
void RestoreVars();
00336
void halfconnect();
00337
int set_fdmask() const;
00338
void clear_fdmask() throw ();
00339 PGSTD::string RawGetVar(const PGSTD::string &);
00340
void process_notice_raw(const
char msg[]) throw ();
00341
00342
00344 PGSTD::string m_ConnInfo;
00345
00347 PGconn *m_Conn;
00349 internal::unique<transaction_base> m_Trans;
00350
00352 PGSTD::auto_ptr<noticer> m_Noticer;
00354 FILE *m_Trace;
00355
00356 typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00358 TriggerList m_Triggers;
00359
00361 PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00362
00363 mutable fd_set m_fdmask;
00364
00365 friend class transaction_base;
00366 result Exec(const
char[],
int Retries);
00367 result exec_prepared(const
char[],
00368
int NumParams,
00369 const
char *const *Params,
00370
int Retries);
00371
void RegisterTransaction(transaction_base *);
00372
void UnregisterTransaction(transaction_base *) throw ();
00373
void MakeEmpty(result &, ExecStatusType=PGRES_EMPTY_QUERY);
00374
bool ReadCopyLine(PGSTD::string &);
00375
void WriteCopyLine(const PGSTD::string &);
00376
void EndCopyWrite();
00377
void start_exec(const PGSTD::string &);
00378 PGresult *get_result();
00379
00380
void RawSetVar(const PGSTD::string &Var, const PGSTD::string &Value);
00381
void AddVariables(const PGSTD::map<PGSTD::string, PGSTD::string> &);
00382
00383 friend class largeobject;
00384 PGconn *RawConnection()
const {
return m_Conn; }
00385
00386
friend class trigger;
00387
void AddTrigger(trigger *);
00388
void RemoveTrigger(trigger *) throw ();
00389
00390 friend class pipeline;
00391
void consume_input() throw () { PQconsumeInput(m_Conn); }
00392
bool is_busy() const throw () {
return PQisBusy(m_Conn); }
00393
00394
00395 connection_base(
const connection_base &);
00396 connection_base &operator=(
const connection_base &);
00397 };
00398
00399
00400 }
00401
00402
00403
00404 inline pqxx::connection_base::~connection_base()
00405 {
00406 close();
00407 }
00408
00409