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 
namespace pqxx
00039 {
00040 
class connection_base;
00041 
class transaction_base;
00042 
00043 
00044 namespace internal
00045 {
00046 class PQXX_LIBEXPORT transactionfocus : 
public namedclass
00047 {
00048 
public:
00049   transactionfocus(
transaction_base &t, 
00050       
const PGSTD::string &Name,
00051       
const PGSTD::string &Classname) :
00052     
namedclass(Name, Classname),
00053     m_Trans(t),
00054     m_registered(false)
00055   {
00056   }
00057 
00058 
protected:
00059   
void register_me();
00060   
void unregister_me() throw ();
00061   
void reg_pending_error(const PGSTD::string &) throw ();
00062   bool registered() const throw () { 
return m_registered; }
00063 
00064   transaction_base &m_Trans;
00065 
00066 
private:
00067   
bool m_registered;
00068 
00070   transactionfocus();
00072   transactionfocus(
const transactionfocus &);
00074   transactionfocus &operator=(
const transactionfocus &);
00075 };
00076 } 
00077 
00078 
00079 
00081 
00089 class PQXX_LIBEXPORT transaction_base : 
public internal::namedclass
00090 {
00091   
00092 
public:
00094   typedef isolation_traits<read_committed> isolation_tag;
00095 
00096   
virtual ~transaction_base() =0;                                       
00097 
00099 
00111   
void commit();                                                        
00112 
00114 
00117   
void abort();                                                         
00118 
00120 
00124   
result exec(
const char Query[], 
00125               
const PGSTD::string &Desc=PGSTD::string());               
00126 
00128 
00135   result exec(
const PGSTD::string &Query,
00136               
const PGSTD::string &Desc=PGSTD::string())                
00137         { 
return exec(Query.c_str(), Desc); }
00138 
00139   result exec(
const PGSTD::stringstream &Query,
00140               
const PGSTD::string &Desc=PGSTD::string())                
00141         { 
return exec(Query.str(), Desc); }
00142 
00144   void process_notice(
const char Msg[]) 
const                           
00145         { m_Conn.process_notice(Msg); }
00147   void process_notice(
const PGSTD::string &Msg) 
const                   
00148         { m_Conn.process_notice(Msg); }
00149 
00151   connection_base &conn()
 const { 
return m_Conn; }                      
00152 
00154 
00162   
void set_variable(
const PGSTD::string &Var, 
const PGSTD::string &Val);
00163 
00165 
00171   PGSTD::string get_variable(
const PGSTD::string &) const;              
00172 
00173 #ifdef PQXX_DEPRECATED_HEADERS
00175   
void Commit() { commit(); }
00177   
void Abort() { abort(); }
00179   result Exec(
const char Q[], 
const PGSTD::string &D=PGSTD::string())
00180         { 
return exec(Q,D); }
00182   result Exec(
const PGSTD::string &Q, 
const PGSTD::string &D=PGSTD::string())
00183         { 
return exec(Q,D); }
00185   
void ProcessNotice(
const char M[])
 const { 
return process_notice(M); }
00187   
void ProcessNotice(
const PGSTD::string &M)
 const { 
return process_notice(M); }
00189   PGSTD::string Name()
 const { 
return name(); }
00191   connection_base &Conn()
 const { 
return conn(); }
00193   
void SetVariable(
const PGSTD::string &Var, 
const PGSTD::string &Val)
00194         { set_variable(Var,Val); }
00195 
#endif
00196 
00197 
protected:
00199 
00202   
explicit transaction_base(connection_base &, 
00203                           
const PGSTD::string &TName,
00204                           
const PGSTD::string &CName);
00205 
00207 
00209   
void Begin();
00210 
00212   
void End() throw ();
00213 
00215   virtual 
void do_begin() =0;
00217   virtual result do_exec(const 
char Query[]) =0;
00219   virtual 
void do_commit() =0;
00221   virtual 
void do_abort() =0;
00222 
00223   
00224 
00226 
00234   result DirectExec(const 
char C[], 
int Retries=0);
00235  
00236 private:
00237   
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254   enum Status 
00255   { 
00256     st_nascent, 
00257     st_active, 
00258     st_aborted, 
00259     st_committed,
00260     st_in_doubt
00261   };
00262 
00263 
00264   
void CheckPendingError();
00265 
00266   
friend class Cursor;
00267   
friend class cursor_base;
00268   
int GetUniqueCursorNum() { 
return m_UniqueCursorNum++; }
00269   
void MakeEmpty(result &R)
 const { m_Conn.MakeEmpty(R); }
00270 
00271   
friend class internal::transactionfocus;
00272   
void RegisterFocus(internal::transactionfocus *);
00273   
void UnregisterFocus(internal::transactionfocus *) throw ();
00274   
void RegisterPendingError(const PGSTD::string &) throw ();
00275   friend class tablereader;
00276   
void BeginCopyRead(const PGSTD::string &Table, const PGSTD::string &Columns);
00277   
bool ReadCopyLine(PGSTD::string &L) { 
return m_Conn.ReadCopyLine(L); }
00278   
friend class tablewriter;
00279   
void BeginCopyWrite(
const PGSTD::string &Table, 
00280         
const PGSTD::string &Columns = PGSTD::string());
00281   
void WriteCopyLine(
const PGSTD::string &L) { m_Conn.WriteCopyLine(L); }
00282   
void EndCopyWrite() { m_Conn.EndCopyWrite(); }
00283 
00284   
friend class pipeline;
00285   
void start_exec(
const PGSTD::string &Q) { m_Conn.start_exec(Q); }
00286   internal::pq::PGresult *get_result() { 
return m_Conn.get_result(); }
00287   
void consume_input() throw () { m_Conn.consume_input(); }
00288   
bool is_busy() const throw () { 
return m_Conn.is_busy(); }
00289 
00290   connection_base &m_Conn;
00291 
00292   
int m_UniqueCursorNum;
00293   internal::unique<internal::transactionfocus> m_Focus;
00294   Status m_Status;
00295   
bool m_Registered;
00296   
mutable PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00297   PGSTD::string m_PendingError;
00298 
00300   transaction_base();
00302   transaction_base(
const transaction_base &);
00304   transaction_base &operator=(
const transaction_base &);
00305 };
00306 
00307 } 
00308 
00309