From 8d89bf37dd4ef3cb7373e1841ff57a53916fff0d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 21 Mar 2012 08:36:21 +0200 Subject: Polymorphic inheritance support --- odb/relational/oracle/context.cxx | 4 +- odb/relational/oracle/context.hxx | 1 + odb/relational/oracle/header.cxx | 33 ++++---- odb/relational/oracle/source.cxx | 154 +++++++------------------------------- 4 files changed, 52 insertions(+), 140 deletions(-) (limited to 'odb/relational/oracle') diff --git a/odb/relational/oracle/context.cxx b/odb/relational/oracle/context.cxx index 2fa566c..a44e3ee 100644 --- a/odb/relational/oracle/context.cxx +++ b/odb/relational/oracle/context.cxx @@ -68,8 +68,9 @@ namespace relational context (ostream& os, semantics::unit& u, options_type const& ops, + features_type& f, sema_rel::model* m) - : root_context (os, u, ops, data_ptr (new (shared) data (os))), + : root_context (os, u, ops, f, data_ptr (new (shared) data (os))), base_context (static_cast (root_context::data_.get ()), m), data_ (static_cast (base_context::data_)) { @@ -80,6 +81,7 @@ namespace relational need_alias_as = false; insert_send_auto_id = true; delay_freeing_statement_result = false; + need_image_clone = true; data_->bind_vector_ = "oracle::bind*"; // Populate the C++ type to DB type map. diff --git a/odb/relational/oracle/context.hxx b/odb/relational/oracle/context.hxx index 37716f0..6b7e968 100644 --- a/odb/relational/oracle/context.hxx +++ b/odb/relational/oracle/context.hxx @@ -112,6 +112,7 @@ namespace relational context (std::ostream&, semantics::unit&, options_type const&, + features_type&, sema_rel::model*); static context& diff --git a/odb/relational/oracle/header.cxx b/odb/relational/oracle/header.cxx index 91f1d93..3eca2e2 100644 --- a/odb/relational/oracle/header.cxx +++ b/odb/relational/oracle/header.cxx @@ -22,24 +22,31 @@ namespace relational virtual void image_extra (type& c) { - if (!(composite (c) || abstract (c))) + if (!(composite (c) || (abstract (c) && !polymorphic (c)))) { - bool gc (options.generate_query ()); + type* poly_root (polymorphic (c)); - if (gc) - os << "oracle::change_callback change_callback_;" - << endl; + // If this is a polymorphic type, only add callback to the root. + // + if (poly_root == 0 || poly_root == &c) + { + bool gc (options.generate_query ()); - os << "oracle::change_callback*" << endl - << "change_callback ()" - << "{"; + if (gc) + os << "oracle::change_callback change_callback_;" + << endl; - if (gc) - os << "return &change_callback_;"; - else - os << "return 0;"; + os << "oracle::change_callback*" << endl + << "change_callback ()" + << "{"; - os << "}"; + if (gc) + os << "return &change_callback_;"; + else + os << "return 0;"; + + os << "}"; + } } } }; diff --git a/odb/relational/oracle/source.cxx b/odb/relational/oracle/source.cxx index 1d7d81f..4ce6e2a 100644 --- a/odb/relational/oracle/source.cxx +++ b/odb/relational/oracle/source.cxx @@ -2,8 +2,6 @@ // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC // license : GNU GPL v3; see accompanying LICENSE file -#include - #include #include @@ -63,127 +61,17 @@ namespace relational // bind // - struct bind_member: relational::bind_member, member_base + struct bind_member: relational::bind_member_impl, + member_base { bind_member (base const& x) - : member_base::base (x), // virtual base - base (x), + : member_base::base (x), // virtual base + member_base::base_impl (x), // virtual base + base_impl (x), member_base (x) { } - virtual bool - pre (member_info& mi) - { - if (container (mi)) - return false; - - ostringstream ostr; - ostr << "b[n]"; - b = ostr.str (); - - arg = arg_override_.empty () ? string ("i") : arg_override_; - - if (var_override_.empty ()) - { - os << "// " << mi.m.name () << endl - << "//" << endl; - - if (inverse (mi.m, key_prefix_) || version (mi.m)) - os << "if (sk == statement_select)" - << "{"; - // If the whole class is readonly, then we will never be - // called with sk == statement_update. - // - else if (!readonly (*context::top_object)) - { - semantics::class_* c; - - if (id (mi.m) || - readonly (mi.m) || - ((c = composite (mi.t)) && readonly (*c))) - os << "if (sk != statement_update)" - << "{"; - } - } - - return true; - } - - virtual void - post (member_info& mi) - { - if (var_override_.empty ()) - { - semantics::class_* c; - - if ((c = composite (mi.t))) - { - bool ro (readonly (*c)); - column_count_type const& cc (column_count (*c)); - - os << "n += " << cc.total << "UL"; - - // select = total - // insert = total - inverse - // update = total - inverse - readonly - // - if (cc.inverse != 0 || (!ro && cc.readonly != 0)) - { - os << " - (" << endl - << "sk == statement_select ? 0 : "; - - if (cc.inverse != 0) - os << cc.inverse << "UL"; - - if (!ro && cc.readonly != 0) - { - if (cc.inverse != 0) - os << " + "; - - os << "(" << endl - << "sk == statement_insert ? 0 : " << - cc.readonly << "UL)"; - } - - os << ")"; - } - - os << ";"; - } - else - os << "n++;"; - - bool block (false); - - // The same logic as in pre(). - // - if (inverse (mi.m, key_prefix_) || version (mi.m)) - block = true; - else if (!readonly (*context::top_object)) - { - semantics::class_* c; - - if (id (mi.m) || - readonly (mi.m) || - ((c = composite (mi.t)) && readonly (*c))) - block = true; - } - - if (block) - os << "}"; - else - os << endl; - } - } - - virtual void - traverse_composite (member_info& mi) - { - os << "composite_value_traits< " << mi.fq_type () << - " >::bind (b + n, " << arg << "." << mi.var << "value, sk);"; - } - virtual void traverse_int32 (member_info& mi) { @@ -305,10 +193,6 @@ namespace relational << b << ".callback = &" << arg << "." << mi.var << "callback;" << endl; } - - private: - string b; - string arg; }; entry bind_member_; @@ -632,16 +516,34 @@ namespace relational virtual void init_image_pre (type& c) { - if (options.generate_query () && !(composite (c) || abstract (c))) - os << "if (i.change_callback_.callback != 0)" << endl - << "(i.change_callback_.callback) (i.change_callback_.context);" - << endl; + if (options.generate_query () && + !(composite (c) || (abstract (c) && !polymorphic (c)))) + { + type* poly_root (polymorphic (c)); + bool poly_derived (poly_root != 0 && poly_root != &c); + + if (poly_derived) + os << "{" + << "root_traits::image_type& ri (root_image (i));" + << endl; + + string i (poly_derived ? "ri" : "i"); + + os << "if (" << i << ".change_callback_.callback != 0)" << endl + << "(" << i << ".change_callback_.callback) (" << + i << ".change_callback_.context, 0);"; + + if (poly_derived) + os << "}"; + else + os << endl; + } } virtual void init_value_extra () { - os << "sts.find_statement ().stream_result ();"; + os << "st.stream_result ();"; } virtual void -- cgit v1.1