From 043f4a1a1bb27baafa25c959e2284453ca32dc47 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 15 Oct 2012 13:17:30 +0200 Subject: Implement early connection release --- odb/mssql/connection-factory.cxx | 3 +++ odb/mssql/connection.cxx | 3 ++- odb/mssql/connection.hxx | 3 +++ odb/mssql/no-id-object-result.hxx | 3 +++ odb/mssql/no-id-object-result.txx | 27 +++++++++++++++++++-------- odb/mssql/polymorphic-object-result.hxx | 3 +++ odb/mssql/polymorphic-object-result.txx | 26 +++++++++++++++++++------- odb/mssql/prepared-query.hxx | 2 ++ odb/mssql/simple-object-result.hxx | 3 +++ odb/mssql/simple-object-result.txx | 24 ++++++++++++++++++------ odb/mssql/transaction-impl.cxx | 15 +++++++++++---- odb/mssql/view-result.hxx | 3 +++ odb/mssql/view-result.txx | 25 ++++++++++++++++++------- 13 files changed, 107 insertions(+), 33 deletions(-) diff --git a/odb/mssql/connection-factory.cxx b/odb/mssql/connection-factory.cxx index 1a86fcf..8360423 100644 --- a/odb/mssql/connection-factory.cxx +++ b/odb/mssql/connection-factory.cxx @@ -133,7 +133,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/mssql/connection.cxx b/odb/mssql/connection.cxx index 808d560..4c69a0c 100644 --- a/odb/mssql/connection.cxx +++ b/odb/mssql/connection.cxx @@ -103,7 +103,8 @@ namespace odb { // Deallocate prepared statements before we close the connection. // - prepared_map_.clear (); + recycle (); + clear_prepared_map (); statement_cache_.reset (); direct_stmt_.reset (); diff --git a/odb/mssql/connection.hxx b/odb/mssql/connection.hxx index 2744f4f..0451f9b 100644 --- a/odb/mssql/connection.hxx +++ b/odb/mssql/connection.hxx @@ -132,6 +132,9 @@ namespace odb connection& operator= (const connection&); private: + friend class transaction_impl; // invalidate_results() + + private: database_type& db_; auto_handle handle_; diff --git a/odb/mssql/no-id-object-result.hxx b/odb/mssql/no-id-object-result.hxx index 97f49f9..f9b2b99 100644 --- a/odb/mssql/no-id-object-result.hxx +++ b/odb/mssql/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/mssql/no-id-object-result.txx b/odb/mssql/no-id-object-result.txx index c7e9914..bed98ac 100644 --- a/odb/mssql/no-id-object-result.txx +++ b/odb/mssql/no-id-object-result.txx @@ -16,18 +16,31 @@ namespace odb no_id_object_result_impl:: ~no_id_object_result_impl () { + invalidate (); + } + + template + void no_id_object_result_impl:: + invalidate () + { change_callback_type& cc (statements_.image ().change_callback_); if (cc.context == this) { - cc.context = 0; cc.callback = 0; + cc.context = 0; } + delete image_copy_; + image_copy_ = 0; + if (!this->end_) + { statement_->free_result (); + this->end_ = true; + } - delete image_copy_; + statement_.reset (); } template @@ -35,7 +48,7 @@ namespace odb no_id_object_result_impl (const query_base&, details::shared_ptr statement, statements_type& statements) - : base_type (statements.connection ().database ()), + : base_type (statements.connection ()), statement_ (statement), statements_ (statements), use_copy_ (false), @@ -50,13 +63,11 @@ namespace odb if (!can_load_) throw long_data_reload (); - odb::database& db (this->database ()); - - object_traits::callback (db, obj, callback_event::pre_load); + object_traits::callback (this->db_, obj, callback_event::pre_load); object_traits::init (obj, use_copy_ ? *image_copy_ : statements_.image (), - &db); + &this->db_); // If we are using a copy, make sure the callback information for // long data also comes from the copy. @@ -65,7 +76,7 @@ namespace odb use_copy_ ? &statements_.image () : 0, use_copy_ ? image_copy_ : 0); - object_traits::callback (db, obj, callback_event::post_load); + object_traits::callback (this->db_, obj, callback_event::post_load); } template diff --git a/odb/mssql/polymorphic-object-result.hxx b/odb/mssql/polymorphic-object-result.hxx index d9e5c1e..f7c2b0a 100644 --- a/odb/mssql/polymorphic-object-result.hxx +++ b/odb/mssql/polymorphic-object-result.hxx @@ -68,6 +68,9 @@ namespace odb virtual std::size_t size (); + virtual void + invalidate (); + using base_type::current; private: diff --git a/odb/mssql/polymorphic-object-result.txx b/odb/mssql/polymorphic-object-result.txx index e469511..53244a3 100644 --- a/odb/mssql/polymorphic-object-result.txx +++ b/odb/mssql/polymorphic-object-result.txx @@ -18,6 +18,13 @@ namespace odb polymorphic_object_result_impl:: ~polymorphic_object_result_impl () { + invalidate (); + } + + template + void polymorphic_object_result_impl:: + invalidate () + { change_callback_type& cc ( statements_.root_statements ().image ().change_callback_); @@ -28,10 +35,15 @@ namespace odb } if (image_copy_ != 0) + { object_traits::free_image (image_copy_); + image_copy_ = 0; + } if (!this->end_) statement_->free_result (); + + statement_.reset (); } template @@ -39,7 +51,7 @@ namespace odb polymorphic_object_result_impl (const query_base&, details::shared_ptr st, statements_type& sts) - : base_type (sts.connection ().database ()), + : base_type (sts.connection ()), statement_ (st), statements_ (sts), use_copy_ (false), @@ -62,7 +74,6 @@ namespace odb assert (!rsts.locked ()); typename statements_type::auto_lock l (rsts); - odb::database& db (this->database ()); image_type& i (use_copy_ ? *image_copy_ : statements_.image ()); typename root_traits::image_type& ri ( use_copy_ ? object_traits::root_image (i) : rsts.image ()); @@ -99,7 +110,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); @@ -120,9 +132,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_); // If we are using a copy, make sure the callback information for // long data also comes from the copy. @@ -153,14 +165,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/mssql/prepared-query.hxx b/odb/mssql/prepared-query.hxx index 35a4774..c096e46 100644 --- a/odb/mssql/prepared-query.hxx +++ b/odb/mssql/prepared-query.hxx @@ -23,6 +23,8 @@ namespace odb virtual ~prepared_query_impl (); + prepared_query_impl (odb::connection& c): odb::prepared_query_impl (c) {} + mssql::query_base query; }; } diff --git a/odb/mssql/simple-object-result.hxx b/odb/mssql/simple-object-result.hxx index bdbd3ec..f9f4ea9 100644 --- a/odb/mssql/simple-object-result.hxx +++ b/odb/mssql/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/mssql/simple-object-result.txx b/odb/mssql/simple-object-result.txx index 68f4316..0cd9fa6 100644 --- a/odb/mssql/simple-object-result.txx +++ b/odb/mssql/simple-object-result.txx @@ -18,18 +18,31 @@ namespace odb object_result_impl:: ~object_result_impl () { + invalidate (); + } + + template + void object_result_impl:: + invalidate () + { change_callback_type& cc (statements_.image ().change_callback_); if (cc.context == this) { - cc.context = 0; cc.callback = 0; + cc.context = 0; } delete image_copy_; + image_copy_ = 0; if (!this->end_) + { statement_->free_result (); + this->end_ = true; + } + + statement_.reset (); } template @@ -37,7 +50,7 @@ namespace odb object_result_impl (const query_base&, details::shared_ptr statement, statements_type& statements) - : base_type (statements.connection ().database ()), + : base_type (statements.connection ()), statement_ (statement), statements_ (statements), use_copy_ (false), @@ -57,13 +70,12 @@ 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 ( use_copy_ ? *image_copy_ : statements_.image ()); - object_traits::init (obj, i, &db); + object_traits::init (obj, i, &this->db_); // If we are using a copy, make sure the callback information for // long data also comes from the copy. @@ -89,7 +101,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 diff --git a/odb/mssql/transaction-impl.cxx b/odb/mssql/transaction-impl.cxx index 15d210e..9dc9be8 100644 --- a/odb/mssql/transaction-impl.cxx +++ b/odb/mssql/transaction-impl.cxx @@ -56,6 +56,10 @@ namespace odb void transaction_impl:: commit () { + // Invalidate query results. + // + connection_->invalidate_results (); + { odb::tracer* t; if ((t = connection_->tracer ()) || (t = database_.tracer ())) @@ -68,15 +72,18 @@ namespace odb if (!SQL_SUCCEEDED (r)) translate_error (r, *connection_, true); - // We cannot release the connection early since we may still need - // to free (query) statements. + // Release the connection. // - //connection_.reset (); + connection_.reset (); } void transaction_impl:: rollback () { + // Invalidate query results. + // + connection_->invalidate_results (); + { odb::tracer* t; if ((t = connection_->tracer ()) || (t = database_.tracer ())) @@ -91,7 +98,7 @@ namespace odb // Release the connection. // - //connection_.reset (); + connection_.reset (); } } } diff --git a/odb/mssql/view-result.hxx b/odb/mssql/view-result.hxx index 7215641..26bf65e 100644 --- a/odb/mssql/view-result.hxx +++ b/odb/mssql/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/mssql/view-result.txx b/odb/mssql/view-result.txx index 208d511..b396808 100644 --- a/odb/mssql/view-result.txx +++ b/odb/mssql/view-result.txx @@ -16,6 +16,13 @@ namespace odb view_result_impl:: ~view_result_impl () { + invalidate (); + } + + template + void view_result_impl:: + invalidate () + { change_callback_type& cc (statements_.image ().change_callback_); if (cc.context == this) @@ -24,10 +31,16 @@ namespace odb cc.context = 0; } + delete image_copy_; + image_copy_ = 0; + if (!this->end_) + { statement_->free_result (); + this->end_ = true; + } - delete image_copy_; + statement_.reset (); } template @@ -35,7 +48,7 @@ namespace odb view_result_impl (const query_base&, details::shared_ptr statement, statements_type& statements) - : base_type (statements.connection ().database ()), + : base_type (statements.connection ()), statement_ (statement), statements_ (statements), use_copy_ (false), @@ -50,13 +63,11 @@ namespace odb if (!can_load_) throw long_data_reload (); - odb::database& db (this->database ()); - - view_traits::callback (db, view, callback_event::pre_load); + view_traits::callback (this->db_, view, callback_event::pre_load); view_traits::init (view, use_copy_ ? *image_copy_ : statements_.image (), - &db); + &this->db_); // If we are using a copy, make sure the callback information for // long data also comes from the copy. @@ -65,7 +76,7 @@ namespace odb use_copy_ ? &statements_.image () : 0, use_copy_ ? image_copy_ : 0); - view_traits::callback (db, view, callback_event::post_load); + view_traits::callback (this->db_, view, callback_event::post_load); } template -- cgit v1.1