aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-04-25 18:32:22 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-04-25 19:27:36 +0200
commit84d9c3f57c35cf9e99e89eeeb6cc4f1c52c3f5a2 (patch)
tree6467dcafcb98ada1695f27af90ba10966f2dcafb
parent2f1d254fb49e8cc8bd9ea2137758614e5825eaed (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.
-rw-r--r--odb/context.cxx24
-rw-r--r--odb/context.hxx9
-rw-r--r--odb/relational/mysql/context.cxx9
-rw-r--r--odb/relational/mysql/context.hxx2
-rw-r--r--odb/relational/sqlite/context.cxx4
-rw-r--r--odb/relational/sqlite/context.hxx2
-rw-r--r--odb/relational/type-processor.cxx89
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