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
00039 namespace pqxx
00040 {
00041 class connection_base;
00042 class transaction_base;
00043
00044
00045 namespace internal
00046 {
00047 class PQXX_LIBEXPORT transactionfocus : public namedclass
00048 {
00049 public:
00050 transactionfocus(transaction_base &t,
00051 const PGSTD::string &Name,
00052 const PGSTD::string &Classname) :
00053 namedclass(Name, Classname),
00054 m_Trans(t),
00055 m_registered(false)
00056 {
00057 }
00058
00059 protected:
00060 void register_me();
00061 void unregister_me() throw ();
00062 void reg_pending_error(const PGSTD::string &) throw ();
00063 bool registered() const throw () { return m_registered; }
00064
00065 transaction_base &m_Trans;
00066
00067 private:
00068 bool m_registered;
00069
00071 transactionfocus();
00073 transactionfocus(const transactionfocus &);
00075 transactionfocus &operator=(const transactionfocus &);
00076 };
00077 }
00078
00079
00080
00082
00090 class PQXX_LIBEXPORT transaction_base : public internal::namedclass
00091 {
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
00121
00126 result exec(const char Query[],
00127 const PGSTD::string &Desc=PGSTD::string());
00128
00130
00138 result exec(const PGSTD::string &Query,
00139 const PGSTD::string &Desc=PGSTD::string())
00140 { return exec(Query.c_str(), Desc); }
00141
00142 result exec(const PGSTD::stringstream &Query,
00143 const PGSTD::string &Desc=PGSTD::string())
00144 { return exec(Query.str(), Desc); }
00145
00147 void process_notice(const char Msg[]) const
00148 { m_Conn.process_notice(Msg); }
00150 void process_notice(const PGSTD::string &Msg) const
00151 { m_Conn.process_notice(Msg); }
00152
00154 connection_base &conn() const { return m_Conn; }
00155
00157
00165 void set_variable(const PGSTD::string &Var, const PGSTD::string &Val);
00166
00168
00174 PGSTD::string get_variable(const PGSTD::string &) const;
00175
00176 #ifdef PQXX_DEPRECATED_HEADERS
00177
00178 void Commit() { commit(); }
00180 void Abort() { abort(); }
00182 result Exec(const char Q[], const PGSTD::string &D=PGSTD::string())
00183 { return exec(Q,D); }
00185 result Exec(const PGSTD::string &Q, const PGSTD::string &D=PGSTD::string())
00186 { return exec(Q,D); }
00188 void ProcessNotice(const char M[]) const { return process_notice(M); }
00190 void ProcessNotice(const PGSTD::string &M) const { return process_notice(M); }
00192 PGSTD::string Name() const { return name(); }
00194 connection_base &Conn() const { return conn(); }
00196 void SetVariable(const PGSTD::string &Var, const PGSTD::string &Val)
00197 { set_variable(Var,Val); }
00198 #endif
00199
00200 protected:
00202
00205 explicit transaction_base(connection_base &,
00206 const PGSTD::string &TName,
00207 const PGSTD::string &CName);
00208
00210
00212 void Begin();
00213
00215 void End() throw ();
00216
00218 virtual void do_begin() =0;
00220 virtual result do_exec(const char Query[]) =0;
00222 virtual void do_commit() =0;
00224 virtual void do_abort() =0;
00225
00226
00227
00229
00237 result DirectExec(const char C[], int Retries=0);
00238
00239 private:
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 enum Status
00260 {
00261 st_nascent,
00262 st_active,
00263 st_aborted,
00264 st_committed,
00265 st_in_doubt
00266 };
00267
00268
00269 void CheckPendingError();
00270
00271 friend class Cursor;
00272 friend class cursor_base;
00273 int GetUniqueCursorNum() { return m_UniqueCursorNum++; }
00274 void MakeEmpty(result &R) const { m_Conn.MakeEmpty(R); }
00275
00276 friend class internal::transactionfocus;
00277 void RegisterFocus(internal::transactionfocus *);
00278 void UnregisterFocus(internal::transactionfocus *) throw ();
00279 void RegisterPendingError(const PGSTD::string &) throw ();
00280 friend class tablereader;
00281 void BeginCopyRead(const PGSTD::string &Table, const PGSTD::string &Columns);
00282 bool ReadCopyLine(PGSTD::string &L) { return m_Conn.ReadCopyLine(L); }
00283 friend class tablewriter;
00284 void BeginCopyWrite(const PGSTD::string &Table,
00285 const PGSTD::string &Columns = PGSTD::string());
00286 void WriteCopyLine(const PGSTD::string &L) { m_Conn.WriteCopyLine(L); }
00287 void EndCopyWrite() { m_Conn.EndCopyWrite(); }
00288
00289 friend class pipeline;
00290 void start_exec(const PGSTD::string &Q) { m_Conn.start_exec(Q); }
00291 internal::pq::PGresult *get_result() { return m_Conn.get_result(); }
00292 void consume_input() throw () { m_Conn.consume_input(); }
00293 bool is_busy() const throw () { return m_Conn.is_busy(); }
00294
00295 connection_base &m_Conn;
00296
00297 int m_UniqueCursorNum;
00298 internal::unique<internal::transactionfocus> m_Focus;
00299 Status m_Status;
00300 bool m_Registered;
00301 mutable PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00302 PGSTD::string m_PendingError;
00303
00305 transaction_base();
00307 transaction_base(const transaction_base &);
00309 transaction_base &operator=(const transaction_base &);
00310 };
00311
00312 }
00313
00314