// file : common/session/custom/session.hxx // copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC // 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& 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