From be5909a7fc240c007bb0128353d493af947a8749 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 22 Mar 2011 16:22:06 +0200 Subject: Add object and container statement caches --- odb/sqlite/object-statements.hxx | 333 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 odb/sqlite/object-statements.hxx (limited to 'odb/sqlite/object-statements.hxx') diff --git a/odb/sqlite/object-statements.hxx b/odb/sqlite/object-statements.hxx new file mode 100644 index 0000000..73f3162 --- /dev/null +++ b/odb/sqlite/object-statements.hxx @@ -0,0 +1,333 @@ +// file : odb/sqlite/object-statements.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_SQLITE_OBJECT_STATEMENTS_HXX +#define ODB_SQLITE_OBJECT_STATEMENTS_HXX + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace odb +{ + namespace sqlite + { + class connection; + + class LIBODB_SQLITE_EXPORT object_statements_base: + public details::shared_base + { + public: + typedef sqlite::connection connection_type; + + connection_type& + connection () + { + return conn_; + } + + // Locking. + // + void + lock () + { + assert (!locked_); + locked_ = true; + } + + void + unlock () + { + assert (locked_); + locked_ = false; + } + + bool + locked () const + { + return locked_; + } + + public: + virtual + ~object_statements_base (); + + protected: + object_statements_base (connection_type& conn) + : conn_ (conn), locked_ (false) + { + } + + protected: + connection_type& conn_; + bool locked_; + }; + + template + class object_statements: public object_statements_base + { + public: + typedef T object_type; + typedef odb::object_traits object_traits; + typedef typename object_traits::id_type id_type; + typedef typename object_traits::pointer_type pointer_type; + typedef typename object_traits::image_type image_type; + typedef typename object_traits::id_image_type id_image_type; + + typedef pointer_cache_traits object_cache_traits; + + typedef + typename object_traits::container_statement_cache_type + container_statement_cache_type; + + typedef sqlite::insert_statement persist_statement_type; + typedef sqlite::select_statement find_statement_type; + typedef sqlite::update_statement update_statement_type; + typedef sqlite::delete_statement erase_statement_type; + + // Automatic lock. + // + struct auto_lock + { + // Lock the statements unless they are already locked in which + // case subsequent calls to locked() will return false. + // + auto_lock (object_statements&); + + // Unlock the statemens if we are holding the lock and clear + // the delayed loads. This should only happen in case an + // exception is thrown. In normal circumstances, the user + // should call unlock() explicitly. + // + ~auto_lock (); + + // Return true if this auto_lock instance holds the lock. + // + bool + locked () const; + + // Unlock the statemens. + // + void + unlock (); + + private: + auto_lock (const auto_lock&); + auto_lock& operator= (const auto_lock&); + + private: + object_statements& s_; + bool locked_; + }; + + // + // + object_statements (connection_type&); + + // Delayed loading. + // + void + delay_load (const id_type& id, + object_type& obj, + const typename object_cache_traits::position_type& p) + { + delayed_.push_back (delayed_load (id, obj, p)); + } + + void + load_delayed () + { + assert (locked ()); + + if (!delayed_.empty ()) + load_delayed_ (); + } + + void + clear_delayed () + { + if (!delayed_.empty ()) + clear_delayed_ (); + } + + // Object image. + // + image_type& + image () + { + return image_; + } + + binding& + in_image_binding () + { + return in_image_binding_; + } + + binding& + out_image_binding () + { + return out_image_binding_; + } + + bool* + out_image_truncated () + { + return out_image_truncated_; + } + + // Object id image. + // + id_image_type& + id_image () + { + return id_image_; + } + + binding& + id_image_binding () + { + return id_image_binding_; + } + + // Statements. + // + persist_statement_type& + persist_statement () + { + if (persist_ == 0) + persist_.reset ( + new (details::shared) persist_statement_type ( + conn_, object_traits::persist_statement, in_image_binding_)); + + return *persist_; + } + + find_statement_type& + find_statement () + { + if (find_ == 0) + find_.reset ( + new (details::shared) find_statement_type ( + conn_, + object_traits::find_statement, + id_image_binding_, + out_image_binding_)); + + return *find_; + } + + update_statement_type& + update_statement () + { + if (update_ == 0) + update_.reset ( + new (details::shared) update_statement_type ( + conn_, + object_traits::update_statement, + id_image_binding_, + in_image_binding_)); + + return *update_; + } + + erase_statement_type& + erase_statement () + { + if (erase_ == 0) + erase_.reset ( + new (details::shared) erase_statement_type ( + conn_, + object_traits::erase_statement, + id_image_binding_)); + + return *erase_; + } + + // Container statement cache. + // + container_statement_cache_type& + container_statment_cache () + { + return container_statement_cache_; + } + + private: + object_statements (const object_statements&); + object_statements& operator= (const object_statements&); + + private: + void + load_delayed_ (); + + void + clear_delayed_ (); + + private: + container_statement_cache_type container_statement_cache_; + + image_type image_; + + // In (send) binding. The last element is the id parameter. + // + binding in_image_binding_; + bind in_image_bind_[object_traits::in_column_count + 1]; + + // Out (receive) binding. + // + binding out_image_binding_; + bind out_image_bind_[object_traits::out_column_count]; + bool out_image_truncated_[object_traits::out_column_count]; + + // Id image binding (only in). + // + id_image_type id_image_; + binding id_image_binding_; + + details::shared_ptr persist_; + details::shared_ptr find_; + details::shared_ptr update_; + details::shared_ptr erase_; + + // Delayed loading. + // + struct delayed_load + { + typedef typename object_cache_traits::position_type position_type; + + delayed_load () {} + delayed_load (const id_type& i, object_type& o, const position_type& p) + : id (i), obj (&o), pos (p) + { + } + + id_type id; + object_type* obj; + position_type pos; + }; + + typedef std::vector delayed_loads; + delayed_loads delayed_; + }; + } +} + +#include +#include + +#include + +#endif // ODB_SQLITE_OBJECT_STATEMENTS_HXX -- cgit v1.1