From 19131a419b35e409e6b65fc47ff31f7742ff54f3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 7 Mar 2012 10:21:09 +0200 Subject: Use RAII to free select statement results --- odb/relational/source.hxx | 106 +++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 48 deletions(-) (limited to 'odb/relational/source.hxx') 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_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_() -- cgit v1.1