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 close() throw ();
00329 void wait_read() const;
00330 void wait_read(long seconds, long microseconds) const;
00331 void wait_write() const;
00332
00333 private:
00335 void Connect();
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 }
00414
00415