From 26e36b3a9d7b49d46ecfa69b447482251acba8ac Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 24 Jan 2024 16:53:38 +0300 Subject: Turn libodb repository into package for muti-package repository --- libodb/odb/transaction.hxx | 278 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 libodb/odb/transaction.hxx (limited to 'libodb/odb/transaction.hxx') diff --git a/libodb/odb/transaction.hxx b/libodb/odb/transaction.hxx new file mode 100644 index 0000000..1958df3 --- /dev/null +++ b/libodb/odb/transaction.hxx @@ -0,0 +1,278 @@ +// file : odb/transaction.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_TRANSACTION_HXX +#define ODB_TRANSACTION_HXX + +#include + +#include +#include // std::size_t + +#include + +#include +#include + +namespace odb +{ + class transaction_impl; + + class LIBODB_EXPORT transaction + { + public: + typedef odb::database database_type; + typedef odb::connection connection_type; + + // If the second argument is false, then this transaction is not made + // the current transaction of the thread. + // + explicit + transaction (transaction_impl*, bool make_current = true); + + // Create a finalized transaction instance which can later be initialized + // with reset(). + // + transaction (); + + // Unless the transaction has already been finalized (explicitly + // committed or rolled back), the destructor will roll it back. + // + ~transaction (); + + // Unless the current transaction has already been finalized (explicitly + // committed or rolled back), reset will roll it back. If the second + // argument is false, then this transaction is not made the current + // transaction of the thread. + // + void + reset (transaction_impl*, bool make_current = true); + + void + commit (); + + void + rollback (); + + // Return the database this transaction is on. + // + database_type& + database (); + + // Return the connection this transaction is on. + // + // The second version verifies the connection is to the specified + // database. For database implementations that support attaching multiple + // databases it may also select the connection corresponding to the + // specified database. + // + connection_type& + connection (); + + connection_type& + connection (database_type&); + + bool + finalized () const {return finalized_;} + + public: + // Return true if there is a transaction in effect. + // + static bool + has_current (); + + // Return current transaction or throw if there is no transaction + // in effect. + // + static transaction& + current (); + + // Set the current thread's transaction. + // + static void + current (transaction&); + + // Revert to the no transaction in effect state for the current thread. + // + static void + reset_current (); + + // SQL statement tracing. + // + public: + typedef odb::tracer tracer_type; + + void + tracer (tracer_type&); + + void + tracer (tracer_type*); + + tracer_type* + tracer () const; + + // Post-commit/rollback callbacks. + // + public: + static const unsigned short event_commit = 0x01; + static const unsigned short event_rollback = 0x02; + static const unsigned short event_all = event_commit | event_rollback; + + typedef void (*callback_type) ( + unsigned short event, void* key, unsigned long long data); + + // Register a post-commit/rollback callback. The data argument + // can be used to store any user data that does not exceed 8 + // bytes and doesn't require alignment greater than unsigned + // long long, such as an old value that needs to be restored + // in case of a rollback. + // + // The state argument can be used to indicate to the caller + // that the callback has been unregistered because the + // transaction has terminated. In this case the transaction + // resets the passed pointer to 0. + // + // Note that the order in which the callbacks are called is + // unspecified. + // + void + callback_register (callback_type, + void* key, + unsigned short event = event_all, + unsigned long long data = 0, + transaction** state = 0); + + // Unregister a post-commit/rollback callback. Note that this is a + // potentially slow operation. You also don't need to unregister + // a callback that has been called or auto-reset using the state + // argument passed to register(). This function does nothing if + // the key is not found. + // + void + callback_unregister (void* key); + + // Update the event, data, and state values for a callback. Note + // that just like unregister(), this is a potentially slow operation. + // + void + callback_update (void* key, + unsigned short event, + unsigned long long data = 0, + transaction** state = 0); + + public: + transaction_impl& + implementation (); + + // Copying or assignment of transactions is not supported. + // + private: + transaction (const transaction&); + transaction& operator= (const transaction&); + + protected: + friend struct rollback_guard; + + std::size_t + callback_find (void* key); + + void + callback_call (unsigned short event); + + protected: + bool finalized_; + details::unique_ptr impl_; + + // Callbacks. + // + struct callback_data + { + unsigned short event; + callback_type func; + void* key; + unsigned long long data; + transaction** state; + }; + + // Slots for the first 20 callback are pre-allocated on the stack. + // For the rest they are allocated dynamically as needed. + // + // Note, if you change stack_callback_count, make sure you also + // update the common/transaction/callback test accordingly. + // + static const std::size_t stack_callback_count = 20; + static const std::size_t max_callback_count = ~(std::size_t (0)); + + callback_data stack_callbacks_[stack_callback_count]; + std::vector dyn_callbacks_; + + // When a callback is unregistered, the free slot from the stack is + // added to the linked list of free slots which is organized by + // re-using the key data member to store the slot's index (we cannot + // store a pointer because std::vector may move slots on expansion). + // The value equal to max_callback_count indicates no free slots are + // available. + // + std::size_t free_callback_; + + // Total number of used slots, both registered and in the free list. + // + std::size_t callback_count_; + }; + + class LIBODB_EXPORT transaction_impl + { + public: + typedef odb::tracer tracer_type; + typedef odb::database database_type; + typedef odb::connection connection_type; + + virtual + ~transaction_impl (); + + virtual void + start () = 0; + + virtual void + commit () = 0; + + virtual void + rollback () = 0; + + database_type& + database () + { + return database_; + } + + virtual connection_type& + connection (database_type*); + + virtual void + tracer (tracer_type*); + + virtual tracer_type* + tracer () const; + + protected: + transaction_impl (database_type& db) + : database_ (db), connection_ (0) + { + } + + transaction_impl (database_type& db, connection_type& c) + : database_ (db), connection_ (&c) + { + } + + protected: + database_type& database_; + connection_type* connection_; + }; +} + +#include + +#include + +#endif // ODB_TRANSACTION_HXX -- cgit v1.1