diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-15 13:17:30 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-15 13:17:30 +0200 |
commit | c3a2b62f33e1f3fe19700257efdba7123b272cc4 (patch) | |
tree | 281f2275a2a7202c24bf114532adcd5752eaf19d | |
parent | 9126281b53722115b2e8624632f2dd616f0c26a0 (diff) |
Implement early connection release
-rw-r--r-- | odb/mysql/connection-factory.cxx | 3 | ||||
-rw-r--r-- | odb/mysql/connection.cxx | 3 | ||||
-rw-r--r-- | odb/mysql/connection.hxx | 3 | ||||
-rw-r--r-- | odb/mysql/no-id-object-result.hxx | 3 | ||||
-rw-r--r-- | odb/mysql/no-id-object-result.txx | 23 | ||||
-rw-r--r-- | odb/mysql/polymorphic-object-result.hxx | 3 | ||||
-rw-r--r-- | odb/mysql/polymorphic-object-result.txx | 27 | ||||
-rw-r--r-- | odb/mysql/prepared-query.hxx | 2 | ||||
-rw-r--r-- | odb/mysql/simple-object-result.hxx | 3 | ||||
-rw-r--r-- | odb/mysql/simple-object-result.txx | 22 | ||||
-rw-r--r-- | odb/mysql/transaction-impl.cxx | 20 | ||||
-rw-r--r-- | odb/mysql/view-result.hxx | 3 | ||||
-rw-r--r-- | odb/mysql/view-result.txx | 23 |
13 files changed, 111 insertions, 27 deletions
diff --git a/odb/mysql/connection-factory.cxx b/odb/mysql/connection-factory.cxx index cc23de5..45a6edb 100644 --- a/odb/mysql/connection-factory.cxx +++ b/odb/mysql/connection-factory.cxx @@ -273,7 +273,10 @@ namespace odb in_use_--; if (keep) + { connections_.push_back (pooled_connection_ptr (inc_ref (c))); + connections_.back ()->recycle (); + } if (waiters_ != 0) cond_.signal (); diff --git a/odb/mysql/connection.cxx b/odb/mysql/connection.cxx index ef854c6..17dd939 100644 --- a/odb/mysql/connection.cxx +++ b/odb/mysql/connection.cxx @@ -85,7 +85,8 @@ namespace odb // Destroy prepared query statements before freeing the connections. // - prepared_map_.clear (); + recycle (); + clear_prepared_map (); if (stmt_handles_.size () > 0) free_stmt_handles (); diff --git a/odb/mysql/connection.hxx b/odb/mysql/connection.hxx index 88fd04d..e729407 100644 --- a/odb/mysql/connection.hxx +++ b/odb/mysql/connection.hxx @@ -173,6 +173,9 @@ namespace odb clear_ (); private: + friend class transaction_impl; // invalidate_results() + + private: // Needed to break the circular connection-database dependency // (odb::connection has the odb::database member). // diff --git a/odb/mysql/no-id-object-result.hxx b/odb/mysql/no-id-object-result.hxx index 5907d20..c57a6f9 100644 --- a/odb/mysql/no-id-object-result.hxx +++ b/odb/mysql/no-id-object-result.hxx @@ -54,6 +54,9 @@ namespace odb virtual std::size_t size (); + virtual void + invalidate (); + using base_type::current; private: diff --git a/odb/mysql/no-id-object-result.txx b/odb/mysql/no-id-object-result.txx index 530eeb7..6bcad44 100644 --- a/odb/mysql/no-id-object-result.txx +++ b/odb/mysql/no-id-object-result.txx @@ -20,11 +20,24 @@ namespace odb } template <typename T> + void no_id_object_result_impl<T>:: + invalidate () + { + if (!this->end_) + { + statement_->free_result (); + this->end_ = true; + } + + statement_.reset (); + } + + template <typename T> no_id_object_result_impl<T>:: no_id_object_result_impl (const query_base&, details::shared_ptr<select_statement> statement, statements_type& statements) - : base_type (statements.connection ().database ()), + : base_type (statements.connection ()), statement_ (statement), statements_ (statements), count_ (0) @@ -38,11 +51,9 @@ namespace odb if (count_ > statement_->fetched ()) fetch (); - odb::database& db (this->database ()); - - object_traits::callback (db, obj, callback_event::pre_load); - object_traits::init (obj, statements_.image (), &db); - object_traits::callback (db, obj, callback_event::post_load); + object_traits::callback (this->db_, obj, callback_event::pre_load); + object_traits::init (obj, statements_.image (), &this->db_); + object_traits::callback (this->db_, obj, callback_event::post_load); } template <typename T> diff --git a/odb/mysql/polymorphic-object-result.hxx b/odb/mysql/polymorphic-object-result.hxx index 7749e14..ebd1756 100644 --- a/odb/mysql/polymorphic-object-result.hxx +++ b/odb/mysql/polymorphic-object-result.hxx @@ -67,6 +67,9 @@ namespace odb virtual std::size_t size (); + virtual void + invalidate (); + using base_type::current; private: diff --git a/odb/mysql/polymorphic-object-result.txx b/odb/mysql/polymorphic-object-result.txx index 518ff91..32b5524 100644 --- a/odb/mysql/polymorphic-object-result.txx +++ b/odb/mysql/polymorphic-object-result.txx @@ -22,11 +22,24 @@ namespace odb } template <typename T> + void polymorphic_object_result_impl<T>:: + invalidate () + { + if (!this->end_) + { + statement_->free_result (); + this->end_ = true; + } + + statement_.reset (); + } + + template <typename T> polymorphic_object_result_impl<T>:: polymorphic_object_result_impl (const query_base&, details::shared_ptr<select_statement> st, statements_type& sts) - : base_type (sts.connection ().database ()), + : base_type (sts.connection ()), statement_ (st), statements_ (sts), count_ (0) @@ -55,7 +68,6 @@ namespace odb assert (!rsts.locked ()); typename statements_type::auto_lock l (rsts); - odb::database& db (this->database ()); typename object_traits::image_type& i (statements_.image ()); typename root_traits::image_type& ri (rsts.image ()); @@ -92,7 +104,8 @@ namespace odb // Insert it as a root pointer (for non-unique pointers, rp should // still be valid and for unique pointers this is a no-op). // - ig.reset (object_traits::pointer_cache_traits::insert (db, id, rp)); + ig.reset ( + object_traits::pointer_cache_traits::insert (this->db_, id, rp)); pobj = &pointer_traits::get_ref (p); current (p); @@ -113,9 +126,9 @@ namespace odb } callback_event ce (callback_event::pre_load); - pi.dispatch (info_type::call_callback, db, pobj, &ce); + pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); - object_traits::init (*pobj, i, &db); + object_traits::init (*pobj, i, &this->db_); // Initialize the id image and binding and load the rest of the object // (containers, dynamic part, etc). @@ -139,14 +152,14 @@ namespace odb if (&pi != &object_traits::info) { std::size_t d (object_traits::depth); - pi.dispatch (info_type::call_load, db, pobj, &d); + pi.dispatch (info_type::call_load, this->db_, pobj, &d); }; rsts.load_delayed (); l.unlock (); ce = callback_event::post_load; - pi.dispatch (info_type::call_callback, db, pobj, &ce); + pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); ig.release (); } diff --git a/odb/mysql/prepared-query.hxx b/odb/mysql/prepared-query.hxx index da83aee..684009f 100644 --- a/odb/mysql/prepared-query.hxx +++ b/odb/mysql/prepared-query.hxx @@ -23,6 +23,8 @@ namespace odb virtual ~prepared_query_impl (); + prepared_query_impl (odb::connection& c): odb::prepared_query_impl (c) {} + mysql::query_base query; }; } diff --git a/odb/mysql/simple-object-result.hxx b/odb/mysql/simple-object-result.hxx index bcf74f7..2eb2930 100644 --- a/odb/mysql/simple-object-result.hxx +++ b/odb/mysql/simple-object-result.hxx @@ -58,6 +58,9 @@ namespace odb virtual std::size_t size (); + virtual void + invalidate (); + using base_type::current; private: diff --git a/odb/mysql/simple-object-result.txx b/odb/mysql/simple-object-result.txx index e341b16..fa554dc 100644 --- a/odb/mysql/simple-object-result.txx +++ b/odb/mysql/simple-object-result.txx @@ -22,11 +22,24 @@ namespace odb } template <typename T> + void object_result_impl<T>:: + invalidate () + { + if (!this->end_) + { + statement_->free_result (); + this->end_ = true; + } + + statement_.reset (); + } + + template <typename T> object_result_impl<T>:: object_result_impl (const query_base&, details::shared_ptr<select_statement> statement, statements_type& statements) - : base_type (statements.connection ().database ()), + : base_type (statements.connection ()), statement_ (statement), statements_ (statements), count_ (0) @@ -52,11 +65,10 @@ namespace odb assert (!statements_.locked ()); typename statements_type::auto_lock l (statements_); - odb::database& db (this->database ()); - object_traits::callback (db, obj, callback_event::pre_load); + object_traits::callback (this->db_, obj, callback_event::pre_load); typename object_traits::image_type& i (statements_.image ()); - object_traits::init (obj, i, &db); + object_traits::init (obj, i, &this->db_); // Initialize the id image and binding and load the rest of the object // (containers, etc). @@ -75,7 +87,7 @@ namespace odb object_traits::load_ (statements_, obj); statements_.load_delayed (); l.unlock (); - object_traits::callback (db, obj, callback_event::post_load); + object_traits::callback (this->db_, obj, callback_event::post_load); } template <typename T> diff --git a/odb/mysql/transaction-impl.cxx b/odb/mysql/transaction-impl.cxx index 02b3581..75b9c9a 100644 --- a/odb/mysql/transaction-impl.cxx +++ b/odb/mysql/transaction-impl.cxx @@ -55,6 +55,14 @@ namespace odb void transaction_impl:: commit () { + // Invalidate query results. + // + connection_->invalidate_results (); + + // Cancel and clear the active statement if any. This normally + // should happen automatically, however, if an exception is + // thrown, this may not be the case. + // connection_->clear (); { @@ -68,12 +76,20 @@ namespace odb // Release the connection. // - //connection_.reset (); + connection_.reset (); } void transaction_impl:: rollback () { + // Invalidate query results. + // + connection_->invalidate_results (); + + // Cancel and clear the active statement if any. This normally + // should happen automatically, however, if an exception is + // thrown, this may not be the case. + // connection_->clear (); { @@ -87,7 +103,7 @@ namespace odb // Release the connection. // - //connection_.reset (); + connection_.reset (); } } } diff --git a/odb/mysql/view-result.hxx b/odb/mysql/view-result.hxx index 14a6002..25a4a43 100644 --- a/odb/mysql/view-result.hxx +++ b/odb/mysql/view-result.hxx @@ -54,6 +54,9 @@ namespace odb virtual std::size_t size (); + virtual void + invalidate (); + using base_type::current; private: diff --git a/odb/mysql/view-result.txx b/odb/mysql/view-result.txx index 27eb1ab..5c26fce 100644 --- a/odb/mysql/view-result.txx +++ b/odb/mysql/view-result.txx @@ -20,11 +20,24 @@ namespace odb } template <typename T> + void view_result_impl<T>:: + invalidate () + { + if (!this->end_) + { + statement_->free_result (); + this->end_ = true; + } + + statement_.reset (); + } + + template <typename T> view_result_impl<T>:: view_result_impl (const query_base&, details::shared_ptr<select_statement> statement, statements_type& statements) - : base_type (statements.connection ().database ()), + : base_type (statements.connection ()), statement_ (statement), statements_ (statements), count_ (0) @@ -38,11 +51,9 @@ namespace odb if (count_ > statement_->fetched ()) fetch (); - odb::database& db (this->database ()); - - view_traits::callback (db, view, callback_event::pre_load); - view_traits::init (view, statements_.image (), &db); - view_traits::callback (db, view, callback_event::post_load); + view_traits::callback (this->db_, view, callback_event::pre_load); + view_traits::init (view, statements_.image (), &this->db_); + view_traits::callback (this->db_, view, callback_event::post_load); } template <typename T> |