00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef PQXX_H_TRANSACTION_BASE
00021 #define PQXX_H_TRANSACTION_BASE
00022
00023 #include "pqxx/compiler-public.hxx"
00024 #include "pqxx/compiler-internal-pre.hxx"
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "pqxx/connection_base"
00036 #include "pqxx/isolation"
00037 #include "pqxx/result"
00038
00039
00040
00041
00042 namespace pqxx
00043 {
00044 class connection_base;
00045 class transaction_base;
00046
00047
00048 namespace internal
00049 {
00050 class sql_cursor;
00051
00052 class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
00053 {
00054 public:
00055 explicit transactionfocus(transaction_base &t) :
00056 namedclass("transactionfocus"),
00057 m_Trans(t),
00058 m_registered(false)
00059 {
00060 }
00061
00062 protected:
00063 void register_me();
00064 void unregister_me() throw ();
00065 void reg_pending_error(const PGSTD::string &) throw ();
00066 bool registered() const throw () { return m_registered; }
00067
00068 transaction_base &m_Trans;
00069
00070 private:
00071 bool m_registered;
00072
00074 transactionfocus();
00076 transactionfocus(const transactionfocus &);
00078 transactionfocus &operator=(const transactionfocus &);
00079 };
00080
00081
00082 class PQXX_LIBEXPORT parameterized_invocation : statement_parameters
00083 {
00084 public:
00085 parameterized_invocation(connection_base &, const PGSTD::string &query);
00086
00087 parameterized_invocation &operator()() { add_param(); return *this; }
00088 template<typename T> parameterized_invocation &operator()(const T &v)
00089 { add_param(v); return *this; }
00090 template<typename T>
00091 parameterized_invocation &operator()(const T &v, bool nonnull)
00092 { add_param(v, nonnull); return *this; }
00093
00094 result exec();
00095
00096 private:
00098 parameterized_invocation &operator=(const parameterized_invocation &);
00099
00100 connection_base &m_home;
00101 const PGSTD::string m_query;
00102 };
00103 }
00104
00105
00106 namespace internal
00107 {
00108 namespace gate
00109 {
00110 class transaction_subtransaction;
00111 class transaction_tablereader;
00112 class transaction_tablewriter;
00113 class transaction_transactionfocus;
00114 }
00115 }
00116
00117
00119
00129 class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
00130 public virtual internal::namedclass
00131 {
00132 public:
00134 typedef isolation_traits<read_committed> isolation_tag;
00135
00136 virtual ~transaction_base() =0;
00137
00139
00151 void commit();
00152
00154
00157 void abort();
00158
00163
00164 PGSTD::string esc(const char str[]) const
00165 { return m_Conn.esc(str); }
00167 PGSTD::string esc(const char str[], size_t maxlen) const
00168 { return m_Conn.esc(str, maxlen); }
00170 PGSTD::string esc(const PGSTD::string &str) const
00171 { return m_Conn.esc(str); }
00172
00174
00185 PGSTD::string esc_raw(const unsigned char str[], size_t len) const
00186 { return m_Conn.esc_raw(str, len); }
00188 PGSTD::string esc_raw(const PGSTD::string &) const;
00189
00191
00192 template<typename T> PGSTD::string quote(const T &t) const
00193 { return m_Conn.quote(t); }
00195
00197
00212 result exec(const PGSTD::string &Query,
00213 const PGSTD::string &Desc=PGSTD::string());
00214
00215 result exec(const PGSTD::stringstream &Query,
00216 const PGSTD::string &Desc=PGSTD::string())
00217 { return exec(Query.str(), Desc); }
00218
00220
00221
00222
00223
00224
00225 internal::parameterized_invocation parameterized(const PGSTD::string &query);
00226
00231
00232
00276 prepare::invocation prepared(const PGSTD::string &statement=PGSTD::string());
00277
00279
00284
00285 void process_notice(const char Msg[]) const
00286 { m_Conn.process_notice(Msg); }
00288 void process_notice(const PGSTD::string &Msg) const
00289 { m_Conn.process_notice(Msg); }
00291
00293 connection_base &conn() const { return m_Conn; }
00294
00296
00304 void set_variable(const PGSTD::string &Var, const PGSTD::string &Val);
00305
00307
00316 PGSTD::string get_variable(const PGSTD::string &);
00317
00318
00319 protected:
00321
00327 explicit transaction_base(connection_base &c, bool direct=true);
00328
00330
00332 void Begin();
00333
00335 void End() throw ();
00336
00338 virtual void do_begin() =0;
00340 virtual result do_exec(const char Query[]) =0;
00342 virtual void do_commit() =0;
00344 virtual void do_abort() =0;
00345
00346
00347
00349
00357 result DirectExec(const char C[], int Retries=0);
00358
00360 void reactivation_avoidance_clear() throw ()
00361 {m_reactivation_avoidance.clear();}
00362
00363 protected:
00365
00367 internal::reactivation_avoidance_counter m_reactivation_avoidance;
00368
00369 private:
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 enum Status
00390 {
00391 st_nascent,
00392 st_active,
00393 st_aborted,
00394 st_committed,
00395 st_in_doubt
00396 };
00397
00399 void PQXX_PRIVATE activate();
00400
00401 void PQXX_PRIVATE CheckPendingError();
00402
00403 template<typename T> bool parm_is_null(T *p) const throw () { return !p; }
00404 template<typename T> bool parm_is_null(T) const throw () { return false; }
00405
00406 friend class pqxx::internal::gate::transaction_transactionfocus;
00407 void PQXX_PRIVATE RegisterFocus(internal::transactionfocus *);
00408 void PQXX_PRIVATE UnregisterFocus(internal::transactionfocus *) throw ();
00409 void PQXX_PRIVATE RegisterPendingError(const PGSTD::string &) throw ();
00410
00411 friend class pqxx::internal::gate::transaction_tablereader;
00412 void PQXX_PRIVATE BeginCopyRead(const PGSTD::string &, const PGSTD::string &);
00413 bool ReadCopyLine(PGSTD::string &);
00414
00415 friend class pqxx::internal::gate::transaction_tablewriter;
00416 void PQXX_PRIVATE BeginCopyWrite(
00417 const PGSTD::string &Table,
00418 const PGSTD::string &Columns);
00419 void WriteCopyLine(const PGSTD::string &);
00420 void EndCopyWrite();
00421
00422 friend class pqxx::internal::gate::transaction_subtransaction;
00423
00424 connection_base &m_Conn;
00425
00426 internal::unique<internal::transactionfocus> m_Focus;
00427 Status m_Status;
00428 bool m_Registered;
00429 PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00430 PGSTD::string m_PendingError;
00431
00433 transaction_base();
00435 transaction_base(const transaction_base &);
00437 transaction_base &operator=(const transaction_base &);
00438 };
00439
00440 }
00441
00442
00443 #include "pqxx/compiler-internal-post.hxx"
00444
00445 #endif
00446