aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-03-07 10:21:09 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-03-07 10:21:09 +0200
commit19131a419b35e409e6b65fc47ff31f7742ff54f3 (patch)
tree48a2fc660814062ce114d83e939f16d0ede511e6
parentf573927d48a7ceb155cf681e7cbad1e5176b2c0b (diff)
Use RAII to free select statement results
-rw-r--r--odb/relational/context.cxx1
-rw-r--r--odb/relational/context.hxx1
-rw-r--r--odb/relational/mssql/context.cxx1
-rw-r--r--odb/relational/mssql/source.cxx18
-rw-r--r--odb/relational/mysql/context.cxx1
-rw-r--r--odb/relational/oracle/context.cxx1
-rw-r--r--odb/relational/pgsql/context.cxx1
-rw-r--r--odb/relational/source.hxx106
-rw-r--r--odb/relational/sqlite/context.cxx1
9 files changed, 65 insertions, 66 deletions
diff --git a/odb/relational/context.cxx b/odb/relational/context.cxx
index ae73603..98bbfe4 100644
--- a/odb/relational/context.cxx
+++ b/odb/relational/context.cxx
@@ -26,6 +26,7 @@ namespace relational
generate_grow (current ().generate_grow),
need_alias_as (current ().need_alias_as),
insert_send_auto_id (current ().insert_send_auto_id),
+ delay_freeing_statement_result (current ().delay_freeing_statement_result),
bind_vector (data_->bind_vector_),
truncated_vector (data_->truncated_vector_)
{
diff --git a/odb/relational/context.hxx b/odb/relational/context.hxx
index dddb86e..52cb9c0 100644
--- a/odb/relational/context.hxx
+++ b/odb/relational/context.hxx
@@ -158,6 +158,7 @@ namespace relational
bool generate_grow;
bool need_alias_as;
bool insert_send_auto_id;
+ bool delay_freeing_statement_result;
string const& bind_vector;
string const& truncated_vector;
diff --git a/odb/relational/mssql/context.cxx b/odb/relational/mssql/context.cxx
index 312cc03..1fddbe9 100644
--- a/odb/relational/mssql/context.cxx
+++ b/odb/relational/mssql/context.cxx
@@ -84,6 +84,7 @@ namespace relational
generate_grow = false;
need_alias_as = true;
insert_send_auto_id = false;
+ delay_freeing_statement_result = true;
data_->bind_vector_ = "mssql::bind*";
// Populate the C++ type to DB type map.
diff --git a/odb/relational/mssql/source.cxx b/odb/relational/mssql/source.cxx
index 1b800aa..2d8d41d 100644
--- a/odb/relational/mssql/source.cxx
+++ b/odb/relational/mssql/source.cxx
@@ -971,24 +971,6 @@ namespace relational
}
virtual void
- free_statement_result_immediate ()
- {
- // Only free the result if there are no rows. Otherwise we
- // need to keep the result alive until after we are done
- // streaming long data.
- //
- os << "if (r == select_statement::no_data)" << endl
- << "st.free_result ();"
- << endl;
- }
-
- virtual void
- free_statement_result_delayed ()
- {
- os << "sts.find_statement ().free_result ();";
- }
-
- virtual void
persist_statement_extra (type& c,
relational::query_parameters&,
persist_position p)
diff --git a/odb/relational/mysql/context.cxx b/odb/relational/mysql/context.cxx
index ad7236c..5d45934 100644
--- a/odb/relational/mysql/context.cxx
+++ b/odb/relational/mysql/context.cxx
@@ -80,6 +80,7 @@ namespace relational
generate_grow = true;
need_alias_as = true;
insert_send_auto_id = true;
+ delay_freeing_statement_result = false;
data_->bind_vector_ = "MYSQL_BIND*";
data_->truncated_vector_ = "my_bool*";
diff --git a/odb/relational/oracle/context.cxx b/odb/relational/oracle/context.cxx
index dbe61af..2fa566c 100644
--- a/odb/relational/oracle/context.cxx
+++ b/odb/relational/oracle/context.cxx
@@ -79,6 +79,7 @@ namespace relational
generate_grow = false;
need_alias_as = false;
insert_send_auto_id = true;
+ delay_freeing_statement_result = false;
data_->bind_vector_ = "oracle::bind*";
// Populate the C++ type to DB type map.
diff --git a/odb/relational/pgsql/context.cxx b/odb/relational/pgsql/context.cxx
index 17ceaaa..9ce333e 100644
--- a/odb/relational/pgsql/context.cxx
+++ b/odb/relational/pgsql/context.cxx
@@ -80,6 +80,7 @@ namespace relational
generate_grow = true;
need_alias_as = true;
insert_send_auto_id = true;
+ delay_freeing_statement_result = false;
data_->bind_vector_ = "pgsql::bind*";
data_->truncated_vector_ = "bool*";
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index a8edcf3..e6ca961 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -2191,7 +2191,6 @@ namespace relational
}
}
-
init_value_extra ();
// If we are loading an eager pointer, then the call to init
@@ -2236,12 +2235,7 @@ namespace relational
<< "}"
<< "}";
- os << "if (r == select_statement::no_data)"
- << "{"
- << "st.free_result ();"
- << "return false;"
- << "}"
- << "return true;"
+ os << "return r != select_statement::no_data;"
<< "}";
// delete_all
@@ -2315,7 +2309,8 @@ namespace relational
<< "cb.version++;"
<< "}"
<< "select_statement& st (sts.select_all_statement ());"
- << "st.execute ();";
+ << "st.execute ();"
+ << "auto_result ar (st);";
// If we are loading eager object pointers, we may need to cache
// the result since we will be loading other objects.
@@ -2344,9 +2339,6 @@ namespace relational
os << "bool more (r != select_statement::no_data);"
<< endl
- << "if (!more)" << endl
- << "st.free_result ();"
- << endl
<< "sts.id_binding (id);"
<< "functions_type& fs (sts.functions ());";
@@ -2809,19 +2801,6 @@ namespace relational
{
}
- // By default we free statement result immediately after fetch.
- //
- virtual void
- free_statement_result_immediate ()
- {
- os << "st.free_result ();";
- }
-
- virtual void
- free_statement_result_delayed ()
- {
- }
-
virtual void
object_query_statement_ctor_args (type&)
{
@@ -3553,7 +3532,8 @@ namespace relational
<< "throw object_not_persistent ();"
<< endl;
- free_statement_result_delayed ();
+ if (delay_freeing_statement_result)
+ os << "sts.find_statement ().free_result ();";
if (straight_readwrite_containers)
os << "binding& idb (sts.id_image_binding ());"
@@ -3698,7 +3678,8 @@ namespace relational
<< "throw object_changed ();"
<< endl;
- free_statement_result_delayed ();
+ if (delay_freeing_statement_result)
+ os << "sts.find_statement ().free_result ();";
os << "if (version (sts.image ()) != obj." <<
optimistic->name () << ")" << endl
@@ -3728,13 +3709,22 @@ namespace relational
<< db << "::transaction::current ().connection ());"
<< object_statements_type << "& sts (" << endl
<< "conn.statement_cache ().find_object<object_type> ());"
- << object_statements_type << "::auto_lock l (sts);"
- << endl
+ << object_statements_type << "::auto_lock l (sts);";
+
+ if (delay_freeing_statement_result)
+ os << "auto_result ar;";
+
+ os << endl
<< "if (l.locked ())"
<< "{"
<< "if (!find_ (sts, id))" << endl
- << "return pointer_type ();"
- << "}"
+ << "return pointer_type ();";
+
+ if (delay_freeing_statement_result)
+ os << endl
+ << "ar.set (sts.find_statement ());";
+
+ os << "}"
<< "pointer_type p (" << endl
<< "access::object_factory< object_type, pointer_type >::create ());"
<< "pointer_traits< pointer_type >::guard pg (p);"
@@ -3748,7 +3738,9 @@ namespace relational
<< "init (obj, sts.image (), &db);";
init_value_extra ();
- free_statement_result_delayed ();
+
+ if (delay_freeing_statement_result)
+ os << "ar.free ();";
os << "load_ (sts, obj);"
<< "sts.load_delayed ();"
@@ -3786,15 +3778,21 @@ namespace relational
os << "if (!find_ (sts, id))" << endl
<< "return false;"
- << endl
- << "reference_cache_traits< object_type >::insert_guard ig (" << endl
+ << endl;
+
+ if (delay_freeing_statement_result)
+ os << "auto_result ar (sts.find_statement ());";
+
+ os << "reference_cache_traits< object_type >::insert_guard ig (" << endl
<< "reference_cache_traits< object_type >::insert (db, id, obj));"
<< endl
<< "callback (db, obj, callback_event::pre_load);"
<< "init (obj, sts.image (), &db);";
init_value_extra ();
- free_statement_result_delayed ();
+
+ if (delay_freeing_statement_result)
+ os << "ar.free ();";
os << "load_ (sts, obj);"
<< "sts.load_delayed ();"
@@ -3828,23 +3826,24 @@ namespace relational
<< "return false;"
<< endl;
+ if (delay_freeing_statement_result)
+ os << "auto_result ar (sts.find_statement ());"
+ << endl;
+
if (optimistic != 0)
{
os << "if (version (sts.image ()) == obj." <<
- optimistic->name () << ")"
- << "{";
-
- free_statement_result_delayed ();
-
- os << "return true;"
- << "}";
+ optimistic->name () << ")" << endl
+ << "return true;";
}
os << "callback (db, obj, callback_event::pre_load);"
<< "init (obj, sts.image (), &db);";
init_value_extra ();
- free_statement_result_delayed ();
+
+ if (delay_freeing_statement_result)
+ os << "ar.free ();";
os << "load_ (sts, obj);"
<< "sts.load_delayed ();"
@@ -3893,11 +3892,12 @@ namespace relational
<< "}"
<< "select_statement& st (sts.find_statement ());"
<< "st.execute ();"
- << "select_statement::result r (st.fetch ());";
+ << "auto_result ar (st);"
+ << "select_statement::result r (st.fetch ());"
+ << endl;
if (grow)
- os << endl
- << "if (r == select_statement::truncated)"
+ os << "if (r == select_statement::truncated)"
<< "{"
<< "if (grow (im, sts.select_image_truncated ()))" << endl
<< "im.version++;"
@@ -3911,10 +3911,20 @@ namespace relational
<< "}"
<< "}";
- free_statement_result_immediate ();
+ // If we are delaying, only free the result if it is empty.
+ //
+ if (delay_freeing_statement_result)
+ os << "if (r != select_statement::no_data)"
+ << "{"
+ << "ar.release ();"
+ << "return true;"
+ << "}"
+ << "else" << endl
+ << "return false;";
+ else
+ os << "return r != select_statement::no_data;";
- os << "return r != select_statement::no_data;"
- << "}";
+ os << "}";
}
// load_()
diff --git a/odb/relational/sqlite/context.cxx b/odb/relational/sqlite/context.cxx
index 46689bd..9f25fcc 100644
--- a/odb/relational/sqlite/context.cxx
+++ b/odb/relational/sqlite/context.cxx
@@ -78,6 +78,7 @@ namespace relational
generate_grow = true;
need_alias_as = true;
insert_send_auto_id = true;
+ delay_freeing_statement_result = false;
data_->bind_vector_ = "sqlite::bind*";
data_->truncated_vector_ = "bool*";