aboutsummaryrefslogtreecommitdiff
path: root/odb/relational/mysql/context.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational/mysql/context.cxx')
-rw-r--r--odb/relational/mysql/context.cxx95
1 files changed, 68 insertions, 27 deletions
diff --git a/odb/relational/mysql/context.cxx b/odb/relational/mysql/context.cxx
index ec1a967..1e44b34 100644
--- a/odb/relational/mysql/context.cxx
+++ b/odb/relational/mysql/context.cxx
@@ -106,6 +106,13 @@ namespace relational
{
}
+ string const& context::
+ convert_expr (string const& sqlt, semantics::data_member& m, bool to)
+ {
+ sql_type const& t (parse_sql_type (sqlt, m));
+ return to ? t.to : t.from;
+ }
+
string context::
quote_id_impl (qname const& id) const
{
@@ -319,20 +326,31 @@ namespace relational
//
sql_type const& context::
- parse_sql_type (string const& t, semantics::data_member& m)
+ parse_sql_type (string const& t, semantics::data_member& m, bool custom)
{
- // If this proves to be too expensive, we can maintain a
- // cache of parsed types.
+ // If this proves to be too expensive, we can maintain a cache of
+ // parsed types across contexts.
//
data::sql_type_cache::iterator i (data_->sql_type_cache_.find (t));
- if (i != data_->sql_type_cache_.end ())
- return i->second;
+ if (i != data_->sql_type_cache_.end ()
+ && (custom ? i->second.custom_cached : i->second.straight_cached))
+ {
+ return (custom ? i->second.custom : i->second.straight);
+ }
else
{
try
{
- return (data_->sql_type_cache_[t] = parse_sql_type (t));
+ sql_type st (
+ parse_sql_type (
+ t,
+ custom ? &unit.get<custom_db_types> ("custom-db-types") : 0));
+
+ if (custom)
+ return data_->sql_type_cache_[t].cache_custom (st);
+ else
+ return data_->sql_type_cache_[t].cache_straight (st);
}
catch (invalid_sql_type const& e)
{
@@ -344,12 +362,41 @@ namespace relational
}
}
+ inline sql_type
+ error (bool fail, string const& m)
+ {
+ if (!fail)
+ return sql_type ();
+ else
+ throw context::invalid_sql_type (m);
+ }
+
sql_type context::
- parse_sql_type (string const& sqlt)
+ parse_sql_type (string sqlt, custom_db_types const* ct)
{
try
{
sql_type r;
+
+ // First run the type through the custom mapping, if requested.
+ //
+ if (ct != 0)
+ {
+ for (custom_db_types::const_iterator i (ct->begin ());
+ i != ct->end (); ++i)
+ {
+ custom_db_type const& t (*i);
+
+ if (t.type.match (sqlt))
+ {
+ r.to = t.type.replace (sqlt, t.to);
+ r.from = t.type.replace (sqlt, t.from);
+ sqlt = t.type.replace (sqlt, t.as);
+ break;
+ }
+ }
+ }
+
sql_lexer l (sqlt);
// While most type names use single identifier, there are
@@ -599,11 +646,11 @@ namespace relational
{
if (tt == sql_token::t_identifier)
{
- throw invalid_sql_type (
- "unknown MySQL type '" + t.identifier () + "'");
+ return error (ct, "unknown MySQL type '" + t.identifier () +
+ "'");
}
else
- throw invalid_sql_type ("expected MySQL type name");
+ return error (ct, "expected MySQL type name");
}
// Fall through.
@@ -624,9 +671,8 @@ namespace relational
{
if (t.type () != sql_token::t_string_lit)
{
- throw invalid_sql_type (
- "string literal expected in MySQL ENUM or SET "
- "declaration");
+ return error (ct, "string literal expected in MySQL "
+ "ENUM or SET declaration");
}
if (r.type == sql_type::ENUM)
@@ -638,8 +684,8 @@ namespace relational
break;
else if (t.punctuation () != sql_token::p_comma)
{
- throw invalid_sql_type (
- "comma expected in MySQL ENUM or SET declaration");
+ return error (ct, "comma expected in MySQL ENUM or "
+ "SET declaration");
}
t = l.next ();
@@ -649,8 +695,8 @@ namespace relational
{
if (t.type () != sql_token::t_int_lit)
{
- throw invalid_sql_type (
- "integer range expected in MySQL type declaration");
+ return error (ct, "integer range expected in MySQL type "
+ "declaration");
}
unsigned int v;
@@ -658,9 +704,8 @@ namespace relational
if (!(is >> v && is.eof ()))
{
- throw invalid_sql_type (
- "invalid range value '" + t.literal () + "' in MySQL "
- "type declaration");
+ return error (ct, "invalid range value '" + t.literal () +
+ "' in MySQL type declaration");
}
r.range = true;
@@ -687,8 +732,7 @@ namespace relational
if (t.punctuation () != sql_token::p_rparen)
{
- throw invalid_sql_type (
- "expected ')' in MySQL type declaration");
+ return error (ct, "expected ')' in MySQL type declaration");
}
s = parse_sign;
@@ -741,9 +785,7 @@ namespace relational
}
if (r.type == sql_type::invalid)
- {
- throw invalid_sql_type ("incomplete MySQL type declaration");
- }
+ return error (ct, "incomplete MySQL type declaration");
// If range is omitted for CHAR or BIT types, it defaults to 1.
//
@@ -757,8 +799,7 @@ namespace relational
}
catch (sql_lexer::invalid_input const& e)
{
- throw invalid_sql_type (
- "invalid MySQL type declaration: " + e.message);
+ return error (ct, "invalid MySQL type declaration: " + e.message);
}
}
}