From 0d49ea1fe08cf1eab41a00149393a291c65a59d7 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 25 Jan 2024 20:32:06 +0300 Subject: Turn odb-tests repository into package for muti-package repository --- odb-tests/common/session/custom/session.hxx | 191 ++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 odb-tests/common/session/custom/session.hxx (limited to 'odb-tests/common/session/custom/session.hxx') diff --git a/odb-tests/common/session/custom/session.hxx b/odb-tests/common/session/custom/session.hxx new file mode 100644 index 0000000..2d2f597 --- /dev/null +++ b/odb-tests/common/session/custom/session.hxx @@ -0,0 +1,191 @@ +// file : common/session/custom/session.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef SESSION_HXX +#define SESSION_HXX + +#include +#include +#include + +#include +#include + +#include // odb::object_traits +#include // odb::details::type_info_comparator + +// This custom session implementation assumes we are working with +// one database at a time. +// +class session +{ +public: + session (); + ~session (); + +private: + session (const session&); + session& operator= (const session&); + + // Session for the current thread. This can be implemented in pretty + // much any way that makes sense to the application. It can be a global + // session as we have here. In multi-threaded applications we could use + // TLS instead. + // +public: + static session* current; + + // Change tracking interface. + // +public: + // Call flush() within a transaction to apply the changes to the + // database. + // + void + flush (odb::database&); + +private: + struct object_map_base + { + virtual + ~object_map_base () {} + + // Return true if we flushed anything. + // + virtual bool + flush (odb::database&) = 0; + + virtual void + mark (unsigned short event) = 0; + }; + + enum object_state + { + tracking, // Tracking any modifications by storing the original copy. + changed, // Known to be changed. + flushed // Flushed but not yet committed/rolled back. + }; + + template + struct object_data + { + typedef typename odb::object_traits::pointer_type pointer_type; + + explicit + object_data (pointer_type o): obj (o), state (tracking) {} + + pointer_type obj; + pointer_type orig; + object_state state; + }; + + template + struct object_map: object_map_base, + std::map::id_type, + object_data > + { + virtual bool + flush (odb::database&); + + virtual void + mark (unsigned short event); + }; + + // Object cache interface. + // +public: + static bool + _has_cache () {return current != 0;} + + template + struct cache_position + { + typedef object_map map; + typedef typename map::iterator iterator; + + cache_position (): map_ (0) {} + cache_position (map& m, const iterator& p): map_ (&m), pos_ (p) {} + + cache_position (const cache_position& p) + : map_ (p.map_) + { + // It might not be ok to use an uninitialized iterator. + // + if (p.map_ != 0) + pos_ = p.pos_; + } + + cache_position& + operator= (const cache_position& p) + { + // It might not be ok to use an uninitialized iterator on the rhs. + // + if (p.map_ != 0) + pos_ = p.pos_; + map_ = p.map_; + return *this; + } + + map* map_; + iterator pos_; + }; + + // Cache management. + // + template + static cache_position + _cache_insert (odb::database&, + const typename odb::object_traits::id_type&, + const typename odb::object_traits::pointer_type&); + + template + static typename odb::object_traits::pointer_type + _cache_find (odb::database&, const typename odb::object_traits::id_type&); + + template + static void + _cache_erase (const cache_position& p) + { + if (p.map_ != 0) + p.map_->erase (p.pos_); + } + + // Notifications. + // + template + static void + _cache_persist (const cache_position& p) + { + _cache_load (p); + } + + template + static void + _cache_load (const cache_position&); + + template + static void + _cache_update (odb::database&, const T&); + + template + static void + _cache_erase (odb::database&, + const typename odb::object_traits::id_type&); + +private: + // Post-commit/rollback callback. + // + static void + mark (unsigned short event, void* key, unsigned long long); + +private: + typedef std::map, + odb::details::type_info_comparator> type_map; + type_map map_; + odb::transaction* tran_; +}; + +#include "session.txx" + +#endif // SESSION_HXX -- cgit v1.1