transaction_base.hxx

00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/transaction_base.hxx
00005  *
00006  *   DESCRIPTION
00007  *      common code and definitions for the transaction classes.
00008  *   pqxx::transaction_base defines the interface for any abstract class that
00009  *   represents a database transaction
00010  *   DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead.
00011  *
00012  * Copyright (c) 2001-2015, Jeroen T. Vermeulen <jtv@xs4all.nl>
00013  *
00014  * See COPYING for copyright license.  If you did not receive a file called
00015  * COPYING with this source code, please notify the distributor of this mistake,
00016  * or contact the author.
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 /* End-user programs need not include this file, unless they define their own
00027  * transaction classes.  This is not something the typical program should want
00028  * to do.
00029  *
00030  * However, reading this file is worthwhile because it defines the public
00031  * interface for the available transaction classes such as transaction and
00032  * nontransaction.
00033  */
00034 
00035 #include "pqxx/connection_base"
00036 #include "pqxx/isolation"
00037 #include "pqxx/result"
00038 
00039 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
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 } // namespace internal
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 } // namespace internal::gate
00119 } // namespace internal
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;                                       //[t1]
00141 
00143 
00155   void commit();                                                        //[t1]
00156 
00158 
00161   void abort();                                                         //[t10]
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     //[t62]
00188                                            { return conn().esc_raw(data, len); }
00190   std::string esc_raw(const std::string &) const;                       //[t62]
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());                   //[t1]
00240 
00241   result exec(const std::stringstream &Query,
00242               const std::string &Desc=std::string())
00243         { return exec(Query.str(), Desc); }
00244 
00246   /* Use this to build up a parameterized statement invocation, then invoke it
00247    * using @c exec()
00248    *
00249    * Example: @c trans.parameterized("SELECT $1 + 1")(1).exec();
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                           //[t14]
00312         { m_Conn.process_notice(Msg); }
00314   void process_notice(const std::string &Msg) const                     //[t14]
00315         { m_Conn.process_notice(Msg); }
00317 
00319   connection_base &conn() const { return m_Conn; }                      //[t4]
00320 
00322 
00329   void set_variable(const std::string &Var, const std::string &Val);    //[t61]
00330 
00332 
00341   std::string get_variable(const std::string &);                        //[t61]
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   // For use by implementing class:
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   /* A transaction goes through the following stages in its lifecycle:
00396    * <ul>
00397    * <li> nascent: the transaction hasn't actually begun yet.  If our connection
00398    *    fails at this stage, it may recover and the transaction can attempt to
00399    *    establish itself again.
00400    * <li> active: the transaction has begun.  Since no commit command has been
00401    *    issued, abortion is implicit if the connection fails now.
00402    * <li> aborted: an abort has been issued; the transaction is terminated and
00403    *    its changes to the database rolled back.  It will accept no further
00404    *    commands.
00405    * <li> committed: the transaction has completed successfully, meaning that a
00406    *    commit has been issued.  No further commands are accepted.
00407    * <li> in_doubt: the connection was lost at the exact wrong time, and there
00408    *    is no way of telling whether the transaction was committed or aborted.
00409    * </ul>
00410    *
00411    * Checking and maintaining state machine logic is the responsibility of the
00412    * base class (ie., this one).
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 } // namespace pqxx
00468 
00469 
00470 #include "pqxx/compiler-internal-post.hxx"
00471 
00472 #endif
00473 

Generated on 17 Mar 2017 for libpqxx by  doxygen 1.6.1