transaction_base.hxx
/*-------------------------------------------------------------------------
*
* FILE
* pqxx/transaction_base.hxx
*
* DESCRIPTION
* common code and definitions for the transaction classes.
* pqxx::transaction_base defines the interface for any abstract class that
* represents a database transaction
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead.
*
* Copyright (c) 2001-2011, Jeroen T. Vermeulen <jtv@xs4all.nl>
*
* See COPYING for copyright license. If you did not receive a file called
* COPYING with this source code, please notify the distributor of this mistake,
* or contact the author.
*
*-------------------------------------------------------------------------
*/
#ifndef PQXX_H_TRANSACTION_BASE
#define PQXX_H_TRANSACTION_BASE
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"
/* End-user programs need not include this file, unless they define their own
* transaction classes. This is not something the typical program should want
* to do.
*
* However, reading this file is worthwhile because it defines the public
* interface for the available transaction classes such as transaction and
* nontransaction.
*/
#include "pqxx/connection_base"
#include "pqxx/isolation"
#include "pqxx/result"
/* Methods tested in eg. self-test program test001 are marked with "//[t1]"
*/
namespace pqxx
{
class connection_base;
class transaction_base;
namespace internal
{
class sql_cursor;
class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
{
public:
explicit transactionfocus(transaction_base &t) :
namedclass("transactionfocus"),
m_Trans(t),
m_registered(false)
{
}
protected:
void register_me();
void unregister_me() throw ();
void reg_pending_error(const PGSTD::string &) throw ();
bool registered() const throw () { return m_registered; }
transaction_base &m_Trans;
private:
bool m_registered;
transactionfocus();
transactionfocus(const transactionfocus &);
transactionfocus &operator=(const transactionfocus &);
};
class PQXX_LIBEXPORT parameterized_invocation : statement_parameters
{
public:
parameterized_invocation(connection_base &, const PGSTD::string &query);
parameterized_invocation &operator()() { add_param(); return *this; }
parameterized_invocation &operator()(const binarystring &v)
{ add_binary_param(v, true); return *this; }
template<typename T> parameterized_invocation &operator()(const T &v)
{ add_param(v, true); return *this; }
parameterized_invocation &operator()(const binarystring &v, bool nonnull)
{ add_binary_param(v, nonnull); return *this; }
template<typename T>
parameterized_invocation &operator()(const T &v, bool nonnull)
{ add_param(v, nonnull); return *this; }
result exec();
private:
parameterized_invocation &operator=(const parameterized_invocation &);
connection_base &m_home;
const PGSTD::string m_query;
};
} // namespace internal
namespace internal
{
namespace gate
{
class transaction_subtransaction;
class transaction_tablereader;
class transaction_tablewriter;
class transaction_transactionfocus;
} // namespace internal::gate
} // namespace internal
class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
public virtual internal::namedclass
{
public:
typedef isolation_traits<read_committed> isolation_tag;
virtual ~transaction_base() =0; //[t1]
void commit(); //[t1]
void abort(); //[t10]
PGSTD::string esc(const char str[]) const { return conn().esc(str); }
PGSTD::string esc(const char str[], size_t maxlen) const
{ return conn().esc(str, maxlen); }
PGSTD::string esc(const PGSTD::string &str) const { return conn().esc(str); }
PGSTD::string esc_raw(const unsigned char str[], size_t len) const //[t62]
{ return conn().esc_raw(str, len); }
PGSTD::string esc_raw(const PGSTD::string &) const; //[t62]
template<typename T> PGSTD::string quote(const T &t) const
{ return conn().quote(t); }
PGSTD::string quote_raw(const unsigned char str[], size_t len) const
{ return conn().quote_raw(str, len); }
PGSTD::string quote_raw(const PGSTD::string &str) const;
PGSTD::string quote_name(const PGSTD::string &identifier) const
{ return conn().quote_name(identifier); }
result exec(const PGSTD::string &Query,
const PGSTD::string &Desc=PGSTD::string()); //[t1]
result exec(const PGSTD::stringstream &Query,
const PGSTD::string &Desc=PGSTD::string())
{ return exec(Query.str(), Desc); }
/* Use this to build up a parameterized statement invocation, then invoke it
* using @c exec()
*
* Example: @c trans.parameterized("SELECT $1 + 1")(1).exec();
*/
internal::parameterized_invocation parameterized(const PGSTD::string &query);
prepare::invocation prepared(const PGSTD::string &statement=PGSTD::string());
void process_notice(const char Msg[]) const //[t14]
{ m_Conn.process_notice(Msg); }
void process_notice(const PGSTD::string &Msg) const //[t14]
{ m_Conn.process_notice(Msg); }
connection_base &conn() const { return m_Conn; } //[t4]
void set_variable(const PGSTD::string &Var, const PGSTD::string &Val);//[t61]
PGSTD::string get_variable(const PGSTD::string &); //[t61]
protected:
explicit transaction_base(connection_base &c, bool direct=true);
void Begin();
void End() throw ();
virtual void do_begin() =0;
virtual result do_exec(const char Query[]) =0;
virtual void do_commit() =0;
virtual void do_abort() =0;
// For use by implementing class:
result DirectExec(const char C[], int Retries=0);
void reactivation_avoidance_clear() throw ()
{m_reactivation_avoidance.clear();}
protected:
internal::reactivation_avoidance_counter m_reactivation_avoidance;
private:
/* A transaction goes through the following stages in its lifecycle:
* <ul>
* <li> nascent: the transaction hasn't actually begun yet. If our connection
* fails at this stage, it may recover and the transaction can attempt to
* establish itself again.
* <li> active: the transaction has begun. Since no commit command has been
* issued, abortion is implicit if the connection fails now.
* <li> aborted: an abort has been issued; the transaction is terminated and
* its changes to the database rolled back. It will accept no further
* commands.
* <li> committed: the transaction has completed successfully, meaning that a
* commit has been issued. No further commands are accepted.
* <li> in_doubt: the connection was lost at the exact wrong time, and there
* is no way of telling whether the transaction was committed or aborted.
* </ul>
*
* Checking and maintaining state machine logic is the responsibility of the
* base class (ie., this one).
*/
enum Status
{
st_nascent,
st_active,
st_aborted,
st_committed,
st_in_doubt
};
void PQXX_PRIVATE activate();
void PQXX_PRIVATE CheckPendingError();
template<typename T> bool parm_is_null(T *p) const throw () { return !p; }
template<typename T> bool parm_is_null(T) const throw () { return false; }
friend class pqxx::internal::gate::transaction_transactionfocus;
void PQXX_PRIVATE RegisterFocus(internal::transactionfocus *);
void PQXX_PRIVATE UnregisterFocus(internal::transactionfocus *) throw ();
void PQXX_PRIVATE RegisterPendingError(const PGSTD::string &) throw ();
friend class pqxx::internal::gate::transaction_tablereader;
void PQXX_PRIVATE BeginCopyRead(const PGSTD::string &, const PGSTD::string &);
bool ReadCopyLine(PGSTD::string &);
friend class pqxx::internal::gate::transaction_tablewriter;
void PQXX_PRIVATE BeginCopyWrite(
const PGSTD::string &Table,
const PGSTD::string &Columns);
void WriteCopyLine(const PGSTD::string &);
void EndCopyWrite();
friend class pqxx::internal::gate::transaction_subtransaction;
connection_base &m_Conn;
internal::unique<internal::transactionfocus> m_Focus;
Status m_Status;
bool m_Registered;
PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
PGSTD::string m_PendingError;
transaction_base();
transaction_base(const transaction_base &);
transaction_base &operator=(const transaction_base &);
};
} // namespace pqxx
#include "pqxx/compiler-internal-post.hxx"
#endif
pqxx::transaction_base::isolation_tag
isolation_traits< read_committed > isolation_tag
If nothing else is known, our isolation level is at least read_committed.
Definition: transaction_base.hxx:138
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:81
pqxx::isolation_traits
Traits class to describe an isolation level; primarly for libpqxx&#39;s own use.
Definition: isolation.hxx:69
pqxx::connection_base
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:151
pqxx::transaction_base::conn
connection_base & conn() const
Connection this transaction is running in.
Definition: transaction_base.hxx:305
pqxx::transaction_base::quote_name
std::string quote_name(const std::string &identifier) const
Escape an SQL identifier for use in a query.
Definition: transaction_base.hxx:204
pqxx::transaction_base::esc_raw
std::string esc_raw(const unsigned char str[], size_t len) const
Escape binary data for use as SQL string literal in this transaction.
Definition: transaction_base.hxx:187
pqxx::internal::parameterized_invocation::operator()
parameterized_invocation & operator()(const T &v)
Definition: transaction_base.hxx:90
pqxx::transaction_base::esc
std::string esc(const char str[], size_t maxlen) const
Escape string for use as SQL string literal in this transaction.
Definition: transaction_base.hxx:170
pqxx::internal::unique
Ensure proper opening/closing of GUEST objects related to a "host" object.
Definition: util.hxx:699
pqxx::transaction_base::reactivation_avoidance_clear
void reactivation_avoidance_clear()
Forget about any reactivation-blocking resources we tried to allocate.
Definition: transaction_base.hxx:372
pqxx::internal::parameterized_invocation
Definition: transaction_base.hxx:82
pqxx::binarystring
Definition: binarystring.hxx:59
pqxx::internal::transactionfocus
Definition: transaction_base.hxx:52
pqxx::transaction_base::quote_raw
std::string quote_raw(const unsigned char str[], size_t len) const
Binary-escape and quote a binarystring for use as an SQL constant.
Definition: transaction_base.hxx:198
pqxx::internal::parameterized_invocation::operator()
parameterized_invocation & operator()()
Definition: transaction_base.hxx:87
pqxx::internal::parameterized_invocation::operator()
parameterized_invocation & operator()(const T &v, bool nonnull)
Definition: transaction_base.hxx:95
pqxx::internal::transactionfocus::m_Trans
transaction_base & m_Trans
Definition: transaction_base.hxx:68
pqxx::internal::transactionfocus::transactionfocus
transactionfocus(transaction_base &t)
Definition: transaction_base.hxx:55
pqxx::transaction_base::quote
std::string quote(const T &t) const
Represent object as SQL string, including quoting & escaping.
Definition: transaction_base.hxx:194
pqxx::internal::transactionfocus::registered
bool registered() const
Definition: transaction_base.hxx:66
pqxx::transaction_base::esc
std::string esc(const std::string &str) const
Escape string for use as SQL string literal in this transaction.
Definition: transaction_base.hxx:173
pqxx::transaction_base::exec
result exec(const std::stringstream &Query, const std::string &Desc=std::string())
Definition: transaction_base.hxx:227
pqxx::internal::reactivation_avoidance_counter
Definition: connection_base.hxx:59
pqxx::transaction_base::m_reactivation_avoidance
internal::reactivation_avoidance_counter m_reactivation_avoidance
Resources allocated in this transaction that make reactivation impossible.
Definition: transaction_base.hxx:379
pqxx::transaction_base::process_notice
void process_notice(const std::string &Msg) const
Have connection process warning message.
Definition: transaction_base.hxx:300
pqxx::internal::parameterized_invocation::operator()
parameterized_invocation & operator()(const binarystring &v)
Definition: transaction_base.hxx:88
pqxx::internal::namedclass
Definition: util.hxx:672
pqxx::prepare::invocation
Helper class for passing parameters to, and executing, prepared statements.
Definition: prepared_statement.hxx:124
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: basic_connection.hxx:35
pqxx::transaction_base
Definition: transaction_base.hxx:133
pqxx::internal::parameterized_invocation::operator()
parameterized_invocation & operator()(const binarystring &v, bool nonnull)
Definition: transaction_base.hxx:92