libpqxx  5.0
transaction_base.hxx
1 /*-------------------------------------------------------------------------
2  *
3  * FILE
4  * pqxx/transaction_base.hxx
5  *
6  * DESCRIPTION
7  * common code and definitions for the transaction classes.
8  * pqxx::transaction_base defines the interface for any abstract class that
9  * represents a database transaction
10  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead.
11  *
12  * Copyright (c) 2001-2015, Jeroen T. Vermeulen <jtv@xs4all.nl>
13  *
14  * See COPYING for copyright license. If you did not receive a file called
15  * COPYING with this source code, please notify the distributor of this mistake,
16  * or contact the author.
17  *
18  *-------------------------------------------------------------------------
19  */
20 #ifndef PQXX_H_TRANSACTION_BASE
21 #define PQXX_H_TRANSACTION_BASE
22 
23 #include "pqxx/compiler-public.hxx"
24 #include "pqxx/compiler-internal-pre.hxx"
25 
26 /* End-user programs need not include this file, unless they define their own
27  * transaction classes. This is not something the typical program should want
28  * to do.
29  *
30  * However, reading this file is worthwhile because it defines the public
31  * interface for the available transaction classes such as transaction and
32  * nontransaction.
33  */
34 
35 #include "pqxx/connection_base"
36 #include "pqxx/isolation"
37 #include "pqxx/result"
38 
39 /* Methods tested in eg. self-test program test001 are marked with "//[t1]"
40  */
41 
42 namespace pqxx
43 {
44 class connection_base;
45 class transaction_base;
46 
47 
48 namespace internal
49 {
50 class sql_cursor;
51 
52 class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
53 {
54 public:
56  namedclass("transactionfocus"),
57  m_Trans(t),
58  m_registered(false)
59  {
60  }
61 
62 protected:
63  void register_me();
64  void unregister_me() PQXX_NOEXCEPT;
65  void reg_pending_error(const std::string &) PQXX_NOEXCEPT;
66  bool registered() const PQXX_NOEXCEPT { return m_registered; }
67 
69 
70 private:
71  bool m_registered;
72 
78  transactionfocus &operator=(const transactionfocus &);
79 };
80 
81 
82 class PQXX_LIBEXPORT parameterized_invocation : statement_parameters
83 {
84 public:
85  parameterized_invocation(connection_base &, const std::string &query);
86 
87  parameterized_invocation &operator()() { add_param(); return *this; }
89  { add_binary_param(v, true); return *this; }
90  template<typename T> parameterized_invocation &operator()(const T &v)
91  { add_param(v, true); return *this; }
93  { add_binary_param(v, nonnull); return *this; }
94  template<typename T>
95  parameterized_invocation &operator()(const T &v, bool nonnull)
96  { add_param(v, nonnull); return *this; }
97 
98  result exec();
99 
100 private:
103 
104  connection_base &m_home;
105  const std::string m_query;
106 };
107 } // namespace internal
108 
109 
110 namespace internal
111 {
112 namespace gate
113 {
114 class transaction_subtransaction;
115 class transaction_tablereader;
116 class transaction_tablewriter;
117 class transaction_transactionfocus;
118 } // namespace internal::gate
119 } // namespace internal
120 
121 
123 
133 class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
134  public virtual internal::namedclass
135 {
136 public:
139 
140  virtual ~transaction_base() =0; //[t1]
141 
143 
155  void commit(); //[t1]
156 
158 
161  void abort(); //[t10]
162 
167  std::string esc(const char str[]) const { return conn().esc(str); }
170  std::string esc(const char str[], size_t maxlen) const
171  { return conn().esc(str, maxlen); }
173  std::string esc(const std::string &str) const { return conn().esc(str); }
174 
176 
187  std::string esc_raw(const unsigned char data[], size_t len) const //[t62]
188  { return conn().esc_raw(data, len); }
190  std::string esc_raw(const std::string &) const; //[t62]
191 
193 
196  std::string unesc_raw(const std::string &text) const
197  { return conn().unesc_raw(text); }
198 
200 
203  std::string unesc_raw(const char *text) const
204  { return conn().unesc_raw(text); }
205 
207 
208  template<typename T> std::string quote(const T &t) const
209  { return conn().quote(t); }
210 
212  std::string quote_raw(const unsigned char str[], size_t len) const
213  { return conn().quote_raw(str, len); }
214 
215  std::string quote_raw(const std::string &str) const;
216 
218  std::string quote_name(const std::string &identifier) const
219  { return conn().quote_name(identifier); }
221 
223 
238  result exec(const std::string &Query,
239  const std::string &Desc=std::string()); //[t1]
240 
241  result exec(const std::stringstream &Query,
242  const std::string &Desc=std::string())
243  { return exec(Query.str(), Desc); }
244 
246  /* Use this to build up a parameterized statement invocation, then invoke it
247  * using @c exec()
248  *
249  * Example: @c trans.parameterized("SELECT $1 + 1")(1).exec();
250  */
251  internal::parameterized_invocation parameterized(const std::string &query);
252 
257 
302  prepare::invocation prepared(const std::string &statement=std::string());
303 
305 
310  void process_notice(const char Msg[]) const //[t14]
312  { m_Conn.process_notice(Msg); }
314  void process_notice(const std::string &Msg) const //[t14]
315  { m_Conn.process_notice(Msg); }
317 
319  connection_base &conn() const { return m_Conn; } //[t4]
320 
322 
329  void set_variable(const std::string &Var, const std::string &Val); //[t61]
330 
332 
341  std::string get_variable(const std::string &); //[t61]
342 
343 
344 protected:
346 
352  explicit transaction_base(connection_base &c, bool direct=true);
353 
355 
357  void Begin();
358 
360  void End() PQXX_NOEXCEPT;
361 
363  virtual void do_begin() =0;
365  virtual result do_exec(const char Query[]) =0;
367  virtual void do_commit() =0;
369  virtual void do_abort() =0;
370 
371  // For use by implementing class:
372 
374 
382  result DirectExec(const char C[], int Retries=0);
383 
385  void reactivation_avoidance_clear() PQXX_NOEXCEPT
386  {m_reactivation_avoidance.clear();}
387 
388 protected:
390 
393 
394 private:
395  /* A transaction goes through the following stages in its lifecycle:
396  * <ul>
397  * <li> nascent: the transaction hasn't actually begun yet. If our connection
398  * fails at this stage, it may recover and the transaction can attempt to
399  * establish itself again.
400  * <li> active: the transaction has begun. Since no commit command has been
401  * issued, abortion is implicit if the connection fails now.
402  * <li> aborted: an abort has been issued; the transaction is terminated and
403  * its changes to the database rolled back. It will accept no further
404  * commands.
405  * <li> committed: the transaction has completed successfully, meaning that a
406  * commit has been issued. No further commands are accepted.
407  * <li> in_doubt: the connection was lost at the exact wrong time, and there
408  * is no way of telling whether the transaction was committed or aborted.
409  * </ul>
410  *
411  * Checking and maintaining state machine logic is the responsibility of the
412  * base class (ie., this one).
413  */
414  enum Status
415  {
416  st_nascent,
417  st_active,
418  st_aborted,
419  st_committed,
420  st_in_doubt
421  };
422 
424  PQXX_PRIVATE void activate();
425 
426  PQXX_PRIVATE void CheckPendingError();
427 
428  template<typename T> bool parm_is_null(T *p) const PQXX_NOEXCEPT
429  { return !p; }
430  template<typename T> bool parm_is_null(T) const PQXX_NOEXCEPT
431  { return false; }
432 
433  friend class pqxx::internal::gate::transaction_transactionfocus;
434  PQXX_PRIVATE void RegisterFocus(internal::transactionfocus *);
435  PQXX_PRIVATE void UnregisterFocus(internal::transactionfocus *) PQXX_NOEXCEPT;
436  PQXX_PRIVATE void RegisterPendingError(const std::string &) PQXX_NOEXCEPT;
437 
438  friend class pqxx::internal::gate::transaction_tablereader;
439  PQXX_PRIVATE void BeginCopyRead(const std::string &, const std::string &);
440  bool ReadCopyLine(std::string &);
441 
442  friend class pqxx::internal::gate::transaction_tablewriter;
443  PQXX_PRIVATE void BeginCopyWrite(
444  const std::string &Table,
445  const std::string &Columns);
446  void WriteCopyLine(const std::string &);
447  void EndCopyWrite();
448 
449  friend class pqxx::internal::gate::transaction_subtransaction;
450 
451  connection_base &m_Conn;
452 
453  internal::unique<internal::transactionfocus> m_Focus;
454  Status m_Status;
455  bool m_Registered;
456  std::map<std::string, std::string> m_Vars;
457  std::string m_PendingError;
458 
464  transaction_base &operator=(const transaction_base &);
465 };
466 
467 } // namespace pqxx
468 
469 
470 #include "pqxx/compiler-internal-post.hxx"
471 
472 #endif
473 
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:149
connection_base & conn() const
Connection this transaction is running in.
Definition: transaction_base.hxx:319
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:212
void clear() PQXX_NOEXCEPT
Definition: result.hxx:133
std::string esc_raw(const unsigned char data[], size_t len) const
Escape binary data for use as SQL string literal in this transaction.
Definition: transaction_base.hxx:187
Definition: transaction_base.hxx:52
Definition: connection_base.hxx:59
std::string quote_name(const std::string &identifier) const
Escape an SQL identifier for use in a query.
Definition: transaction_base.hxx:218
Traits class to describe an isolation level; primarly for libpqxx&#39;s own use.
Definition: isolation.hxx:69
void process_notice(const std::string &Msg) const
Have connection process warning message.
Definition: transaction_base.hxx:314
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
std::string unesc_raw(const char *text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: transaction_base.hxx:203
std::string quote(const T &t) const
Represent object as SQL string, including quoting &amp; escaping.
Definition: transaction_base.hxx:208
parameterized_invocation & operator()(const binarystring &v, bool nonnull)
Definition: transaction_base.hxx:92
transaction_base & m_Trans
Definition: transaction_base.hxx:68
Definition: binarystring.hxx:59
parameterized_invocation & operator()(const T &v, bool nonnull)
Definition: transaction_base.hxx:95
std::string esc(const std::string &str) const
Escape string for use as SQL string literal in this transaction.
Definition: transaction_base.hxx:173
Helper class for passing parameters to, and executing, prepared statements.
Definition: prepared_statement.hxx:124
parameterized_invocation & operator()()
Definition: transaction_base.hxx:87
parameterized_invocation & operator()(const T &v)
Definition: transaction_base.hxx:90
isolation_traits< read_committed > isolation_tag
If nothing else is known, our isolation level is at least read_committed.
Definition: transaction_base.hxx:138
internal::reactivation_avoidance_counter m_reactivation_avoidance
Resources allocated in this transaction that make reactivation impossible.
Definition: transaction_base.hxx:392
Definition: util.hxx:629
result exec(const std::stringstream &Query, const std::string &Desc=std::string())
Definition: transaction_base.hxx:241
transactionfocus(transaction_base &t)
Definition: transaction_base.hxx:55
parameterized_invocation & operator()(const binarystring &v)
Definition: transaction_base.hxx:88
std::string unesc_raw(const std::string &text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: transaction_base.hxx:196
Definition: transaction_base.hxx:82
Result set containing data returned by a query or command.
Definition: result.hxx:78
Definition: transaction_base.hxx:133