summaryrefslogtreecommitdiff
path: root/odb/relational
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational')
-rw-r--r--odb/relational/mysql/context.cxx10
-rw-r--r--odb/relational/mysql/context.hxx5
-rw-r--r--odb/relational/mysql/schema.cxx18
-rw-r--r--odb/relational/mysql/source.cxx4
-rw-r--r--odb/relational/pgsql/context.cxx12
-rw-r--r--odb/relational/pgsql/context.hxx5
-rw-r--r--odb/relational/pgsql/source.cxx4
-rw-r--r--odb/relational/schema.hxx8
-rw-r--r--odb/relational/sqlite/context.cxx12
-rw-r--r--odb/relational/sqlite/context.hxx6
-rw-r--r--odb/relational/sqlite/source.cxx4
-rw-r--r--odb/relational/type-processor.cxx93
12 files changed, 110 insertions, 71 deletions
diff --git a/odb/relational/mysql/context.cxx b/odb/relational/mysql/context.cxx
index e9446c2..431470a 100644
--- a/odb/relational/mysql/context.cxx
+++ b/odb/relational/mysql/context.cxx
@@ -234,12 +234,9 @@ namespace relational
}
string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f)
+ database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
- string r (base_context::database_type_impl (t, hint, ctx, f));
+ string r (base_context::database_type_impl (t, hint, id));
if (!r.empty ())
return r;
@@ -290,9 +287,6 @@ namespace relational
if (e->unsigned_ ())
r += " UNSIGNED";
}
-
- if ((f & ctf_default_null) == 0)
- r += " NOT NULL";
}
return r;
diff --git a/odb/relational/mysql/context.hxx b/odb/relational/mysql/context.hxx
index 019b878..00ebe57 100644
--- a/odb/relational/mysql/context.hxx
+++ b/odb/relational/mysql/context.hxx
@@ -97,10 +97,7 @@ namespace relational
protected:
virtual string
- database_type_impl (semantics::type&,
- semantics::names*,
- semantics::context&,
- column_type_flags);
+ database_type_impl (semantics::type&, semantics::names*, bool);
public:
virtual
diff --git a/odb/relational/mysql/schema.cxx b/odb/relational/mysql/schema.cxx
index 0b44c53..3848c75 100644
--- a/odb/relational/mysql/schema.cxx
+++ b/odb/relational/mysql/schema.cxx
@@ -37,11 +37,27 @@ namespace relational
}
};
- struct object_columns: relational::object_columns
+ struct object_columns: relational::object_columns, context
{
object_columns (base const& x): base (x) {}
virtual void
+ null (semantics::data_member& m)
+ {
+ if (!context::null (m, prefix_))
+ os << " NOT NULL";
+ else
+ {
+ // MySQL TIMESTAMP is by default NOT NULL. If we want it
+ // to contain NULL values, we need to explicitly declare
+ // the column as NULL.
+ //
+ if (column_sql_type (m, prefix_).type == sql_type::TIMESTAMP)
+ os << " NULL";
+ }
+ }
+
+ virtual void
constraints (semantics::data_member& m)
{
base::constraints (m);
diff --git a/odb/relational/mysql/source.cxx b/odb/relational/mysql/source.cxx
index 17bffdc..d3b4129 100644
--- a/odb/relational/mysql/source.cxx
+++ b/odb/relational/mysql/source.cxx
@@ -588,7 +588,7 @@ namespace relational
{
os << "}";
- if (!null_pointer (mi.m, key_prefix_))
+ if (!null (mi.m, key_prefix_))
os << "else" << endl
<< "throw null_pointer ();";
}
@@ -786,7 +786,7 @@ namespace relational
<< endl
<< "if (i." << mi.var << "null)" << endl;
- if (null_pointer (mi.m, key_prefix_))
+ if (null (mi.m, key_prefix_))
os << member << " = ptr_traits::pointer_type ();";
else
os << "throw null_pointer ();";
diff --git a/odb/relational/pgsql/context.cxx b/odb/relational/pgsql/context.cxx
index 5a6b158..6c6c5a0 100644
--- a/odb/relational/pgsql/context.cxx
+++ b/odb/relational/pgsql/context.cxx
@@ -211,12 +211,9 @@ namespace relational
}
string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f)
+ database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
- string r (base_context::database_type_impl (t, hint, ctx, f));
+ string r (base_context::database_type_impl (t, hint, id));
if (!r.empty ())
return r;
@@ -224,13 +221,8 @@ namespace relational
using semantics::enum_;
if (t.is_a<semantics::enum_> ())
- {
r = "INTEGER";
- if ((f & ctf_default_null) == 0)
- r += " NOT NULL";
- }
-
return r;
}
diff --git a/odb/relational/pgsql/context.hxx b/odb/relational/pgsql/context.hxx
index 66d9318..a4fbc00 100644
--- a/odb/relational/pgsql/context.hxx
+++ b/odb/relational/pgsql/context.hxx
@@ -85,10 +85,7 @@ namespace relational
protected:
virtual string
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f);
+ database_type_impl (semantics::type& t, semantics::names* hint, bool);
public:
virtual
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index 0ed6890..3b7664d 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -502,7 +502,7 @@ namespace relational
{
os << "}";
- if (!null_pointer (mi.m, key_prefix_))
+ if (!null (mi.m, key_prefix_))
os << "else" << endl
<< "throw null_pointer ();";
}
@@ -674,7 +674,7 @@ namespace relational
<< endl
<< "if (i." << mi.var << "null)" << endl;
- if (null_pointer (mi.m, key_prefix_))
+ if (null (mi.m, key_prefix_))
os << member << " = ptr_traits::pointer_type ();";
else
os << "throw null_pointer ();";
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index b9243df..9d64276 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -189,6 +189,7 @@ namespace relational
os << " " << quote_id (name) << " ";
type (m);
+ null (m);
constraints (m);
reference (m);
@@ -202,6 +203,13 @@ namespace relational
}
virtual void
+ null (semantics::data_member& m)
+ {
+ if (!context::null (m, prefix_))
+ os << " NOT NULL";
+ }
+
+ virtual void
constraints (semantics::data_member& m)
{
if (m.count ("id"))
diff --git a/odb/relational/sqlite/context.cxx b/odb/relational/sqlite/context.cxx
index b026822..4d00621 100644
--- a/odb/relational/sqlite/context.cxx
+++ b/odb/relational/sqlite/context.cxx
@@ -197,12 +197,9 @@ namespace relational
}
string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f)
+ database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
- string r (base_context::database_type_impl (t, hint, ctx, f));
+ string r (base_context::database_type_impl (t, hint, id));
if (!r.empty ())
return r;
@@ -210,13 +207,8 @@ namespace relational
using semantics::enum_;
if (t.is_a<semantics::enum_> ())
- {
r = "INTEGER";
- if ((f & ctf_default_null) == 0)
- r += " NOT NULL";
- }
-
return r;
}
diff --git a/odb/relational/sqlite/context.hxx b/odb/relational/sqlite/context.hxx
index c625069..b5c3d85 100644
--- a/odb/relational/sqlite/context.hxx
+++ b/odb/relational/sqlite/context.hxx
@@ -49,10 +49,8 @@ namespace relational
protected:
virtual string
- database_type_impl (semantics::type&,
- semantics::names*,
- semantics::context&,
- column_type_flags);
+ database_type_impl (semantics::type&, semantics::names*, bool);
+
public:
virtual
~context ();
diff --git a/odb/relational/sqlite/source.cxx b/odb/relational/sqlite/source.cxx
index 35a3246..6a99fc8 100644
--- a/odb/relational/sqlite/source.cxx
+++ b/odb/relational/sqlite/source.cxx
@@ -321,7 +321,7 @@ namespace relational
{
os << "}";
- if (!null_pointer (mi.m, key_prefix_))
+ if (!null (mi.m, key_prefix_))
os << "else" << endl
<< "throw null_pointer ();";
}
@@ -437,7 +437,7 @@ namespace relational
<< endl
<< "if (i." << mi.var << "null)" << endl;
- if (null_pointer (mi.m, key_prefix_))
+ if (null (mi.m, key_prefix_))
os << member << " = ptr_traits::pointer_type ();";
else
os << "throw null_pointer ();";
diff --git a/odb/relational/type-processor.cxx b/odb/relational/type-processor.cxx
index f7b0b2a..0f1c1d2 100644
--- a/odb/relational/type-processor.cxx
+++ b/odb/relational/type-processor.cxx
@@ -131,14 +131,7 @@ namespace relational
type = idt.get<string> ("type");
if (type.empty ())
- {
- column_type_flags f (ctf_none);
-
- if (null_pointer (m))
- f |= ctf_default_null;
-
- type = database_type (idt, id.belongs ().hint (), id, f);
- }
+ type = database_type (idt, id.belongs ().hint (), true);
}
else
{
@@ -149,12 +142,22 @@ namespace relational
type = t.get<string> ("type");
if (type.empty ())
- type = database_type (t, m.belongs ().hint (), m, ctf_none);
+ type = database_type (t, m.belongs ().hint (), m.count ("id"));
}
if (!type.empty ())
{
m.set ("column-type", type);
+
+ // Issue a warning if we are relaxing null-ness.
+ //
+ if (m.count ("null") && m.type ().count ("not-null"))
+ {
+ os << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " warning: data member declared null while its type is "
+ << "declared not null" << endl;
+ }
+
return;
}
@@ -221,14 +224,7 @@ namespace relational
type = idt.get<string> ("type");
if (type.empty ())
- {
- column_type_flags f (ctf_none);
-
- if (null_pointer (m, prefix))
- f |= ctf_default_null;
-
- type = database_type (idt, id.belongs ().hint (), id, f);
- }
+ type = database_type (idt, id.belongs ().hint (), true);
}
else
{
@@ -236,7 +232,7 @@ namespace relational
type = t.get<string> ("type");
if (type.empty ())
- type = database_type (t, hint, m, ctf_none);
+ type = database_type (t, hint, false);
}
if (!type.empty ())
@@ -366,6 +362,10 @@ namespace relational
t.set ("container-kind", ck);
+ // Mark id column as not null.
+ //
+ t.set ("id-not-null", string ());
+
// Get the value type.
//
try
@@ -404,6 +404,33 @@ namespace relational
t.set ("value-tree-type", vt);
t.set ("value-tree-hint", vh);
+ // If we have a set container, automatically mark the value
+ // column as not null. If we already have an explicit null for
+ // this column, issue an error.
+ //
+ if (ck == ck_set)
+ {
+ if (t.count ("value-null"))
+ {
+ os << t.file () << ":" << t.line () << ":" << t.column () << ":"
+ << " error: set container cannot contain null values" << endl;
+
+ throw generation_failed ();
+ }
+ else
+ t.set ("value-not-null", string ());
+ }
+
+ // Issue a warning if we are relaxing null-ness in the
+ // container type.
+ //
+ if (t.count ("value-null") && vt->count ("not-null"))
+ {
+ os << t.file () << ":" << t.line () << ":" << t.column () << ":"
+ << " warning: container value declared null while its type "
+ << "is declared not null" << endl;
+ }
+
// Get the index type for ordered containers.
//
if (ck == ck_ordered)
@@ -443,6 +470,7 @@ namespace relational
t.set ("index-tree-type", it);
t.set ("index-tree-hint", ih);
+ t.set ("index-not-null", string ());
}
// Get the key type for maps.
@@ -484,6 +512,7 @@ namespace relational
t.set ("key-tree-type", kt);
t.set ("key-tree-hint", kh);
+ t.set ("key-not-null", string ());
}
}
@@ -507,6 +536,28 @@ namespace relational
if (ck == ck_ordered && m.count ("value-inverse"))
m.set ("unordered", string ()); // Keep compatible with pragma.
+ // Issue an error if we have a null column in a set container.
+ // This can only happen if the value is declared as null in
+ // the member.
+ //
+ if (ck == ck_set && m.count ("value-null"))
+ {
+ os << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " error: set container cannot contain null values" << endl;
+
+ throw generation_failed ();
+ }
+
+ // Issue a warning if we are relaxing null-ness in the member.
+ //
+ if (m.count ("value-null") &&
+ (t.count ("value-not-null") || vt->count ("not-null")))
+ {
+ os << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " warning: container value declared null while the container "
+ << "type or value type declares it as not null" << endl;
+ }
+
return true;
}
@@ -729,12 +780,6 @@ namespace relational
throw generation_failed ();
}
- if (m.count ("not-null") && !kp.empty ())
- {
- m.remove ("not-null");
- m.set (kp + "-not-null", string ()); // Keep compatible with pragma.
- }
-
// See if this is the inverse side of a bidirectional relationship.
// If so, then resolve the member and cache it in the context.
//