00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef PQXX_CONNECTION_BASE_H
00019 #define PQXX_CONNECTION_BASE_H
00020
00021 #include <map>
00022 #include <memory>
00023
00024 #include "pqxx/except.h"
00025 #include "pqxx/util.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 namespace pqxx
00038 {
00039 class result;
00040 class transaction_base;
00041 class trigger;
00042
00044
00048 struct PQXX_LIBEXPORT noticer : PGSTD::unary_function<const char[], void>
00049 {
00050 virtual ~noticer() {}
00051 virtual void operator()(const char Msg[]) throw () =0;
00052 };
00053
00054
00056 template<> inline PGSTD::string Classname(const transaction_base *)
00057 {
00058 return "transaction_base";
00059 }
00060
00061
00063
00081 class PQXX_LIBEXPORT connection_base
00082 {
00083 public:
00085
00090 explicit connection_base(const PGSTD::string &ConnInfo);
00091
00093
00097 explicit connection_base(const char ConnInfo[]);
00098
00100 virtual ~connection_base() =0;
00101
00103 void Disconnect() throw ();
00104
00106 bool is_open() const;
00107
00109
00117 template<typename TRANSACTOR>
00118 void Perform(const TRANSACTOR &T, int Attempts=3);
00119
00120
00122
00123 * noticer is also passed to the caller, so unless it is stored in another
00124 * auto_ptr, it will be deleted from the caller's context.
00125 * This may be important when running under Windows, where a DLL cannot free
00126 * memory allocated by the main program.
00127 * If a noticer exists when the connection_base is destructed, it will also be
00128 * deleted.
00129 * @param N the new message handler; must not be null or equal to the old one
00130 */
00131 PGSTD::auto_ptr<noticer> SetNoticer(PGSTD::auto_ptr<noticer> N);
00132 noticer *GetNoticer() const throw () { return m_Noticer.get(); }
00133
00135 void ProcessNotice(const char[]) throw ();
00137
00138 { ProcessNotice(msg.c_str()); }
00139
00141 void Trace(FILE *);
00142
00144 void GetNotifs();
00145
00146
00147
00149 const char *DbName()
00150 { Activate(); return PQdb(m_Conn); }
00151
00153 const char *UserName()
00154 { Activate(); return PQuser(m_Conn); }
00155
00157 const char *HostName()
00158 { Activate(); return PQhost(m_Conn); }
00159
00161 const char *Port()
00162 { Activate(); return PQport(m_Conn); }
00163
00165 const char *Options() const throw ()
00166 { return m_ConnInfo.c_str(); }
00167
00169
00176 int BackendPID() const
00177 { return m_Conn ? PQbackendPID(m_Conn) : 0; }
00178
00180
00190 void Activate() { if (!m_Conn) Connect(); }
00191
00193
00201 void Deactivate();
00202
00204
00210 void SetClientEncoding(const PGSTD::string &Encoding)
00211 { SetVariable("CLIENT_ENCODING", Encoding); }
00212
00214
00225 void SetVariable(const PGSTD::string &Var, const PGSTD::string &Value);
00226
00227 protected:
00229 void Connect();
00230
00231 private:
00232 void SetupState();
00233 void InternalSetTrace();
00234 int Status() const { return PQstatus(m_Conn); }
00235 const char *ErrMsg() const;
00236 void Reset(const char OnReconnect[]=0);
00237 void close() throw ();
00238 void RestoreVars();
00239
00241 PGSTD::string m_ConnInfo;
00243 PGconn *m_Conn;
00245 unique<transaction_base> m_Trans;
00246
00248 PGSTD::auto_ptr<noticer> m_Noticer;
00250 FILE *m_Trace;
00251
00252 typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00254 TriggerList m_Triggers;
00255
00257 PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00258
00259 friend class transaction_base;
00260 result Exec(const char[], int Retries=3, const char OnReconnect[]=0);
00261 void RegisterTransaction(transaction_base *);
00262 void UnregisterTransaction(transaction_base *) throw ();
00263 void MakeEmpty(result &, ExecStatusType=PGRES_EMPTY_QUERY);
00264 void BeginCopyRead(const PGSTD::string &Table);
00265 bool ReadCopyLine(PGSTD::string &);
00266 void BeginCopyWrite(const PGSTD::string &Table);
00267 void WriteCopyLine(const PGSTD::string &);
00268 void EndCopy();
00269 void RawSetVar(const PGSTD::string &Var, const PGSTD::string &Value);
00270 void AddVariables(const PGSTD::map<PGSTD::string, PGSTD::string> &);
00271
00272 friend class largeobject;
00273 PGconn *RawConnection() const { return m_Conn; }
00274
00275 friend class trigger;
00276 void AddTrigger(trigger *);
00277 void RemoveTrigger(trigger *) throw ();
00278
00279
00280 connection_base(const connection_base &);
00281 connection_base &operator=(const connection_base &);
00282 };
00283
00284
00285 }
00286
00287
00288
00289 inline pqxx::connection_base::~connection_base()
00290 {
00291 close();
00292 }
00293
00294 #endif
00295