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-19 11:40:30 +0200
commit8112bd0febcfa1e3a76e0d03363facbefc3822f7 (patch)
tree0f5a05b9b29ae7d77e95f7831c214b385aaf6a3b
parentd94948b8bccfd8748245726487d54c41bb199baf (diff)
Implement early connection release
-rw-r--r--odb/sqlite/connection-factory.cxx4
-rw-r--r--odb/sqlite/connection.cxx14
-rw-r--r--odb/sqlite/connection.hxx7
-rw-r--r--odb/sqlite/container-statements.hxx6
-rw-r--r--odb/sqlite/no-id-object-result.hxx3
-rw-r--r--odb/sqlite/no-id-object-result.txx24
-rw-r--r--odb/sqlite/no-id-object-statements.hxx2
-rw-r--r--odb/sqlite/polymorphic-object-result.hxx3
-rw-r--r--odb/sqlite/polymorphic-object-result.txx28
-rw-r--r--odb/sqlite/polymorphic-object-statements.hxx10
-rw-r--r--odb/sqlite/prepared-query.hxx2
-rw-r--r--odb/sqlite/simple-object-result.hxx3
-rw-r--r--odb/sqlite/simple-object-result.txx23
-rw-r--r--odb/sqlite/simple-object-statements.hxx10
-rw-r--r--odb/sqlite/statement-cache.cxx5
-rw-r--r--odb/sqlite/statement.cxx41
-rw-r--r--odb/sqlite/statement.hxx61
-rw-r--r--odb/sqlite/transaction-impl.cxx25
-rw-r--r--odb/sqlite/view-result.hxx3
-rw-r--r--odb/sqlite/view-result.txx24
20 files changed, 148 insertions, 150 deletions
diff --git a/odb/sqlite/connection-factory.cxx b/odb/sqlite/connection-factory.cxx
index 62e43f2..8eb9885 100644
--- a/odb/sqlite/connection-factory.cxx
+++ b/odb/sqlite/connection-factory.cxx
@@ -68,6 +68,7 @@ namespace odb
{
c->factory_ = 0;
connection_.reset (inc_ref (c));
+ connection_->recycle ();
mutex_.unlock ();
return false;
}
@@ -224,7 +225,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/sqlite/connection.cxx b/odb/sqlite/connection.cxx
index bcf28a2..b62ac8c 100644
--- a/odb/sqlite/connection.cxx
+++ b/odb/sqlite/connection.cxx
@@ -104,7 +104,8 @@ namespace odb
{
// Destroy prepared query statements before freeing the connections.
//
- prepared_map_.clear ();
+ recycle ();
+ clear_prepared_map ();
}
transaction_impl* connection::
@@ -176,15 +177,8 @@ namespace odb
// The current first statement will remove itself from the list
// and make the second statement (if any) the new first.
//
- while (statement* s = statements_)
- {
- if (!s->cached ())
- s->finilize ();
- else if (s->active ())
- s->reset ();
- else
- assert (false); // Statement is neither active nor unached.
- }
+ while (statements_ != 0)
+ statements_->reset ();
}
}
}
diff --git a/odb/sqlite/connection.hxx b/odb/sqlite/connection.hxx
index 3524a48..2754102 100644
--- a/odb/sqlite/connection.hxx
+++ b/odb/sqlite/connection.hxx
@@ -123,7 +123,7 @@ namespace odb
wait ();
public:
- // Reset active and finalize uncached statements.
+ // Reset active statements.
//
void
clear ();
@@ -159,7 +159,10 @@ namespace odb
friend void
connection_unlock_callback (void**, int);
- // Linked list of active and uncached statements currently associated
+ private:
+ friend class transaction_impl; // invalidate_results()
+
+ // Linked list of active statements currently associated
// with this connection.
//
private:
diff --git a/odb/sqlite/container-statements.hxx b/odb/sqlite/container-statements.hxx
index 80011d9..a7b39bf 100644
--- a/odb/sqlite/container-statements.hxx
+++ b/odb/sqlite/container-statements.hxx
@@ -173,8 +173,6 @@ namespace odb
insert_one_.reset (
new (details::shared) insert_statement_type (
conn_, insert_one_text_, data_image_binding_));
-
- insert_one_->cached (true);
}
return *insert_one_;
@@ -191,8 +189,6 @@ namespace odb
select_all_text_,
cond_image_binding_,
select_image_binding_));
-
- select_all_->cached (true);
}
return *select_all_;
@@ -206,8 +202,6 @@ namespace odb
delete_all_.reset (
new (details::shared) delete_statement_type (
conn_, delete_all_text_, cond_image_binding_));
-
- delete_all_->cached (true);
}
return *delete_all_;
diff --git a/odb/sqlite/no-id-object-result.hxx b/odb/sqlite/no-id-object-result.hxx
index 60e69e3..3b653bb 100644
--- a/odb/sqlite/no-id-object-result.hxx
+++ b/odb/sqlite/no-id-object-result.hxx
@@ -56,6 +56,9 @@ namespace odb
virtual std::size_t
size ();
+ virtual void
+ invalidate ();
+
using base_type::current;
private:
diff --git a/odb/sqlite/no-id-object-result.txx b/odb/sqlite/no-id-object-result.txx
index 3fe9fc2..9ffb836 100644
--- a/odb/sqlite/no-id-object-result.txx
+++ b/odb/sqlite/no-id-object-result.txx
@@ -20,11 +20,25 @@ namespace odb
}
template <typename T>
+ void no_id_object_result_impl<T>::
+ invalidate ()
+ {
+ if (!this->end_)
+ {
+ statement_->free_result ();
+ this->end_ = true;
+ }
+
+ params_.reset ();
+ statement_.reset ();
+ }
+
+ template <typename T>
no_id_object_result_impl<T>::
no_id_object_result_impl (const query_base& q,
const details::shared_ptr<select_statement>& s,
statements_type& sts)
- : base_type (sts.connection ().database ()),
+ : base_type (sts.connection ()),
result_impl_base (q, s),
statements_ (sts)
{
@@ -64,11 +78,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/sqlite/no-id-object-statements.hxx b/odb/sqlite/no-id-object-statements.hxx
index 93aedb0..f942cf4 100644
--- a/odb/sqlite/no-id-object-statements.hxx
+++ b/odb/sqlite/no-id-object-statements.hxx
@@ -88,8 +88,6 @@ namespace odb
conn_,
object_traits::persist_statement,
insert_image_binding_));
-
- persist_->cached (true);
}
return *persist_;
diff --git a/odb/sqlite/polymorphic-object-result.hxx b/odb/sqlite/polymorphic-object-result.hxx
index 9cf9c6c..0b03456 100644
--- a/odb/sqlite/polymorphic-object-result.hxx
+++ b/odb/sqlite/polymorphic-object-result.hxx
@@ -70,6 +70,9 @@ namespace odb
virtual std::size_t
size ();
+ virtual void
+ invalidate ();
+
using base_type::current;
private:
diff --git a/odb/sqlite/polymorphic-object-result.txx b/odb/sqlite/polymorphic-object-result.txx
index 0dd68cf..8e09bf1 100644
--- a/odb/sqlite/polymorphic-object-result.txx
+++ b/odb/sqlite/polymorphic-object-result.txx
@@ -22,12 +22,26 @@ namespace odb
}
template <typename T>
+ void polymorphic_object_result_impl<T>::
+ invalidate ()
+ {
+ if (!this->end_)
+ {
+ statement_->free_result ();
+ this->end_ = true;
+ }
+
+ params_.reset ();
+ statement_.reset ();
+ }
+
+ template <typename T>
polymorphic_object_result_impl<T>::
polymorphic_object_result_impl (
const query_base& q,
const details::shared_ptr<select_statement>& st,
statements_type& sts)
- : base_type (sts.connection ().database ()),
+ : base_type (sts.connection ()),
result_impl_base (q, st),
statements_ (sts)
{
@@ -48,7 +62,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 +98,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 +120,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 +146,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/sqlite/polymorphic-object-statements.hxx b/odb/sqlite/polymorphic-object-statements.hxx
index 286b9e3..50d66a3 100644
--- a/odb/sqlite/polymorphic-object-statements.hxx
+++ b/odb/sqlite/polymorphic-object-statements.hxx
@@ -107,8 +107,6 @@ namespace odb
object_traits::find_discriminator_statement,
discriminator_id_image_binding_,
discriminator_image_binding_));
-
- find_discriminator_->cached (true);
}
return *find_discriminator_;
@@ -296,8 +294,6 @@ namespace odb
conn_,
object_traits::persist_statement,
insert_image_binding_));
-
- persist_->cached (true);
}
return *persist_;
@@ -317,8 +313,6 @@ namespace odb
object_traits::find_statements[i],
root_statements_.id_image_binding (),
select_image_bindings_[i]));
-
- p->cached (true);
}
return *p;
@@ -334,8 +328,6 @@ namespace odb
conn_,
object_traits::update_statement,
update_image_binding_));
-
- update_->cached (true);
}
return *update_;
@@ -351,8 +343,6 @@ namespace odb
conn_,
object_traits::erase_statement,
root_statements_.id_image_binding ()));
-
- erase_->cached (true);
}
return *erase_;
diff --git a/odb/sqlite/prepared-query.hxx b/odb/sqlite/prepared-query.hxx
index ddc2c9c..2615179 100644
--- a/odb/sqlite/prepared-query.hxx
+++ b/odb/sqlite/prepared-query.hxx
@@ -23,6 +23,8 @@ namespace odb
virtual
~prepared_query_impl ();
+ prepared_query_impl (odb::connection& c): odb::prepared_query_impl (c) {}
+
sqlite::query_base query;
};
}
diff --git a/odb/sqlite/simple-object-result.hxx b/odb/sqlite/simple-object-result.hxx
index 3e2a17b..02b671e 100644
--- a/odb/sqlite/simple-object-result.hxx
+++ b/odb/sqlite/simple-object-result.hxx
@@ -60,6 +60,9 @@ namespace odb
virtual std::size_t
size ();
+ virtual void
+ invalidate ();
+
using base_type::current;
private:
diff --git a/odb/sqlite/simple-object-result.txx b/odb/sqlite/simple-object-result.txx
index 6763850..1de4b91 100644
--- a/odb/sqlite/simple-object-result.txx
+++ b/odb/sqlite/simple-object-result.txx
@@ -22,11 +22,25 @@ namespace odb
}
template <typename T>
+ void object_result_impl<T>::
+ invalidate ()
+ {
+ if (!this->end_)
+ {
+ statement_->free_result ();
+ this->end_ = true;
+ }
+
+ params_.reset ();
+ statement_.reset ();
+ }
+
+ template <typename T>
object_result_impl<T>::
object_result_impl (const query_base& q,
const details::shared_ptr<select_statement>& statement,
statements_type& statements)
- : base_type (statements.connection ().database ()),
+ : base_type (statements.connection ()),
result_impl_base (q, statement),
statements_ (statements)
{
@@ -44,11 +58,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 +80,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/sqlite/simple-object-statements.hxx b/odb/sqlite/simple-object-statements.hxx
index 66dc0f9..9ff3faf 100644
--- a/odb/sqlite/simple-object-statements.hxx
+++ b/odb/sqlite/simple-object-statements.hxx
@@ -345,8 +345,6 @@ namespace odb
conn_,
object_traits::persist_statement,
insert_image_binding_));
-
- persist_->cached (true);
}
return *persist_;
@@ -363,8 +361,6 @@ namespace odb
object_traits::find_statement,
id_image_binding_,
select_image_binding_));
-
- find_->cached (true);
}
return *find_;
@@ -380,8 +376,6 @@ namespace odb
conn_,
object_traits::update_statement,
update_image_binding_));
-
- update_->cached (true);
}
return *update_;
@@ -397,8 +391,6 @@ namespace odb
conn_,
object_traits::erase_statement,
id_image_binding_));
-
- erase_->cached (true);
}
return *erase_;
@@ -414,8 +406,6 @@ namespace odb
conn_,
object_traits::optimistic_erase_statement,
od_.id_image_binding_));
-
- od_.erase_->cached (true);
}
return *od_.erase_;
diff --git a/odb/sqlite/statement-cache.cxx b/odb/sqlite/statement-cache.cxx
index 6262b25..c350e02 100644
--- a/odb/sqlite/statement-cache.cxx
+++ b/odb/sqlite/statement-cache.cxx
@@ -20,9 +20,6 @@ namespace odb
commit_ (new (shared) generic_statement (conn_, "COMMIT", 7)),
rollback_ (new (shared) generic_statement (conn_, "ROLLBACK", 9))
{
- rollback_->cached (true);
- commit_->cached (true);
- begin_->cached (true);
}
void statement_cache::
@@ -30,7 +27,6 @@ namespace odb
{
begin_immediate_.reset (
new (shared) generic_statement (conn_, "BEGIN IMMEDIATE", 16));
- begin_immediate_->cached (true);
}
void statement_cache::
@@ -38,7 +34,6 @@ namespace odb
{
begin_exclusive_.reset (
new (shared) generic_statement (conn_, "BEGIN EXCLUSIVE", 16));
- begin_exclusive_->cached (true);
}
}
}
diff --git a/odb/sqlite/statement.cxx b/odb/sqlite/statement.cxx
index ce194ed..09cf994 100644
--- a/odb/sqlite/statement.cxx
+++ b/odb/sqlite/statement.cxx
@@ -24,22 +24,18 @@ namespace odb
statement::
~statement ()
{
- if (stmt_ != 0)
- finilize ();
- }
-
- void statement::
- cached (bool cached)
- {
- assert (cached);
-
- if (!cached_)
{
- if (!active_)
- list_remove ();
-
- cached_ = true;
+ odb::tracer* t;
+ if ((t = conn_.transaction_tracer ()) ||
+ (t = conn_.tracer ()) ||
+ (t = conn_.database ().tracer ()))
+ t->deallocate (conn_, *this);
}
+
+ if (next_ != this)
+ list_remove ();
+
+ stmt_.reset ();
}
void statement::
@@ -65,8 +61,6 @@ namespace odb
prev_ = 0;
next_ = this;
- list_add (); // Add to the list because we are uncached.
-
{
odb::tracer* t;
if ((t = conn_.transaction_tracer ()) ||
@@ -76,21 +70,6 @@ namespace odb
}
}
- void statement::
- finilize ()
- {
- {
- odb::tracer* t;
- if ((t = conn_.transaction_tracer ()) ||
- (t = conn_.tracer ()) ||
- (t = conn_.database ().tracer ()))
- t->deallocate (conn_, *this);
- }
-
- list_remove ();
- stmt_.reset ();
- }
-
const char* statement::
text () const
{
diff --git a/odb/sqlite/statement.hxx b/odb/sqlite/statement.hxx
index 92b9c7c..aabb57d 100644
--- a/odb/sqlite/statement.hxx
+++ b/odb/sqlite/statement.hxx
@@ -53,12 +53,6 @@ namespace odb
return conn_;
}
- public:
- using odb::statement::cached;
-
- virtual void
- cached (bool);
-
protected:
statement (connection_type& conn, const std::string& text)
: conn_ (conn)
@@ -118,22 +112,12 @@ namespace odb
{
if (active_)
{
- if (stmt_ != 0)
- sqlite3_reset (stmt_);
-
- if (cached_)
- list_remove ();
-
+ sqlite3_reset (stmt_);
+ list_remove ();
active_ = false;
}
}
- // Cached state (protected part).
- //
- protected:
- void
- finilize ();
-
protected:
friend class sqlite::connection;
@@ -146,38 +130,29 @@ namespace odb
void
init (const char* text, std::size_t text_size);
- // Doubly-linked list of active/uncached statements.
+ // Doubly-linked list of active statements.
//
private:
- void list_add ()
+ void
+ list_add ()
{
- if (next_ == this)
- {
- next_ = conn_.statements_;
- conn_.statements_ = this;
+ next_ = conn_.statements_;
+ conn_.statements_ = this;
- if (next_ != 0)
- next_->prev_ = this;
- }
+ if (next_ != 0)
+ next_->prev_ = this;
}
- void list_remove ()
+ void
+ list_remove ()
{
- if (next_ != this)
- {
- if (prev_ == 0)
- conn_.statements_ = next_;
- else
- {
- prev_->next_ = next_;
- }
-
- if (next_ != 0)
- next_->prev_ = prev_;
-
- prev_ = 0;
- next_ = this;
- }
+ (prev_ == 0 ? conn_.statements_ : prev_->next_) = next_;
+
+ if (next_ != 0)
+ next_->prev_ = prev_;
+
+ prev_ = 0;
+ next_ = this;
}
// prev_ == 0 means we are the first element.
diff --git a/odb/sqlite/transaction-impl.cxx b/odb/sqlite/transaction-impl.cxx
index 9497c0a..1975308 100644
--- a/odb/sqlite/transaction-impl.cxx
+++ b/odb/sqlite/transaction-impl.cxx
@@ -67,10 +67,15 @@ namespace odb
void transaction_impl::
commit ()
{
- // Reset active and finilize uncached statements. Active statements
- // will prevent COMMIT from completing (write statements) or releasing
- // the locks (read statements). Finilization of uncached statements is
- // needed to release the connection.
+ // Invalidate query results.
+ //
+ connection_->invalidate_results ();
+
+ // Reset active statements. Active statements will prevent COMMIT
+ // from completing (write statements) or releasing the locks (read
+ // statements). Normally, a statement is automatically reset on
+ // completion, however, if an exception is thrown, that may not
+ // happen.
//
connection_->clear ();
@@ -84,9 +89,15 @@ namespace odb
void transaction_impl::
rollback ()
{
- // Reset active and finilize uncached statements. Active statements
- // will prevent ROLLBACK from completing. Finilization of uncached
- // statements is needed to release the connection.
+ // Invalidate query results.
+ //
+ connection_->invalidate_results ();
+
+ // Reset active statements. Active statements will prevent ROLLBACK
+ // from completing (write statements) or releasing the locks (read
+ // statements). Normally, a statement is automatically reset on
+ // completion, however, if an exception is thrown, that may not
+ // happen.
//
connection_->clear ();
diff --git a/odb/sqlite/view-result.hxx b/odb/sqlite/view-result.hxx
index 7d552b7..a6d07e7 100644
--- a/odb/sqlite/view-result.hxx
+++ b/odb/sqlite/view-result.hxx
@@ -55,6 +55,9 @@ namespace odb
virtual std::size_t
size ();
+ virtual void
+ invalidate ();
+
using base_type::current;
private:
diff --git a/odb/sqlite/view-result.txx b/odb/sqlite/view-result.txx
index 5256467..ed7fdc8 100644
--- a/odb/sqlite/view-result.txx
+++ b/odb/sqlite/view-result.txx
@@ -20,11 +20,25 @@ namespace odb
}
template <typename T>
+ void view_result_impl<T>::
+ invalidate ()
+ {
+ if (!this->end_)
+ {
+ statement_->free_result ();
+ this->end_ = true;
+ }
+
+ params_.reset ();
+ statement_.reset ();
+ }
+
+ template <typename T>
view_result_impl<T>::
view_result_impl (const query_base& q,
const details::shared_ptr<select_statement>& statement,
statements_type& statements)
- : base_type (statements.connection ().database ()),
+ : base_type (statements.connection ()),
result_impl_base (q, statement),
statements_ (statements)
{
@@ -64,11 +78,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>