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
commite4b2a3484d7a640ff84803e0d9374c93063a151e (patch)
tree367314821b69717f2c96856163dd874cedd5a110
parentfef380f6c9a5fb9904d551478fe180a9c5d24b37 (diff)
Implement early connection release
-rw-r--r--odb/pgsql/connection-factory.cxx3
-rw-r--r--odb/pgsql/connection.cxx3
-rw-r--r--odb/pgsql/connection.hxx3
-rw-r--r--odb/pgsql/no-id-object-result.hxx3
-rw-r--r--odb/pgsql/no-id-object-result.txx23
-rw-r--r--odb/pgsql/polymorphic-object-result.hxx3
-rw-r--r--odb/pgsql/polymorphic-object-result.txx27
-rw-r--r--odb/pgsql/prepared-query.hxx2
-rw-r--r--odb/pgsql/simple-object-result.hxx3
-rw-r--r--odb/pgsql/simple-object-result.txx22
-rw-r--r--odb/pgsql/transaction-impl.cxx16
-rw-r--r--odb/pgsql/view-result.hxx3
-rw-r--r--odb/pgsql/view-result.txx23
13 files changed, 109 insertions, 25 deletions
diff --git a/odb/pgsql/connection-factory.cxx b/odb/pgsql/connection-factory.cxx
index fdf3942..6e602d3 100644
--- a/odb/pgsql/connection-factory.cxx
+++ b/odb/pgsql/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/pgsql/connection.cxx b/odb/pgsql/connection.cxx
index 7921723..8569d39 100644
--- a/odb/pgsql/connection.cxx
+++ b/odb/pgsql/connection.cxx
@@ -72,7 +72,8 @@ namespace odb
{
// Destroy prepared query statements before freeing the connections.
//
- prepared_map_.clear ();
+ recycle ();
+ clear_prepared_map ();
}
transaction_impl* connection::
diff --git a/odb/pgsql/connection.hxx b/odb/pgsql/connection.hxx
index 3cc1f63..9c53b77 100644
--- a/odb/pgsql/connection.hxx
+++ b/odb/pgsql/connection.hxx
@@ -129,6 +129,9 @@ namespace odb
init ();
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/pgsql/no-id-object-result.hxx b/odb/pgsql/no-id-object-result.hxx
index 09a5517..684cb2e 100644
--- a/odb/pgsql/no-id-object-result.hxx
+++ b/odb/pgsql/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/pgsql/no-id-object-result.txx b/odb/pgsql/no-id-object-result.txx
index e9682b2..c406155 100644
--- a/odb/pgsql/no-id-object-result.txx
+++ b/odb/pgsql/no-id-object-result.txx
@@ -19,11 +19,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)
@@ -64,11 +77,9 @@ namespace odb
}
}
- odb::database& db (this->database ());
-
- object_traits::callback (db, obj, callback_event::pre_load);
- object_traits::init (obj, im, &db);
- object_traits::callback (db, obj, callback_event::post_load);
+ object_traits::callback (this->db_, obj, callback_event::pre_load);
+ object_traits::init (obj, im, &this->db_);
+ object_traits::callback (this->db_, obj, callback_event::post_load);
}
template <typename T>
diff --git a/odb/pgsql/polymorphic-object-result.hxx b/odb/pgsql/polymorphic-object-result.hxx
index 896b0e3..b953df9 100644
--- a/odb/pgsql/polymorphic-object-result.hxx
+++ b/odb/pgsql/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/pgsql/polymorphic-object-result.txx b/odb/pgsql/polymorphic-object-result.txx
index 5147fbe..daea20e 100644
--- a/odb/pgsql/polymorphic-object-result.txx
+++ b/odb/pgsql/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)
@@ -48,7 +61,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 ());
@@ -85,7 +97,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);
@@ -106,9 +119,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).
@@ -132,14 +145,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/pgsql/prepared-query.hxx b/odb/pgsql/prepared-query.hxx
index 9b90688..3e2e165 100644
--- a/odb/pgsql/prepared-query.hxx
+++ b/odb/pgsql/prepared-query.hxx
@@ -23,6 +23,8 @@ namespace odb
virtual
~prepared_query_impl ();
+ prepared_query_impl (odb::connection& c): odb::prepared_query_impl (c) {}
+
pgsql::query_base query;
};
}
diff --git a/odb/pgsql/simple-object-result.hxx b/odb/pgsql/simple-object-result.hxx
index c90065c..28887dc 100644
--- a/odb/pgsql/simple-object-result.hxx
+++ b/odb/pgsql/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/pgsql/simple-object-result.txx b/odb/pgsql/simple-object-result.txx
index 26fe9cc..168b8d8 100644
--- a/odb/pgsql/simple-object-result.txx
+++ b/odb/pgsql/simple-object-result.txx
@@ -21,11 +21,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)
@@ -44,11 +57,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).
@@ -67,7 +79,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/pgsql/transaction-impl.cxx b/odb/pgsql/transaction-impl.cxx
index c6fe61a..7cc2bc2 100644
--- a/odb/pgsql/transaction-impl.cxx
+++ b/odb/pgsql/transaction-impl.cxx
@@ -62,6 +62,10 @@ namespace odb
void transaction_impl::
commit ()
{
+ // Invalidate query results.
+ //
+ connection_->invalidate_results ();
+
{
odb::tracer* t;
if ((t = connection_->tracer ()) || (t = database_.tracer ()))
@@ -72,11 +76,19 @@ namespace odb
if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
translate_error (*connection_, h);
+
+ // Release the connection.
+ //
+ connection_.reset ();
}
void transaction_impl::
rollback ()
{
+ // Invalidate query results.
+ //
+ connection_->invalidate_results ();
+
{
odb::tracer* t;
if ((t = connection_->tracer ()) || (t = database_.tracer ()))
@@ -87,6 +99,10 @@ namespace odb
if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
translate_error (*connection_, h);
+
+ // Release the connection.
+ //
+ connection_.reset ();
}
}
}
diff --git a/odb/pgsql/view-result.hxx b/odb/pgsql/view-result.hxx
index d0a21d6..c7b4723 100644
--- a/odb/pgsql/view-result.hxx
+++ b/odb/pgsql/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/pgsql/view-result.txx b/odb/pgsql/view-result.txx
index d596e7c..0d89fbe 100644
--- a/odb/pgsql/view-result.txx
+++ b/odb/pgsql/view-result.txx
@@ -19,11 +19,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)
@@ -64,11 +77,9 @@ namespace odb
}
}
- odb::database& db (this->database ());
-
- view_traits::callback (db, view, callback_event::pre_load);
- view_traits::init (view, im, &db);
- view_traits::callback (db, view, callback_event::post_load);
+ view_traits::callback (this->db_, view, callback_event::pre_load);
+ view_traits::init (view, im, &this->db_);
+ view_traits::callback (this->db_, view, callback_event::post_load);
}
template <typename T>