00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
#include "pqxx/connection_base"
00031
#include "pqxx/isolation"
00032
#include "pqxx/result"
00033
00034
00035
00036
00037
00038
namespace pqxx
00039 {
00040
class connection_base;
00041
class transaction_base;
00042
00043
00044 namespace internal
00045 {
00046 class PQXX_LIBEXPORT transactionfocus :
public namedclass
00047 {
00048
public:
00049 transactionfocus(
transaction_base &t,
00050
const PGSTD::string &Name,
00051
const PGSTD::string &Classname) :
00052
namedclass(Name, Classname),
00053 m_Trans(t),
00054 m_registered(false)
00055 {
00056 }
00057
00058
protected:
00059
void register_me();
00060
void unregister_me() throw ();
00061
void reg_pending_error(const PGSTD::string &) throw ();
00062 bool registered() const throw () {
return m_registered; }
00063
00064 transaction_base &m_Trans;
00065
00066
private:
00067
bool m_registered;
00068
00070 transactionfocus();
00072 transactionfocus(
const transactionfocus &);
00074 transactionfocus &operator=(
const transactionfocus &);
00075 };
00076 }
00077
00078
00079
00081
00089 class PQXX_LIBEXPORT transaction_base :
public internal::namedclass
00090 {
00091
00092
public:
00094 typedef isolation_traits<read_committed> isolation_tag;
00095
00096
virtual ~transaction_base() =0;
00097
00099
00111
void commit();
00112
00114
00117
void abort();
00118
00120
00124
result exec(
const char Query[],
00125
const PGSTD::string &Desc=PGSTD::string());
00126
00128
00135 result exec(
const PGSTD::string &Query,
00136
const PGSTD::string &Desc=PGSTD::string())
00137 {
return exec(Query.c_str(), Desc); }
00138
00139 result exec(
const PGSTD::stringstream &Query,
00140
const PGSTD::string &Desc=PGSTD::string())
00141 {
return exec(Query.str(), Desc); }
00142
00144 void process_notice(
const char Msg[])
const
00145 { m_Conn.process_notice(Msg); }
00147 void process_notice(
const PGSTD::string &Msg)
const
00148 { m_Conn.process_notice(Msg); }
00149
00151 connection_base &conn()
const {
return m_Conn; }
00152
00154
00162
void set_variable(
const PGSTD::string &Var,
const PGSTD::string &Val);
00163
00165
00171 PGSTD::string get_variable(
const PGSTD::string &) const;
00172
00173 #ifdef PQXX_DEPRECATED_HEADERS
00175
void Commit() { commit(); }
00177
void Abort() { abort(); }
00179 result Exec(
const char Q[],
const PGSTD::string &D=PGSTD::string())
00180 {
return exec(Q,D); }
00182 result Exec(
const PGSTD::string &Q,
const PGSTD::string &D=PGSTD::string())
00183 {
return exec(Q,D); }
00185
void ProcessNotice(
const char M[])
const {
return process_notice(M); }
00187
void ProcessNotice(
const PGSTD::string &M)
const {
return process_notice(M); }
00189 PGSTD::string Name()
const {
return name(); }
00191 connection_base &Conn()
const {
return conn(); }
00193
void SetVariable(
const PGSTD::string &Var,
const PGSTD::string &Val)
00194 { set_variable(Var,Val); }
00195
#endif
00196
00197
protected:
00199
00202
explicit transaction_base(connection_base &,
00203
const PGSTD::string &TName,
00204
const PGSTD::string &CName);
00205
00207
00209
void Begin();
00210
00212
void End() throw ();
00213
00215 virtual
void do_begin() =0;
00217 virtual result do_exec(const
char Query[]) =0;
00219 virtual
void do_commit() =0;
00221 virtual
void do_abort() =0;
00222
00223
00224
00226
00234 result DirectExec(const
char C[],
int Retries=0);
00235
00236 private:
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 enum Status
00255 {
00256 st_nascent,
00257 st_active,
00258 st_aborted,
00259 st_committed,
00260 st_in_doubt
00261 };
00262
00263
00264
void CheckPendingError();
00265
00266
friend class Cursor;
00267
friend class cursor_base;
00268
int GetUniqueCursorNum() {
return m_UniqueCursorNum++; }
00269
void MakeEmpty(result &R)
const { m_Conn.MakeEmpty(R); }
00270
00271
friend class internal::transactionfocus;
00272
void RegisterFocus(internal::transactionfocus *);
00273
void UnregisterFocus(internal::transactionfocus *) throw ();
00274
void RegisterPendingError(const PGSTD::string &) throw ();
00275 friend class tablereader;
00276
void BeginCopyRead(const PGSTD::string &Table, const PGSTD::string &Columns);
00277
bool ReadCopyLine(PGSTD::string &L) {
return m_Conn.ReadCopyLine(L); }
00278
friend class tablewriter;
00279
void BeginCopyWrite(
const PGSTD::string &Table,
00280
const PGSTD::string &Columns = PGSTD::string());
00281
void WriteCopyLine(
const PGSTD::string &L) { m_Conn.WriteCopyLine(L); }
00282
void EndCopyWrite() { m_Conn.EndCopyWrite(); }
00283
00284
friend class pipeline;
00285
void start_exec(
const PGSTD::string &Q) { m_Conn.start_exec(Q); }
00286 PGresult *get_result() {
return m_Conn.get_result(); }
00287
void consume_input() throw () { m_Conn.consume_input(); }
00288
bool is_busy() const throw () {
return m_Conn.is_busy(); }
00289
00290 connection_base &m_Conn;
00291
00292
int m_UniqueCursorNum;
00293 internal::unique<internal::transactionfocus> m_Focus;
00294 Status m_Status;
00295
bool m_Registered;
00296
mutable PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00297 PGSTD::string m_PendingError;
00298
00300 transaction_base();
00302 transaction_base(
const transaction_base &);
00304 transaction_base &operator=(
const transaction_base &);
00305 };
00306
00307 }
00308
00309