aboutsummaryrefslogtreecommitdiff
path: root/odb/relational/oracle
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-03-21 08:36:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-04-23 16:50:56 +0200
commit8d89bf37dd4ef3cb7373e1841ff57a53916fff0d (patch)
tree704b7de0338eba0e008a96a09b6d57e86846d1b1 /odb/relational/oracle
parent68ff21c56fb287790440208907ad2a851a108f89 (diff)
Polymorphic inheritance support
Diffstat (limited to 'odb/relational/oracle')
-rw-r--r--odb/relational/oracle/context.cxx4
-rw-r--r--odb/relational/oracle/context.hxx1
-rw-r--r--odb/relational/oracle/header.cxx33
-rw-r--r--odb/relational/oracle/source.cxx154
4 files changed, 52 insertions, 140 deletions
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<data*> (root_context::data_.get ()), m),
data_ (static_cast<data*> (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 <sstream>
-
#include <odb/relational/source.hxx>
#include <odb/relational/oracle/common.hxx>
@@ -63,127 +61,17 @@ namespace relational
// bind
//
- struct bind_member: relational::bind_member, member_base
+ struct bind_member: relational::bind_member_impl<sql_type>,
+ 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> 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