transaction_base.hxx
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() PQXX_NOEXCEPT;
00065 void reg_pending_error(const std::string &) PQXX_NOEXCEPT;
00066 bool registered() const PQXX_NOEXCEPT { 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 std::string &query);
00086
00087 parameterized_invocation &operator()() { add_param(); return *this; }
00088 parameterized_invocation &operator()(const binarystring &v)
00089 { add_binary_param(v, true); return *this; }
00090 template<typename T> parameterized_invocation &operator()(const T &v)
00091 { add_param(v, true); return *this; }
00092 parameterized_invocation &operator()(const binarystring &v, bool nonnull)
00093 { add_binary_param(v, nonnull); return *this; }
00094 template<typename T>
00095 parameterized_invocation &operator()(const T &v, bool nonnull)
00096 { add_param(v, nonnull); return *this; }
00097
00098 result exec();
00099
00100 private:
00102 parameterized_invocation &operator=(const parameterized_invocation &);
00103
00104 connection_base &m_home;
00105 const std::string m_query;
00106 };
00107 }
00108
00109
00110 namespace internal
00111 {
00112 namespace gate
00113 {
00114 class transaction_subtransaction;
00115 class transaction_tablereader;
00116 class transaction_tablewriter;
00117 class transaction_transactionfocus;
00118 }
00119 }
00120
00121
00123
00133 class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
00134 public virtual internal::namedclass
00135 {
00136 public:
00138 typedef isolation_traits<read_committed> isolation_tag;
00139
00140 virtual ~transaction_base() =0;
00141
00143
00155 void commit();
00156
00158
00161 void abort();
00162
00167
00168 std::string esc(const char str[]) const { return conn().esc(str); }
00170 std::string esc(const char str[], size_t maxlen) const
00171 { return conn().esc(str, maxlen); }
00173 std::string esc(const std::string &str) const { return conn().esc(str); }
00174
00176
00187 std::string esc_raw(const unsigned char data[], size_t len) const
00188 { return conn().esc_raw(data, len); }
00190 std::string esc_raw(const std::string &) const;
00191
00193
00196 std::string unesc_raw(const std::string &text) const
00197 { return conn().unesc_raw(text); }
00198
00200
00203 std::string unesc_raw(const char *text) const
00204 { return conn().unesc_raw(text); }
00205
00207
00208 template<typename T> std::string quote(const T &t) const
00209 { return conn().quote(t); }
00210
00212 std::string quote_raw(const unsigned char str[], size_t len) const
00213 { return conn().quote_raw(str, len); }
00214
00215 std::string quote_raw(const std::string &str) const;
00216
00218 std::string quote_name(const std::string &identifier) const
00219 { return conn().quote_name(identifier); }
00221
00223
00238 result exec(const std::string &Query,
00239 const std::string &Desc=std::string());
00240
00241 result exec(const std::stringstream &Query,
00242 const std::string &Desc=std::string())
00243 { return exec(Query.str(), Desc); }
00244
00246
00247
00248
00249
00250
00251 internal::parameterized_invocation parameterized(const std::string &query);
00252
00257
00258
00302 prepare::invocation prepared(const std::string &statement=std::string());
00303
00305
00310
00311 void process_notice(const char Msg[]) const
00312 { m_Conn.process_notice(Msg); }
00314 void process_notice(const std::string &Msg) const
00315 { m_Conn.process_notice(Msg); }
00317
00319 connection_base &conn() const { return m_Conn; }
00320
00322
00329 void set_variable(const std::string &Var, const std::string &Val);
00330
00332
00341 std::string get_variable(const std::string &);
00342
00343
00344 protected:
00346
00352 explicit transaction_base(connection_base &c, bool direct=true);
00353
00355
00357 void Begin();
00358
00360 void End() PQXX_NOEXCEPT;
00361
00363 virtual void do_begin() =0;
00365 virtual result do_exec(const char Query[]) =0;
00367 virtual void do_commit() =0;
00369 virtual void do_abort() =0;
00370
00371
00372
00374
00382 result DirectExec(const char C[], int Retries=0);
00383
00385 void reactivation_avoidance_clear() PQXX_NOEXCEPT
00386 {m_reactivation_avoidance.clear();}
00387
00388 protected:
00390
00392 internal::reactivation_avoidance_counter m_reactivation_avoidance;
00393
00394 private:
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 enum Status
00415 {
00416 st_nascent,
00417 st_active,
00418 st_aborted,
00419 st_committed,
00420 st_in_doubt
00421 };
00422
00424 PQXX_PRIVATE void activate();
00425
00426 PQXX_PRIVATE void CheckPendingError();
00427
00428 template<typename T> bool parm_is_null(T *p) const PQXX_NOEXCEPT
00429 { return !p; }
00430 template<typename T> bool parm_is_null(T) const PQXX_NOEXCEPT
00431 { return false; }
00432
00433 friend class pqxx::internal::gate::transaction_transactionfocus;
00434 PQXX_PRIVATE void RegisterFocus(internal::transactionfocus *);
00435 PQXX_PRIVATE void UnregisterFocus(internal::transactionfocus *) PQXX_NOEXCEPT;
00436 PQXX_PRIVATE void RegisterPendingError(const std::string &) PQXX_NOEXCEPT;
00437
00438 friend class pqxx::internal::gate::transaction_tablereader;
00439 PQXX_PRIVATE void BeginCopyRead(const std::string &, const std::string &);
00440 bool ReadCopyLine(std::string &);
00441
00442 friend class pqxx::internal::gate::transaction_tablewriter;
00443 PQXX_PRIVATE void BeginCopyWrite(
00444 const std::string &Table,
00445 const std::string &Columns);
00446 void WriteCopyLine(const std::string &);
00447 void EndCopyWrite();
00448
00449 friend class pqxx::internal::gate::transaction_subtransaction;
00450
00451 connection_base &m_Conn;
00452
00453 internal::unique<internal::transactionfocus> m_Focus;
00454 Status m_Status;
00455 bool m_Registered;
00456 std::map<std::string, std::string> m_Vars;
00457 std::string m_PendingError;
00458
00460 transaction_base();
00462 transaction_base(const transaction_base &);
00464 transaction_base &operator=(const transaction_base &);
00465 };
00466
00467 }
00468
00469
00470 #include "pqxx/compiler-internal-post.hxx"
00471
00472 #endif
00473