00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "pqxx/compiler-public.hxx"
00021 #include "pqxx/compiler-internal-pre.hxx"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "pqxx/connection_base"
00033 #include "pqxx/isolation"
00034 #include "pqxx/result"
00035
00036
00037
00038
00039 namespace pqxx
00040 {
00041 class connection_base;
00042 class transaction_base;
00043
00044
00045 namespace internal
00046 {
00047 class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
00048 {
00049 public:
00050 explicit transactionfocus(transaction_base &t) :
00051 namedclass("transactionfocus"),
00052 m_Trans(t),
00053 m_registered(false)
00054 {
00055 }
00056
00057 protected:
00058 void register_me();
00059 void unregister_me() throw ();
00060 void reg_pending_error(const PGSTD::string &) throw ();
00061 bool registered() const throw () { return m_registered; }
00062
00063 transaction_base &m_Trans;
00064
00065 private:
00066 bool m_registered;
00067
00069 transactionfocus();
00071 transactionfocus(const transactionfocus &);
00073 transactionfocus &operator=(const transactionfocus &);
00074 };
00075
00076 }
00077
00078
00079
00081
00091 class PQXX_LIBEXPORT transaction_base : public virtual internal::namedclass
00092 {
00093 public:
00095 typedef isolation_traits<read_committed> isolation_tag;
00096
00097 virtual ~transaction_base() =0;
00098
00100
00112 void commit();
00113
00115
00118 void abort();
00119
00124
00125 PGSTD::string esc(const char str[]) const;
00127 PGSTD::string esc(const char str[], size_t maxlen) const
00128 { return m_Conn.esc(str,maxlen); }
00130 PGSTD::string esc(const PGSTD::string &) const;
00131
00133
00144 PGSTD::string esc_raw(const unsigned char str[], size_t len) const
00145 { return m_Conn.esc_raw(str, len); }
00147 PGSTD::string esc_raw(const PGSTD::string &) const;
00149
00151
00156 result exec(const char Query[],
00157 const PGSTD::string &Desc=PGSTD::string());
00158
00160
00168 result exec(const PGSTD::string &Query,
00169 const PGSTD::string &Desc=PGSTD::string())
00170 { return exec(Query.c_str(), Desc); }
00171
00172 result exec(const PGSTD::stringstream &Query,
00173 const PGSTD::string &Desc=PGSTD::string())
00174 { return exec(Query.str(), Desc); }
00175
00180
00181
00215 prepare::invocation prepared(const PGSTD::string &statement);
00216
00218
00223
00224 void process_notice(const char Msg[]) const
00225 { m_Conn.process_notice(Msg); }
00227 void process_notice(const PGSTD::string &Msg) const
00228 { m_Conn.process_notice(Msg); }
00230
00232 connection_base &conn() const { return m_Conn; }
00233
00235
00243 void set_variable(const PGSTD::string &Var, const PGSTD::string &Val);
00244
00246
00255 PGSTD::string get_variable(const PGSTD::string &);
00256
00257 #ifdef PQXX_DEPRECATED_HEADERS
00258
00262
00263 void Commit() PQXX_DEPRECATED { commit(); }
00265 void Abort() PQXX_DEPRECATED { abort(); }
00267 result Exec(const char Q[], const PGSTD::string &D=PGSTD::string())
00268 PQXX_DEPRECATED { return exec(Q,D); }
00270 result Exec(const PGSTD::string &Q, const PGSTD::string &D=PGSTD::string())
00271 PQXX_DEPRECATED { return exec(Q,D); }
00273 void ProcessNotice(const char M[]) const PQXX_DEPRECATED
00274 { return process_notice(M); }
00276 void ProcessNotice(const PGSTD::string &M) const PQXX_DEPRECATED
00277 { return process_notice(M); }
00279 PGSTD::string Name() const PQXX_DEPRECATED { return name(); }
00281 connection_base &Conn() const PQXX_DEPRECATED { return conn(); }
00283 void SetVariable(const PGSTD::string &Var, const PGSTD::string &Val)
00284 PQXX_DEPRECATED { set_variable(Var,Val); }
00286 #endif
00287
00288 protected:
00290
00295 explicit transaction_base(connection_base &, bool direct=true);
00296
00298
00300 void Begin();
00301
00303 void End() throw ();
00304
00306 virtual void do_begin() =0;
00308 virtual result do_exec(const char Query[]) =0;
00310 virtual void do_commit() =0;
00312 virtual void do_abort() =0;
00313
00314
00315
00317
00325 result DirectExec(const char C[], int Retries=0);
00326
00328 void reactivation_avoidance_clear() throw ()
00329 {m_reactivation_avoidance.clear();}
00330
00331 private:
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 enum Status
00352 {
00353 st_nascent,
00354 st_active,
00355 st_aborted,
00356 st_committed,
00357 st_in_doubt
00358 };
00359
00360
00361 void PQXX_PRIVATE CheckPendingError();
00362
00363 template<typename T> bool parm_is_null(T *p) const throw () { return !p; }
00364 template<typename T> bool parm_is_null(T) const throw () { return false; }
00365
00366 friend class Cursor;
00367 friend class cursor_base;
00368 void MakeEmpty(result &R) const { m_Conn.MakeEmpty(R); }
00369
00370 friend class internal::transactionfocus;
00371 void PQXX_PRIVATE RegisterFocus(internal::transactionfocus *);
00372 void PQXX_PRIVATE UnregisterFocus(internal::transactionfocus *) throw ();
00373 void PQXX_PRIVATE RegisterPendingError(const PGSTD::string &) throw ();
00374 friend class tablereader;
00375 void PQXX_PRIVATE BeginCopyRead(const PGSTD::string &, const PGSTD::string &);
00376 bool ReadCopyLine(PGSTD::string &L) { return m_Conn.ReadCopyLine(L); }
00377 friend class tablewriter;
00378 void PQXX_PRIVATE BeginCopyWrite(const PGSTD::string &Table,
00379 const PGSTD::string &Columns = PGSTD::string());
00380 void WriteCopyLine(const PGSTD::string &L) { m_Conn.WriteCopyLine(L); }
00381 void EndCopyWrite() { m_Conn.EndCopyWrite(); }
00382
00383 friend class pipeline;
00384 void start_exec(const PGSTD::string &Q) { m_Conn.start_exec(Q); }
00385 internal::pq::PGresult *get_result() { return m_Conn.get_result(); }
00386 void consume_input() throw () { m_Conn.consume_input(); }
00387 bool is_busy() const throw () { return m_Conn.is_busy(); }
00388
00389 friend class prepare::invocation;
00390 result prepared_exec(const PGSTD::string &,
00391 const char *const[],
00392 const int[],
00393 int);
00394
00395 connection_base &m_Conn;
00396
00397 internal::unique<internal::transactionfocus> m_Focus;
00398 Status m_Status;
00399 bool m_Registered;
00400 PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00401 PGSTD::string m_PendingError;
00402
00403 friend class subtransaction;
00405
00407 internal::reactivation_avoidance_counter m_reactivation_avoidance;
00408
00410 transaction_base();
00412 transaction_base(const transaction_base &);
00414 transaction_base &operator=(const transaction_base &);
00415 };
00416
00417 }
00418
00419
00420 #include "pqxx/compiler-internal-post.hxx"