diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-04-25 18:32:22 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-04-25 19:27:36 +0200 |
commit | 84d9c3f57c35cf9e99e89eeeb6cc4f1c52c3f5a2 (patch) | |
tree | 6467dcafcb98ada1695f27af90ba10966f2dcafb /odb | |
parent | 2f1d254fb49e8cc8bd9ea2137758614e5825eaed (diff) |
Add support for mapping to database types based on type aliases
This allows us to, for example, always map size_t to 64-bit type.
The current implementation does not work for containers. It is not
clear whether it will be possible to make it work using the GCC AST.
Diffstat (limited to 'odb')
-rw-r--r-- | odb/context.cxx | 24 | ||||
-rw-r--r-- | odb/context.hxx | 9 | ||||
-rw-r--r-- | odb/relational/mysql/context.cxx | 9 | ||||
-rw-r--r-- | odb/relational/mysql/context.hxx | 2 | ||||
-rw-r--r-- | odb/relational/sqlite/context.cxx | 4 | ||||
-rw-r--r-- | odb/relational/sqlite/context.hxx | 2 | ||||
-rw-r--r-- | odb/relational/type-processor.cxx | 89 |
7 files changed, 101 insertions, 38 deletions
diff --git a/odb/context.cxx b/odb/context.cxx index d281090..00edd8d 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -264,23 +264,29 @@ column_type (semantics::data_member& m, string const& kp) string context:: database_type_impl (semantics::type& t, - string const& type, + semantics::names* hint, semantics::context& ctx, column_type_flags f) { - // @@ If I handle additional qualifiers (e.g., NOT NULL, AUTO_INCREMENT) - // separately, then I won't need to pass custom type anymore. + type_map_type::const_iterator end (data_->type_map_.end ()), i (end); + + // First check the hinted name. This allows us to handle things like + // size_t which is nice to map to the same type irrespective of the + // actual type. Since this type can be an alias for the one we are + // interested in, go into nested hints. // - if (!type.empty ()) - return type; + for (; hint != 0 && i == end; hint = hint->hint ()) + { + i = data_->type_map_.find (t.fq_name (hint)); + } - // Don't use the name hint here so that we get the primary name (e.g., + // If the hinted name didn't work, try 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)); + if (i == end) + i = data_->type_map_.find (t.fq_name ()); - if (i != data_->type_map_.end ()) + if (i != end) { string r (ctx.count ("id") ? i->second.id_type : i->second.type); diff --git a/odb/context.hxx b/odb/context.hxx index 9878bcb..84e9f70 100644 --- a/odb/context.hxx +++ b/odb/context.hxx @@ -400,16 +400,15 @@ protected: // static column_type_flags const ctf_default_null = 0x01; - // Return empty string if there is no mapping. The second argument - // is the custom type or empty string if it is not specified. + // Return empty string if there is no mapping. // string database_type (semantics::type& t, - string const& type, + semantics::names* hint, semantics::context& c, column_type_flags f) { - return current ().database_type_impl (t, type, c, f); + return current ().database_type_impl (t, hint, c, f); } // The default implementation uses the type map (populated by the database- @@ -417,7 +416,7 @@ protected: // virtual string database_type_impl (semantics::type&, - string const& type, + semantics::names*, semantics::context&, column_type_flags); diff --git a/odb/relational/mysql/context.cxx b/odb/relational/mysql/context.cxx index 4e31361..aa47b78 100644 --- a/odb/relational/mysql/context.cxx +++ b/odb/relational/mysql/context.cxx @@ -50,7 +50,10 @@ namespace relational {"float", "FLOAT", 0}, {"double", "DOUBLE", 0}, - {"::std::string", "TEXT", "VARCHAR (255)"} + {"::std::string", "TEXT", "VARCHAR (255)"}, + + {"::size_t", "BIGINT UNSIGNED", 0}, + {"::std::size_t", "BIGINT UNSIGNED", 0} }; } @@ -232,11 +235,11 @@ namespace relational string context:: database_type_impl (semantics::type& t, - string const& type, + semantics::names* hint, semantics::context& ctx, column_type_flags f) { - string r (base_context::database_type_impl (t, type, ctx, f)); + string r (base_context::database_type_impl (t, hint, ctx, f)); if (!r.empty ()) return r; diff --git a/odb/relational/mysql/context.hxx b/odb/relational/mysql/context.hxx index cada5d9..019b878 100644 --- a/odb/relational/mysql/context.hxx +++ b/odb/relational/mysql/context.hxx @@ -98,7 +98,7 @@ namespace relational protected: virtual string database_type_impl (semantics::type&, - string const& type, + semantics::names*, semantics::context&, column_type_flags); diff --git a/odb/relational/sqlite/context.cxx b/odb/relational/sqlite/context.cxx index b2b3033..b026822 100644 --- a/odb/relational/sqlite/context.cxx +++ b/odb/relational/sqlite/context.cxx @@ -198,11 +198,11 @@ namespace relational string context:: database_type_impl (semantics::type& t, - string const& type, + semantics::names* hint, semantics::context& ctx, column_type_flags f) { - string r (base_context::database_type_impl (t, type, ctx, f)); + string r (base_context::database_type_impl (t, hint, ctx, f)); if (!r.empty ()) return r; diff --git a/odb/relational/sqlite/context.hxx b/odb/relational/sqlite/context.hxx index 621c549..c625069 100644 --- a/odb/relational/sqlite/context.hxx +++ b/odb/relational/sqlite/context.hxx @@ -50,7 +50,7 @@ namespace relational protected: virtual string database_type_impl (semantics::type&, - string const& type, + semantics::names*, semantics::context&, column_type_flags); public: diff --git a/odb/relational/type-processor.cxx b/odb/relational/type-processor.cxx index 5c86b10..f7b0b2a 100644 --- a/odb/relational/type-processor.cxx +++ b/odb/relational/type-processor.cxx @@ -130,12 +130,15 @@ namespace relational if (type.empty () && idt.count ("type")) type = idt.get<string> ("type"); - column_type_flags f (ctf_none); + if (type.empty ()) + { + column_type_flags f (ctf_none); - if (null_pointer (m)) - f |= ctf_default_null; + if (null_pointer (m)) + f |= ctf_default_null; - type = database_type (idt, type, id, f); + type = database_type (idt, id.belongs ().hint (), id, f); + } } else { @@ -145,7 +148,8 @@ namespace relational if (type.empty () && t.count ("type")) type = t.get<string> ("type"); - type = database_type (t, type, m, ctf_none); + if (type.empty ()) + type = database_type (t, m.belongs ().hint (), m, ctf_none); } if (!type.empty ()) @@ -176,6 +180,7 @@ namespace relational void process_container_value (semantics::type& t, + semantics::names* hint, semantics::data_member& m, string const& prefix, bool obj_ptr) @@ -215,19 +220,23 @@ namespace relational if (type.empty () && idt.count ("type")) type = idt.get<string> ("type"); - column_type_flags f (ctf_none); + if (type.empty ()) + { + column_type_flags f (ctf_none); - if (null_pointer (m, prefix)) - f |= ctf_default_null; + if (null_pointer (m, prefix)) + f |= ctf_default_null; - type = database_type (idt, type, id, f); + type = database_type (idt, id.belongs ().hint (), id, f); + } } else { if (type.empty () && t.count ("type")) type = t.get<string> ("type"); - type = database_type (t, type, m, ctf_none); + if (type.empty ()) + type = database_type (t, hint, m, ctf_none); } if (!type.empty ()) @@ -270,16 +279,27 @@ namespace relational semantics::type* it (0); semantics::type* kt (0); + semantics::names* vh (0); + semantics::names* ih (0); + semantics::names* kh (0); + if (t.count ("container")) { ck = t.get<container_kind_type> ("container-kind"); vt = t.get<semantics::type*> ("value-tree-type"); + vh = t.get<semantics::names*> ("value-tree-hint"); if (ck == ck_ordered) + { it = t.get<semantics::type*> ("index-tree-type"); + ih = t.get<semantics::names*> ("index-tree-hint"); + } if (ck == ck_map || ck == ck_multimap) + { kt = t.get<semantics::type*> ("key-tree-type"); + kh = t.get<semantics::names*> ("key-tree-hint"); + } } else { @@ -358,8 +378,19 @@ namespace relational throw generation_failed (); tree type (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); - vt = &dynamic_cast<semantics::type&> (*unit.find (type)); + + // Find the hint. + // + for (tree ot (DECL_ORIGINAL_TYPE (decl)); + ot != 0; + ot = decl ? DECL_ORIGINAL_TYPE (decl) : 0) + { + if ((vh = unit.find_hint (ot))) + break; + + decl = TYPE_NAME (ot); + } } catch (generation_failed const&) { @@ -371,7 +402,7 @@ namespace relational } t.set ("value-tree-type", vt); - + t.set ("value-tree-hint", vh); // Get the index type for ordered containers. // @@ -387,8 +418,19 @@ namespace relational throw generation_failed (); tree type (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); - it = &dynamic_cast<semantics::type&> (*unit.find (type)); + + // Find the hint. + // + for (tree ot (DECL_ORIGINAL_TYPE (decl)); + ot != 0; + ot = decl ? DECL_ORIGINAL_TYPE (decl) : 0) + { + if ((ih = unit.find_hint (ot))) + break; + + decl = TYPE_NAME (ot); + } } catch (generation_failed const&) { @@ -400,6 +442,7 @@ namespace relational } t.set ("index-tree-type", it); + t.set ("index-tree-hint", ih); } // Get the key type for maps. @@ -416,8 +459,19 @@ namespace relational throw generation_failed (); tree type (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); - kt = &dynamic_cast<semantics::type&> (*unit.find (type)); + + // Find the hint. + // + for (tree ot (DECL_ORIGINAL_TYPE (decl)); + ot != 0; + ot = decl ? DECL_ORIGINAL_TYPE (decl) : 0) + { + if ((kh = unit.find_hint (ot))) + break; + + decl = TYPE_NAME (ot); + } } catch (generation_failed const&) { @@ -429,6 +483,7 @@ namespace relational } t.set ("key-tree-type", kt); + t.set ("key-tree-hint", kh); } } @@ -437,13 +492,13 @@ namespace relational m.set ("id-tree-type", &id_tree_type); m.set ("id-column-type", &id_column_type); - process_container_value (*vt, m, "value", true); + process_container_value (*vt, vh, m, "value", true); if (it != 0) - process_container_value (*it, m, "index", false); + process_container_value (*it, ih, m, "index", false); if (kt != 0) - process_container_value (*kt, m, "key", false); + process_container_value (*kt, kh, m, "key", false); // If this is an inverse side of a bidirectional object relationship // and it is an ordered container, mark it as unordred since there is |