diff options
Diffstat (limited to 'odb/relational/source.cxx')
-rw-r--r-- | odb/relational/source.cxx | 474 |
1 files changed, 358 insertions, 116 deletions
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx index 5a02703..7516801 100644 --- a/odb/relational/source.cxx +++ b/odb/relational/source.cxx @@ -18,8 +18,8 @@ traverse_object (type& c) using semantics::data_member; data_member* id (id_member (c)); - bool auto_id (id ? id->count ("auto") : false); - bool base_id (id ? &id->scope () != &c : false); // Comes from base. + bool auto_id (id && auto_ (*id)); + bool base_id (id && &id->scope () != &c); // Comes from base. member_access* id_ma (id ? &id->get<member_access> ("get") : 0); bool has_ptr (has_a (c, test_pointer)); @@ -49,7 +49,8 @@ traverse_object (type& c) } string const& type (class_fq_name (c)); - string traits ("access::object_traits< " + type + " >"); + string traits ("access::object_traits_impl< " + type + ", id_" + + db.string () + " >"); column_count_type const& cc (column_count (c)); os << "// " << class_name (c) << endl @@ -187,7 +188,7 @@ traverse_object (type& c) << "//" << endl << "if (--d != 0)" << "{" - << "if (object_traits<base_type>::grow (*i.base, " << + << "if (base_traits::grow (*i.base, " << "t + " << cols << "UL" << (poly_base != poly_root ? ", d" : "") << "))" << endl << "i.base->version++;" @@ -268,7 +269,7 @@ traverse_object (type& c) os << "// " << class_name (*poly_base) << " base" << endl << "//" << endl << "if (sk == statement_select)" << endl - << "object_traits<base_type>::"; + << "base_traits::"; if (poly_base == poly_root) os << "bind (b + n, *i.base, sk);"; @@ -360,7 +361,7 @@ traverse_object (type& c) os << "// " << class_name (*poly_base) << " base" << endl << "//" << endl << "if (--d != 0)" << endl - << "object_traits<base_type>::init (o, *i.base, db" << + << "base_traits::init (o, *i.base, db" << (poly_base != poly_root ? ", d" : "") << ");" << endl; } @@ -450,7 +451,8 @@ traverse_object (type& c) << "typeid (" << type << ")," << endl; if (poly_derived) - os << "&object_traits< " << class_fq_name (*poly_base) << " >::info"; + os << "&object_traits_impl< " << class_fq_name (*poly_base) << + ", id_" << db << " >::info"; else os << "0"; @@ -463,7 +465,7 @@ traverse_object (type& c) os << "," << endl << strlit (string (n, 2, string::npos)) << "," << endl << "&odb::create_impl< " << type << " >," << endl - << "&odb::dispatch_impl< " << type << " >," << endl; + << "&odb::dispatch_impl< " << type << ", id_" << db << " >," << endl; if (poly_derived) os << "&statements_type::delayed_loader"; @@ -883,7 +885,7 @@ traverse_object (type& c) // hierarchy. // if (poly_derived) - os << "object_traits<base_type>::persist (db, obj, false, false);" + os << "base_traits::persist (db, obj, false, false);" << endl; os << "image_type& im (sts.image ());" @@ -1135,7 +1137,7 @@ traverse_object (type& c) // if (!readonly_base) { - os << "object_traits<base_type>::update (db, obj, false, false);" + os << "base_traits::update (db, obj, false, false);" << endl; } else @@ -1550,7 +1552,7 @@ traverse_object (type& c) // Call our base last (we erase polymorphic objects from base // to derived in order not to trigger cascading deletes). // - os << "object_traits<base_type>::erase (db, id, false, false);" + os << "base_traits::erase (db, id, false, false);" << endl; } @@ -1787,7 +1789,7 @@ traverse_object (type& c) // Call our base last (we erase polymorphic objects from base // to derived in order not to trigger cascading deletes). // - os << "object_traits<base_type>::erase (db, obj, false, false);" + os << "base_traits::erase (db, obj, false, false);" << endl; } @@ -2349,7 +2351,7 @@ traverse_object (type& c) if (poly_derived) os << "if (--d != 0)" << endl - << "object_traits<base_type>::load_ (sts.base_statements (), obj" << + << "base_traits::load_ (sts.base_statements (), obj" << (poly_base != poly_root ? ", d" : "") << ");" << endl; @@ -2562,60 +2564,6 @@ traverse_object (type& c) if (options.generate_query ()) { - // query () - // - os << "result< " << traits << "::object_type >" << endl - << traits << "::" << endl - << "query (database&, const query_base_type& q)" - << "{" - << "using namespace " << db << ";" - << "using odb::details::shared;" - << "using odb::details::shared_ptr;" - << endl - << db << "::connection& conn (" << endl - << db << "::transaction::current ().connection ());" - << endl - << "statements_type& sts (" << endl - << "conn.statement_cache ().find_object<object_type> ());" - << endl; - - // Rebind the image if necessary. - // - os << "image_type& im (sts.image ());" - << "binding& imb (sts.select_image_binding (" << - (poly_derived ? "depth" : "") << "));" - << endl; - - if (poly_derived) - { - os << "if (imb.version == 0 ||" << endl - << "check_version (sts.select_image_versions (), im))" - << "{" - << "bind (imb.bind, 0, 0, im, statement_select);" - << "update_version (sts.select_image_versions ()," << endl - << "im," << endl - << "sts.select_image_bindings ());" - << "}"; - } - else - { - os << "if (im.version != sts.select_image_version () ||" << endl - << "imb.version == 0)" - << "{" - << "bind (imb.bind, im, statement_select);" - << "sts.select_image_version (im.version);" - << "imb.version++;" - << "}"; - } - - os << "shared_ptr<select_statement> st (" << endl - << "new (shared) select_statement (" << endl; - object_query_statement_ctor_args (c); - os << "));" << endl - << "st->execute ();"; - - post_query_ (c); - char const* result_type; if (poly) result_type = "polymorphic_object_result_impl<object_type>"; @@ -2624,13 +2572,73 @@ traverse_object (type& c) else result_type = "no_id_object_result_impl<object_type>"; - os << endl - << "shared_ptr< odb::" << result_type << " > r (" << endl - << "new (shared) " << db << "::" << result_type << " (" << endl - << "q, st, sts));" - << endl - << "return result<object_type> (r);" - << "}"; + // Unprepared. + // + if (!options.omit_unprepared ()) + { + // query () + // + os << "result< " << traits << "::object_type >" << endl + << traits << "::" << endl + << "query (database&, const query_base_type& q)" + << "{" + << "using namespace " << db << ";" + << "using odb::details::shared;" + << "using odb::details::shared_ptr;" + << endl + << db << "::connection& conn (" << endl + << db << "::transaction::current ().connection ());" + << endl + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_object<object_type> ());" + << endl; + + // Rebind the image if necessary. + // + os << "image_type& im (sts.image ());" + << "binding& imb (sts.select_image_binding (" << + (poly_derived ? "depth" : "") << "));" + << endl; + + if (poly_derived) + { + os << "if (imb.version == 0 ||" << endl + << "check_version (sts.select_image_versions (), im))" + << "{" + << "bind (imb.bind, 0, 0, im, statement_select);" + << "update_version (sts.select_image_versions ()," << endl + << "im," << endl + << "sts.select_image_bindings ());" + << "}"; + } + else + { + os << "if (im.version != sts.select_image_version () ||" << endl + << "imb.version == 0)" + << "{" + << "bind (imb.bind, im, statement_select);" + << "sts.select_image_version (im.version);" + << "imb.version++;" + << "}"; + } + + os << "q.init_parameters ();" + << "shared_ptr<select_statement> st (" << endl + << "new (shared) select_statement (" << endl; + object_query_statement_ctor_args (c, "q", false); + os << "));" << endl + << "st->execute ();"; + + post_query_ (c, true); + + os << endl + << "shared_ptr< odb::" << result_type << " > r (" << endl + << "new (shared) " << db << "::" << result_type << " (" << endl + << "q, st, sts));" + << endl + << "return result<object_type> (r);" + << "}"; + } // erase_query // @@ -2642,12 +2650,142 @@ traverse_object (type& c) << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << endl + << "q.init_parameters ();" << "delete_statement st (" << endl; object_erase_query_statement_ctor_args (c); os << ");" << endl << "return st.execute ();" << "}"; + + // Prepared. Very similar to unprepared but has some annoying variations + // that make it difficult to factor out something common. + // + if (options.generate_prepared ()) + { + os << "odb::details::shared_ptr<prepared_query_impl>" << endl + << traits << "::" << endl + << "prepare_query (connection& c, const char* n, " << + "const query_base_type& q)" + << "{" + << "using namespace " << db << ";" + << "using odb::details::shared;" + << "using odb::details::shared_ptr;" + << endl + << db << "::connection& conn (" << endl + << "static_cast<" << db << "::connection&> (c));" + << endl + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_object<object_type> ());" + << endl; + + // Rebind the image if necessary. + // + os << "image_type& im (sts.image ());" + << "binding& imb (sts.select_image_binding (" << + (poly_derived ? "depth" : "") << "));" + << endl; + + if (poly_derived) + { + os << "if (imb.version == 0 ||" << endl + << "check_version (sts.select_image_versions (), im))" + << "{" + << "bind (imb.bind, 0, 0, im, statement_select);" + << "update_version (sts.select_image_versions ()," << endl + << "im," << endl + << "sts.select_image_bindings ());" + << "}"; + } + else + { + os << "if (im.version != sts.select_image_version () ||" << endl + << "imb.version == 0)" + << "{" + << "bind (imb.bind, im, statement_select);" + << "sts.select_image_version (im.version);" + << "imb.version++;" + << "}"; + } + + os << "shared_ptr<" << db << "::prepared_query_impl> r (" << endl + << "new (shared) " << db << "::prepared_query_impl (conn));" + << "r->name = n;" + << "r->execute = &execute_query;" + << "r->query = q;" + << "r->stmt.reset (" << endl + << "new (shared) select_statement (" << endl; + object_query_statement_ctor_args (c, "r->query", true); + os << "));" + << endl + << "return r;" + << "}"; + + os << "odb::details::shared_ptr<result_impl>" << endl + << traits << "::" << endl + << "execute_query (prepared_query_impl& q)" + << "{" + << "using namespace " << db << ";" + << "using odb::details::shared;" + << "using odb::details::shared_ptr;" + << endl + << db << "::prepared_query_impl& pq (" << endl + << "static_cast<" << db << "::prepared_query_impl&> (q));" + << "shared_ptr<select_statement> st (" << endl + << "odb::details::inc_ref (" << endl + << "static_cast<select_statement*> (pq.stmt.get ())));" + << endl + << db << "::connection& conn (" << endl + << db << "::transaction::current ().connection ());" + << endl + << "// The connection used by the current transaction and the" << endl + << "// one used to prepare this statement must be the same." << endl + << "//" << endl + << "assert (&conn == &st->connection ());" + << endl + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_object<object_type> ());" + << endl; + + // Rebind the image if necessary. + // + os << "image_type& im (sts.image ());" + << "binding& imb (sts.select_image_binding (" << + (poly_derived ? "depth" : "") << "));" + << endl; + + if (poly_derived) + { + os << "if (imb.version == 0 ||" << endl + << "check_version (sts.select_image_versions (), im))" + << "{" + << "bind (imb.bind, 0, 0, im, statement_select);" + << "update_version (sts.select_image_versions ()," << endl + << "im," << endl + << "sts.select_image_bindings ());" + << "}"; + } + else + { + os << "if (im.version != sts.select_image_version () ||" << endl + << "imb.version == 0)" + << "{" + << "bind (imb.bind, im, statement_select);" + << "sts.select_image_version (im.version);" + << "imb.version++;" + << "}"; + } + + os << "pq.query.init_parameters ();" + << "st->execute ();"; + post_query_ (c, false); + + os << endl + << "return shared_ptr<result_impl> (" << endl + << "new (shared) " << db << "::" << result_type << " (" << endl + << "pq.query, st, sts));" + << "}"; + } } if (embedded_schema) @@ -2658,7 +2796,8 @@ void relational::source::class_:: traverse_view (type& c) { string const& type (class_fq_name (c)); - string traits ("access::view_traits< " + type + " >"); + string traits ("access::view_traits_impl< " + type + ", id_" + + db.string () + " >"); os << "// " << class_name (c) << endl << "//" << endl @@ -3391,54 +3530,157 @@ traverse_view (type& c) << "}"; } - // query () + // Unprepared. // - os << "result< " << traits << "::view_type >" << endl - << traits << "::" << endl - << "query (database&, const query_base_type& q)" - << "{" - << "using namespace " << db << ";" - << "using odb::details::shared;" - << "using odb::details::shared_ptr;" - << endl - << db << "::connection& conn (" << endl - << db << "::transaction::current ().connection ());" - << endl - << "view_statements< view_type >& sts (" << endl - << "conn.statement_cache ().find_view<view_type> ());" - << endl - << "image_type& im (sts.image ());" - << "binding& imb (sts.image_binding ());" - << endl - << "if (im.version != sts.image_version () || imb.version == 0)" - << "{" - << "bind (imb.bind, im);" - << "sts.image_version (im.version);" - << "imb.version++;" - << "}"; + if (!options.omit_unprepared ()) + { + os << "result< " << traits << "::view_type >" << endl + << traits << "::" << endl + << "query (database&, const query_base_type& q)" + << "{" + << "using namespace " << db << ";" + << "using odb::details::shared;" + << "using odb::details::shared_ptr;" + << endl + << db << "::connection& conn (" << endl + << db << "::transaction::current ().connection ());" + << endl + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_view<view_type> ());" + << endl + << "image_type& im (sts.image ());" + << "binding& imb (sts.image_binding ());" + << endl + << "if (im.version != sts.image_version () || imb.version == 0)" + << "{" + << "bind (imb.bind, im);" + << "sts.image_version (im.version);" + << "imb.version++;" + << "}"; - if (vq.kind == view_query::runtime) - os << "const query_base_type& qs (q);"; - else - os << "const query_base_type& qs (query_statement (q));"; + if (vq.kind == view_query::runtime) + os << "const query_base_type& qs (q);"; + else + os << "const query_base_type& qs (query_statement (q));"; - os << "shared_ptr<select_statement> st (" << endl - << "new (shared) select_statement (" << endl; + os << "qs.init_parameters ();" + << "shared_ptr<select_statement> st (" << endl + << "new (shared) select_statement (" << endl; + view_query_statement_ctor_args (c, "qs", false); + os << "));" << endl + << "st->execute ();"; - view_query_statement_ctor_args (c); + post_query_ (c, true); - os << "));" << endl - << "st->execute ();"; + os << endl + << "shared_ptr< odb::view_result_impl<view_type> > r (" << endl + << "new (shared) " << db << "::view_result_impl<view_type> (" << endl + << "qs, st, sts));" + << endl + << "return result<view_type> (r);" + << "}"; + } - post_query_ (c); + // Prepared. Very similar to unprepared but has some annoying variations + // that make it difficult to factor out something common. + // + if (options.generate_prepared ()) + { + os << "odb::details::shared_ptr<prepared_query_impl>" << endl + << traits << "::" << endl + << "prepare_query (connection& c, const char* n, " << + "const query_base_type& q)" + << "{" + << "using namespace " << db << ";" + << "using odb::details::shared;" + << "using odb::details::shared_ptr;" + << endl + << db << "::connection& conn (" << endl + << "static_cast<" << db << "::connection&> (c));" + << endl + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_view<view_type> ());" + << endl; - os << endl - << "shared_ptr< odb::view_result_impl<view_type> > r (" << endl - << "new (shared) " << db << "::view_result_impl<view_type> (" << endl - << "qs, st, sts));" - << endl - << "return result<view_type> (r);" - << "}"; + // Rebind the image if necessary. + // + os << "image_type& im (sts.image ());" + << "binding& imb (sts.image_binding ());" + << endl + << "if (im.version != sts.image_version () || imb.version == 0)" + << "{" + << "bind (imb.bind, im);" + << "sts.image_version (im.version);" + << "imb.version++;" + << "}"; + + os << "shared_ptr<" << db << "::prepared_query_impl> r (" << endl + << "new (shared) " << db << "::prepared_query_impl (conn));" + << "r->name = n;" + << "r->execute = &execute_query;"; + + if (vq.kind == view_query::runtime) + os << "r->query = q;"; + else + os << "r->query = query_statement (q);"; + + os << "r->stmt.reset (" << endl + << "new (shared) select_statement (" << endl; + view_query_statement_ctor_args (c, "r->query", true); + os << "));" + << endl + << "return r;" + << "}"; + + os << "odb::details::shared_ptr<result_impl>" << endl + << traits << "::" << endl + << "execute_query (prepared_query_impl& q)" + << "{" + << "using namespace " << db << ";" + << "using odb::details::shared;" + << "using odb::details::shared_ptr;" + << endl + << db << "::prepared_query_impl& pq (" << endl + << "static_cast<" << db << "::prepared_query_impl&> (q));" + << "shared_ptr<select_statement> st (" << endl + << "odb::details::inc_ref (" << endl + << "static_cast<select_statement*> (pq.stmt.get ())));" + << endl + << db << "::connection& conn (" << endl + << db << "::transaction::current ().connection ());" + << endl + << "// The connection used by the current transaction and the" << endl + << "// one used to prepare this statement must be the same." << endl + << "//" << endl + << "assert (&conn == &st->connection ());" + << endl + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_view<view_type> ());" + << endl; + + // Rebind the image if necessary. + // + os << "image_type& im (sts.image ());" + << "binding& imb (sts.image_binding ());" + << endl + << "if (im.version != sts.image_version () || imb.version == 0)" + << "{" + << "bind (imb.bind, im);" + << "sts.image_version (im.version);" + << "imb.version++;" + << "}"; + + os << "pq.query.init_parameters ();" + << "st->execute ();"; + + post_query_ (c, false); + + os << endl + << "return shared_ptr<result_impl> (" << endl + << "new (shared) " << db << "::view_result_impl<view_type> (" << endl + << "pq.query, st, sts));" + << "}"; + } } namespace relational |