Common ODB Runtime Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
transaction.hxx
Go to the documentation of this file.
1 // file : odb/transaction.hxx
2 // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
3 // license : GNU GPL v2; see accompanying LICENSE file
4 
5 #ifndef ODB_TRANSACTION_HXX
6 #define ODB_TRANSACTION_HXX
7 
8 #include <odb/pre.hxx>
9 
10 #include <vector>
11 #include <cstddef> // std::size_t
12 
13 #include <odb/forward.hxx>
14 
15 #include <odb/details/export.hxx>
16 #include <odb/details/unique-ptr.hxx>
17 
18 namespace odb
19 {
20  class transaction_impl;
21 
22  class LIBODB_EXPORT transaction
23  {
24  public:
27 
28  // If the second argument is false, then this transaction is not made
29  // the current transaction of the thread.
30  //
31  explicit
32  transaction (transaction_impl*, bool make_current = true);
33 
34  // Create a finalized transaction instance which can later be initialized
35  // with reset().
36  //
37  transaction ();
38 
39  // Unless the transaction has already been finalized (explicitly
40  // committed or rolled back), the destructor will roll it back.
41  //
42  ~transaction ();
43 
44  // Unless the current transaction has already been finalized (explicitly
45  // committed or rolled back), reset will roll it back. If the second
46  // argument is false, then this transaction is not made the current
47  // transaction of the thread.
48  //
49  void
50  reset (transaction_impl*, bool make_current = true);
51 
52  void
53  commit ();
54 
55  void
56  rollback ();
57 
58  // Return the database this transaction is on.
59  //
61  database ();
62 
63  // Return the connection this transaction is on.
64  //
66  connection ();
67 
68  bool
69  finalized () const {return finalized_;}
70 
71  public:
72  // Return true if there is a transaction in effect.
73  //
74  static bool
75  has_current ();
76 
77  // Return current transaction or throw if there is no transaction
78  // in effect.
79  //
80  static transaction&
81  current ();
82 
83  // Set the current thread's transaction.
84  //
85  static void
86  current (transaction&);
87 
88  // Revert to the no transaction in effect state for the current thread.
89  //
90  static void
91  reset_current ();
92 
93  // SQL statement tracing.
94  //
95  public:
97 
98  void
100 
101  void
102  tracer (tracer_type*);
103 
104  tracer_type*
105  tracer () const;
106 
107  // Post-commit/rollback callbacks.
108  //
109  public:
110  static const unsigned short event_commit = 0x01;
111  static const unsigned short event_rollback = 0x02;
112  static const unsigned short event_all = event_commit | event_rollback;
113 
114  typedef void (*callback_type) (
115  unsigned short event, void* key, unsigned long long data);
116 
117  // Register a post-commit/rollback callback. The data argument
118  // can be used to store any user data that does not exceed 8
119  // bytes and doesn't require alignment greater than unsigned
120  // long long, such as an old value that needs to be restored
121  // in case of a rollback.
122  //
123  // The state argument can be used to indicate to the caller
124  // that the callback has been unregistered because the
125  // transaction has terminated. In this case the transaction
126  // resets the passed pointer to 0.
127  //
128  // Note that the order in which the callbacks are called is
129  // unspecified.
130  //
131  void
132  callback_register (callback_type,
133  void* key,
134  unsigned short event = event_all,
135  unsigned long long data = 0,
136  transaction** state = 0);
137 
138  // Unregister a post-commit/rollback callback. Note that this is a
139  // potentially slow operation. You also don't need to unregister
140  // a callback that has been called or auto-reset using the state
141  // argument passed to register(). This function does nothing if
142  // the key is not found.
143  //
144  void
145  callback_unregister (void* key);
146 
147  // Update the event, data, and state values for a callback. Note
148  // that just like unregister(), this is a potentially slow operation.
149  //
150  void
151  callback_update (void* key,
152  unsigned short event,
153  unsigned long long data = 0,
154  transaction** state = 0);
155 
156  public:
158  implementation ();
159 
160  // Copying or assignment of transactions is not supported.
161  //
162  private:
163  transaction (const transaction&);
164  transaction& operator= (const transaction&);
165 
166  protected:
167  friend struct rollback_guard;
168 
169  std::size_t
170  callback_find (void* key);
171 
172  void
173  callback_call (unsigned short event);
174 
175  protected:
177  details::unique_ptr<transaction_impl> impl_;
178 
179  // Callbacks.
180  //
182  {
183  unsigned short event;
184  callback_type func;
185  void* key;
186  unsigned long long data;
188  };
189 
190  // Slots for the first 20 callback are pre-allocated on the stack.
191  // For the rest they are allocated dynamically as needed.
192  //
193  // Note, if you change stack_callback_count, make sure you also
194  // update the common/transaction/callback test accordingly.
195  //
196  static const std::size_t stack_callback_count = 20;
197  static const std::size_t max_callback_count = ~(std::size_t (0));
198 
199  callback_data stack_callbacks_[stack_callback_count];
200  std::vector<callback_data> dyn_callbacks_;
201 
202  // When a callback is unregistered, the free slot from the stack is
203  // added to the linked list of free slots which is organized by
204  // re-using the key data member to store the slot's index (we cannot
205  // store a pointer because std::vector may move slots on expansion).
206  // The value equal to max_callback_count indicates no free slots are
207  // available.
208  //
209  std::size_t free_callback_;
210 
211  // Total number of used slots, both registered and in the free list.
212  //
213  std::size_t callback_count_;
214  };
215 
216  class LIBODB_EXPORT transaction_impl
217  {
218  public:
221 
222  virtual
223  ~transaction_impl ();
224 
225  virtual void
226  start () = 0;
227 
228  virtual void
229  commit () = 0;
230 
231  virtual void
232  rollback () = 0;
233 
236  {
237  return database_;
238  }
239 
240  connection_type&
242  {
243  return *connection_;
244  }
245 
246  protected:
248  : database_ (db), connection_ (0)
249  {
250  }
251 
253  : database_ (db), connection_ (&c)
254  {
255  }
256 
257  protected:
260  };
261 }
262 
263 #include <odb/transaction.ixx>
264 
265 #include <odb/post.hxx>
266 
267 #endif // ODB_TRANSACTION_HXX
std::size_t callback_count_
Definition: transaction.hxx:213
Definition: transaction.hxx:22
std::vector< callback_data > dyn_callbacks_
Definition: transaction.hxx:200
unsigned short event
Definition: transaction.hxx:183
database_type & database_
Definition: transaction.hxx:258
odb::tracer tracer_type
Definition: transaction.hxx:96
connection_type & connection()
Definition: transaction.hxx:241
odb::connection connection_type
Definition: transaction.hxx:26
void * key
Definition: transaction.hxx:185
Definition: transaction.hxx:216
database_type & database()
Definition: transaction.hxx:235
unsigned long long data
Definition: transaction.hxx:186
odb::database database_type
Definition: transaction.hxx:25
Definition: database.hxx:38
Definition: connection.hxx:33
Definition: transaction.hxx:181
Definition: tracer.hxx:15
odb::connection connection_type
Definition: transaction.hxx:220
callback_type func
Definition: transaction.hxx:184
transaction_impl(database_type &db)
Definition: transaction.hxx:247
std::size_t free_callback_
Definition: transaction.hxx:209
bool finalized() const
Definition: transaction.hxx:69
transaction ** state
Definition: transaction.hxx:187
odb::database database_type
Definition: transaction.hxx:219
bool finalized_
Definition: transaction.hxx:176
connection_type * connection_
Definition: transaction.hxx:259
transaction_impl(database_type &db, connection_type &c)
Definition: transaction.hxx:252
details::unique_ptr< transaction_impl > impl_
Definition: transaction.hxx:177