Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

transaction_base.hxx

Go to the documentation of this file.
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-2003, 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 
00021 /* End-user programs need not include this file, unless they define their own
00022  * transaction classes.  This is not something the typical program should want
00023  * to do.
00024  *
00025  * However, reading this file is worthwhile because it defines the public
00026  * interface for the available transaction classes such as transaction and 
00027  * nontransaction.
00028  */
00029 
00030 #include "pqxx/connection_base"
00031 #include "pqxx/isolation"
00032 #include "pqxx/result"
00033 
00034 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
00035  */
00036 
00037 
00038 namespace pqxx
00039 {
00040 class connection_base;  // See pqxx/connection_base.h
00041 class result;           // See pqxx/result.h
00042 class tablestream;      // See pqxx/tablestream.h
00043 
00044 
00046 template<> inline PGSTD::string Classname(const tablestream *) 
00047 { 
00048   return "tablestream"; 
00049 }
00050 
00051 
00053 
00061 class PQXX_LIBEXPORT transaction_base
00062 {
00063   // TODO: Retry non-serializable transaction w/update only on broken_connection
00064 public:
00066   typedef isolation_traits<read_committed> isolation_tag;
00067 
00068   virtual ~transaction_base() =0;                                       //[t1]
00069 
00070 #ifdef PQXX_DEPRECATED_HEADERS
00071 
00072   void Commit() { commit(); }
00074   void Abort() { abort(); }
00075 #endif
00076 
00078 
00090   void commit();                                                        //[t1]
00091 
00093 
00096   void abort();                                                         //[t10]
00097 
00098 #ifdef PQXX_DEPRECATED_HEADERS
00099 
00100   result Exec(const char Q[], const PGSTD::string &D=PGSTD::string())
00101         { return exec(Q,D); }
00103   result Exec(const PGSTD::string &Q, const PGSTD::string &D=PGSTD::string())
00104         { return exec(Q,D); }
00105 #endif
00106 
00108 
00112   result exec(const char Query[], 
00113               const PGSTD::string &Desc=PGSTD::string());               //[t1]
00114 
00116 
00123   result exec(const PGSTD::string &Query,
00124               const PGSTD::string &Desc=PGSTD::string())                //[t2]
00125         { return exec(Query.c_str(), Desc); }
00126 
00127 #ifdef PQXX_DEPRECATED_HEADERS
00128 
00129   void ProcessNotice(const char M[]) const { return process_notice(M); }
00131   void ProcessNotice(const PGSTD::string &M) const { return process_notice(M); }
00132 #endif
00133 
00135   void process_notice(const char Msg[]) const                           //[t14]
00136         { m_Conn.process_notice(Msg); }
00138   void process_notice(const PGSTD::string &Msg) const                   //[t14]
00139         { m_Conn.process_notice(Msg); }
00140 
00141 #ifdef PQXX_DEPRECATED_HEADERS
00142 
00143   PGSTD::string Name() const { return name(); }
00144 
00146   connection_base &Conn() const { return conn(); }
00147 #endif
00148 
00149   PGSTD::string name() const { return m_Name; }                         //[t1]
00150 
00152   connection_base &conn() const { return m_Conn; }                      //[t4]
00153 
00154 #ifdef PQXX_DEPRECATED_HEADERS
00155 
00156   void SetVariable(const PGSTD::string &Var, const PGSTD::string &Val)
00157         { set_variable(Var,Val); }
00158 #endif
00159 
00161 
00169   void set_variable(const PGSTD::string &Var, const PGSTD::string &Val);//[t61]
00170 
00171 
00172 protected:
00175   explicit transaction_base(connection_base &, 
00176                           const PGSTD::string &TName=PGSTD::string());
00177 
00180   void Begin();
00181 
00183   void End() throw ();
00184 
00186   virtual void do_begin() =0;
00188   virtual result do_exec(const char Query[]) =0;
00190   virtual void do_commit() =0;
00192   virtual void do_abort() =0;
00193 
00194   // For use by implementing class:
00195 
00197   result DirectExec(const char C[], int Retries, const char OnReconnect[]);
00198  
00199 private:
00200   /* A transaction goes through the following stages in its lifecycle:
00201    *  - nascent: the transaction hasn't actually begun yet.  If our connection 
00202    *    fails at this stage, it may recover and the transaction can attempt to
00203    *    establish itself again.
00204    *  - active: the transaction has begun.  Since no commit command has been 
00205    *    issued, abortion is implicit if the connection fails now.
00206    *  - aborted: an abort has been issued; the transaction is terminated and 
00207    *    its changes to the database rolled back.  It will accept no further 
00208    *    commands.
00209    *  - committed: the transaction has completed successfully, meaning that a 
00210    *    commit has been issued.  No further commands are accepted.
00211    *  - in_doubt: the connection was lost at the exact wrong time, and there is
00212    *    no way of telling whether the transaction was committed or aborted.
00213    *
00214    * Checking and maintaining state machine logic is the responsibility of the 
00215    * base class (ie., this one).
00216    */
00217   enum Status 
00218   { 
00219     st_nascent, 
00220     st_active, 
00221     st_aborted, 
00222     st_committed,
00223     st_in_doubt
00224   };
00225 
00226 
00227   friend class Cursor;
00228   int GetUniqueCursorNum() { return m_UniqueCursorNum++; }
00229   void MakeEmpty(result &R) const { m_Conn.MakeEmpty(R); }
00230 
00231   friend class tablestream;
00232   void RegisterStream(tablestream *);
00233   void UnregisterStream(tablestream *) throw ();
00234   void EndCopy() throw () { m_Conn.EndCopy(); }
00235   friend class tablereader;
00236   void BeginCopyRead(const PGSTD::string &Table) 
00237         { m_Conn.BeginCopyRead(Table); }
00238   bool ReadCopyLine(PGSTD::string &L) { return m_Conn.ReadCopyLine(L); }
00239   friend class tablewriter;
00240   void BeginCopyWrite(const PGSTD::string &Table) 
00241         { m_Conn.BeginCopyWrite(Table); }
00242   void WriteCopyLine(const PGSTD::string &L) { m_Conn.WriteCopyLine(L); }
00243 
00244   connection_base &m_Conn;
00245 
00246   PGSTD::string m_Name;
00247   int m_UniqueCursorNum;
00248   unique<tablestream> m_Stream;
00249   Status m_Status;
00250   bool m_Registered;
00251   mutable PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00252 
00253   // Not allowed:
00254   transaction_base();
00255   transaction_base(const transaction_base &);
00256   transaction_base &operator=(const transaction_base &);
00257 };
00258 
00259 
00260 }
00261 
00262 

Generated on Fri Oct 24 20:21:37 2003 for libpqxx by doxygen 1.3.4