From ce696c26d2c9dd5a5813fd865082ab19ac49bcfa Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 6 Nov 2010 18:05:19 +0200 Subject: Add support for container persistence --- odb/context.cxx | 194 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 123 insertions(+), 71 deletions(-) (limited to 'odb/context.cxx') diff --git a/odb/context.cxx b/odb/context.cxx index 1eb597f..552bc28 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v3; see accompanying LICENSE file #include +#include using namespace std; @@ -119,30 +120,8 @@ context:: { } -static string -public_name_impl (semantics::data_member& m) -{ - string s (m.name ()); - size_t n (s.size ()); - - // Do basic processing: remove trailing and leading underscores - // as well as the 'm_' prefix. - // - // @@ What if the resulting names conflict? - // - size_t b (0), e (n - 1); - - if (n > 2 && s[0] == 'm' && s[1] == '_') - b += 2; - - for (; b <= e && s[b] == '_'; b++) ; - for (; e >= b && s[e] == '_'; e--) ; - - return b > e ? s : string (s, b, e - b + 1); -} - string context:: -table_name (semantics::type& t) const +table_name (semantics::class_& t) const { if (t.count ("table")) return t.get ("table"); @@ -151,40 +130,89 @@ table_name (semantics::type& t) const } string context:: -column_name (semantics::data_member& m) const +table_name (semantics::data_member& m, table_prefix const& p) const { - return m.count ("column") ? m.get ("column") : public_name_impl (m); + // If a custom table name was specified, then ignore the top-level + // table prefix. + // + if (m.count ("table")) + { + string const& name (m.get ("table")); + return p.level == 1 ? name : p.prefix + name; + } + + return p.prefix + public_name_db (m); } string context:: -column_type (semantics::data_member& m) const +column_name (semantics::data_member& m) const { - return m.get ("column-type"); + return m.count ("column") ? m.get ("column") : public_name_db (m); } string context:: -column_type_impl (semantics::data_member& m) const +column_name (semantics::data_member& m, string const& p, string const& d) const { - if (m.count ("type")) - return m.get ("type"); + string key (p + "-column"); + return m.count (key) ? m.get (key) : d; +} - semantics::type& t (m.type ()); +string context:: +column_type (semantics::data_member& m, string const& kp) const +{ + return kp.empty () + ? m.get ("column-type") + : m.get (kp + "-column-type"); +} - if (t.count ("type")) - return t.get ("type"); +string context::data:: +column_type_impl (semantics::type& t, + string const& type, + semantics::context* ctx) const +{ + if (!type.empty ()) + return type; // Don't use the name hint here so that we get the primary name (e.g., // ::std::string) instead of a user typedef (e.g., my_string). // string const& name (t.fq_name ()); - type_map_type::const_iterator i (data_->type_map_.find (name)); + type_map_type::const_iterator i (type_map_.find (name)); - if (i != data_->type_map_.end ()) - return m.count ("id") ? i->second.id_type : i->second.type; + if (i != type_map_.end ()) + return ctx != 0 && ctx->count ("id") ? i->second.id_type : i->second.type; return string (); } +static string +public_name_impl (semantics::data_member& m) +{ + string s (m.name ()); + size_t n (s.size ()); + + // Do basic processing: remove trailing and leading underscores + // as well as the 'm_' prefix. + // + // @@ What if the resulting names conflict? + // + size_t b (0), e (n - 1); + + if (n > 2 && s[0] == 'm' && s[1] == '_') + b += 2; + + for (; b <= e && s[b] == '_'; b++) ; + for (; e >= b && s[e] == '_'; e--) ; + + return b > e ? s : string (s, b, e - b + 1); +} + +string context:: +public_name_db (semantics::data_member& m) const +{ + return public_name_impl (m); +} + string context:: public_name (semantics::data_member& m) const { @@ -267,72 +295,96 @@ escape (string const& name) const namespace { - struct column_count_impl: traversal::class_ + struct column_count_impl: object_members_base { column_count_impl () - : member_ (*this) - { - *this >> names_ >> member_; - *this >> inherits_ >> *this; - } - - size_t - count () const + : count_ (0) { - return member_.count_; } virtual void traverse (semantics::class_& c) { if (c.count ("column-count")) - member_.count_ += c.get ("column-count"); + count_ += c.get ("column-count"); else { - size_t n (member_.count_); - inherits (c); - names (c); - c.set ("column-count", member_.count_ - n); + size_t n (count_); + object_members_base::traverse (c); + c.set ("column-count", count_ - n); } } + virtual void + simple (semantics::data_member&) + { + count_++; + } + private: - struct member: traversal::data_member + size_t count_; + }; +} + +size_t context:: +column_count (semantics::class_& c) +{ + if (!c.count ("column-count")) + { + column_count_impl t; + t.traverse (c); + } + + return c.get ("column-count"); +} + +namespace +{ + // Find id member. + // + struct id_member_impl: traversal::class_ + { + id_member_impl () + { + *this >> names_ >> member_; + } + + virtual void + traverse (semantics::class_& c) { - member (column_count_impl& cc): count_ (0), cc_ (cc) {} + member_.m_ = 0; + names (c); + c.set ("id-member", member_.m_); + } + private: + struct member: traversal::data_member + { virtual void traverse (semantics::data_member& m) { - if (m.count ("transient")) - return; - - if (context::comp_value (m.type ())) - cc_.dispatch (m.type ()); - else - count_++; + if (m.count ("id")) + m_ = &m; } - size_t count_; - column_count_impl& cc_; + semantics::data_member* m_; }; member member_; traversal::names names_; - - traversal::inherits inherits_; }; } -size_t context:: -column_count (semantics::class_& c) +semantics::data_member& context:: +id_member (semantics::class_& c) { - if (c.count ("column-count")) - return c.get ("column-count"); + if (!c.count ("id-member")) + { + id_member_impl t; + t.traverse (c); + } - column_count_impl t; - t.traverse (c); - return t.count (); + return *c.get ("id-member"); } // namespace -- cgit v1.1