aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-10-15 13:17:30 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-10-15 13:17:30 +0200
commit043f4a1a1bb27baafa25c959e2284453ca32dc47 (patch)
treeebaefd68f235350b1a14690c6d89e726d4aca8da
parenta049724c258a42af57d1ff572c3d15a3678e3875 (diff)
Implement early connection release
-rw-r--r--odb/mssql/connection-factory.cxx3
-rw-r--r--odb/mssql/connection.cxx3
-rw-r--r--odb/mssql/connection.hxx3
-rw-r--r--odb/mssql/no-id-object-result.hxx3
-rw-r--r--odb/mssql/no-id-object-result.txx27
-rw-r--r--odb/mssql/polymorphic-object-result.hxx3
-rw-r--r--odb/mssql/polymorphic-object-result.txx26
-rw-r--r--odb/mssql/prepared-query.hxx2
-rw-r--r--odb/mssql/simple-object-result.hxx3
-rw-r--r--odb/mssql/simple-object-result.txx24
-rw-r--r--odb/mssql/transaction-impl.cxx15
-rw-r--r--odb/mssql/view-result.hxx3
-rw-r--r--odb/mssql/view-result.txx25
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<SQL_HANDLE_DBC> 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<T>::
~no_id_object_result_impl ()
{
+ invalidate ();
+ }
+
+ template <typename T>
+ void no_id_object_result_impl<T>::
+ 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 <typename T>
@@ -35,7 +48,7 @@ namespace odb
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),
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 <typename T>
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<T>::
~polymorphic_object_result_impl ()
{
+ invalidate ();
+ }
+
+ template <typename T>
+ void polymorphic_object_result_impl<T>::
+ 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 <typename T>
@@ -39,7 +51,7 @@ namespace odb
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),
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<T>::
~object_result_impl ()
{
+ invalidate ();
+ }
+
+ template <typename T>
+ void object_result_impl<T>::
+ 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 <typename T>
@@ -37,7 +50,7 @@ namespace odb
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),
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 <typename T>
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<T>::
~view_result_impl ()
{
+ invalidate ();
+ }
+
+ template <typename T>
+ void view_result_impl<T>::
+ 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 <typename T>
@@ -35,7 +48,7 @@ namespace odb
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),
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 <typename T>