From 8e69f40ab32dc8604b68f360ae30fa961ba036ee Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 4 Feb 2015 17:23:54 +0200 Subject: Implement object loading views See section 10.2 in the manual for details. --- odb/context.cxx | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 7 deletions(-) (limited to 'odb/context.cxx') diff --git a/odb/context.cxx b/odb/context.cxx index e56b412..44d7ef9 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,12 @@ add_space (string& s) string member_access:: translate (string const& obj, string const& val) const { + if (empty ()) + { + error (loc) << "non-empty " << kind << " expression required" << endl; + throw operation_failed (); + } + // This code is similar to translate_expression() from relations/source.cxx. // string r; @@ -2400,18 +2407,59 @@ namespace virtual void traverse_pointer (semantics::data_member& m, semantics::class_& c) { - size_t t (c_.total); + // Object pointers in views require special treatment. + // + if (view_member (m)) + { + using semantics::class_; + + column_count_type cc; + + if (class_* root = polymorphic (c)) + { + // For a polymorphic class we are going to load all the members + // from all the bases (i.e., equivalent to the first statement + // in the list of SELECT statements generated for the object). + // So our count should be the same as the first value in the + // generated column_counts array. + // + for (class_* b (&c);; b = &polymorphic_base (*b)) + { + column_count_type const& ccb (column_count (*b, section_)); + + cc.total += ccb.total - (b != root ? ccb.id : 0); + cc.separate_load += ccb.separate_load; + cc.soft += ccb.soft; - object_members_base::traverse_pointer (m, c); + if (b == root) + break; + } + } + else + cc = column_count (c, section_); - if (context::inverse (m)) + c_.total += cc.total - cc.separate_load; + + if (added (member_path_) != 0 || deleted (member_path_) != 0) + c_.soft += cc.total; + else + c_.soft += cc.soft; + } + else { - size_t n (c_.total - t); + size_t t (c_.total); + + object_members_base::traverse_pointer (m, c); - c_.inverse += n; + if (context::inverse (m)) + { + size_t n (c_.total - t); - if (separate_update (member_path_)) - c_.separate_update -= n; + c_.inverse += n; + + if (separate_update (member_path_)) + c_.separate_update -= n; + } } } -- cgit v1.1