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
commitc3a2b62f33e1f3fe19700257efdba7123b272cc4 (patch)
tree281f2275a2a7202c24bf114532adcd5752eaf19d
parent9126281b53722115b2e8624632f2dd616f0c26a0 (diff)
Implement early connection release
-rw-r--r--odb/mysql/connection-factory.cxx3
-rw-r--r--odb/mysql/connection.cxx3
-rw-r--r--odb/mysql/connection.hxx3
-rw-r--r--odb/mysql/no-id-object-result.hxx3
-rw-r--r--odb/mysql/no-id-object-result.txx23
-rw-r--r--odb/mysql/polymorphic-object-result.hxx3
-rw-r--r--odb/mysql/polymorphic-object-result.txx27
-rw-r--r--odb/mysql/prepared-query.hxx2
-rw-r--r--odb/mysql/simple-object-result.hxx3
-rw-r--r--odb/mysql/simple-object-result.txx22
-rw-r--r--odb/mysql/transaction-impl.cxx20
-rw-r--r--odb/mysql/view-result.hxx3
-rw-r--r--odb/mysql/view-result.txx23
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>