aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-12-01 14:36:39 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-12-01 14:36:39 +0200
commit16ebe8f2b2464c682848cb3d8ef7168586779700 (patch)
tree242ede30b299b6473eb9c9bb144d14c9ba4f9cb4
parentce46e20efba053e914986f20e578d90ab2e42751 (diff)
Implement not_null pointer pragma
New exception: null_pointer.
-rw-r--r--odb/context.cxx1
-rw-r--r--odb/context.hxx18
-rw-r--r--odb/mysql/source.cxx17
-rw-r--r--odb/pragma.cxx31
-rw-r--r--odb/type-processor.cxx22
5 files changed, 82 insertions, 7 deletions
diff --git a/odb/context.cxx b/odb/context.cxx
index 5c16e68..792bd25 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -138,6 +138,7 @@ comp_value_ (semantics::class_& c)
r = r && !c.count ("index-column");
r = r && !c.count ("key-column");
r = r && !c.count ("id-column");
+ r = r && !c.count ("not_null");
r = r && !c.count ("unordered");
c.set ("composite-value", r);
diff --git a/odb/context.hxx b/odb/context.hxx
index bc8a8bf..47375a3 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -88,6 +88,24 @@ public:
: m.get<class_*> (key_prefix + "-object-pointer", 0);
}
+ static bool
+ null_pointer (semantics::data_member& m)
+ {
+ return !(m.count ("not-null") || m.type ().count ("not-null"));
+ }
+
+ static bool
+ null_pointer (semantics::data_member& m, string const& key_prefix)
+ {
+ if (key_prefix.empty ())
+ return null_pointer (m);
+
+ return !(m.count (key_prefix + "-not-null") ||
+ m.type ().count ("not-null") ||
+ m.type ().get<semantics::type*> (
+ "tree-" + key_prefix +"-type")->count ("not-null"));
+ }
+
static semantics::data_member*
inverse (semantics::data_member& m, string const& key_prefix = string ())
{
diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx
index 60b1296..6f159c2 100644
--- a/odb/mysql/source.cxx
+++ b/odb/mysql/source.cxx
@@ -796,8 +796,14 @@ namespace mysql
if (!comp_value (mi.t))
{
if (object_pointer (mi.m, key_prefix_))
+ {
os << "}";
+ if (!null_pointer (mi.m, key_prefix_))
+ os << "else" << endl
+ << "throw null_pointer ();";
+ }
+
os << "i." << mi.var << "null = is_null;"
<< "}";
}
@@ -1022,9 +1028,14 @@ namespace mysql
<< "typedef pointer_traits< " << mi.fq_type () <<
" > ptr_traits;"
<< endl
- << "if (i." << mi.var << "null)" << endl
- << member << " = ptr_traits::pointer_type ();"
- << "else"
+ << "if (i." << mi.var << "null)" << endl;
+
+ if (null_pointer (mi.m, key_prefix_))
+ os << member << " = ptr_traits::pointer_type ();";
+ else
+ os << "throw null_pointer ();";
+
+ os << "else"
<< "{"
<< type << " id;";
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index 002a25c..c2d5df5 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -187,6 +187,17 @@ check_decl_type (tree d, string const& name, string const& p, location_t l)
return false;
}
}
+ else if (p == "not_null")
+ {
+ // Not_null can be used for both members and types (container or pointer).
+ //
+ if (tc != FIELD_DECL && !TYPE_P (d))
+ {
+ error_at (l, "name %qs in db pragma %qs does not refer to a type "
+ "or data member", name.c_str (), pc);
+ return false;
+ }
+ }
else if (p == "unordered")
{
// Unordered can be used for both members (container) and
@@ -449,6 +460,18 @@ handle_pragma (cpp_reader* reader,
tt = pragma_lex (&t);
}
+ else if (p == "not_null")
+ {
+ // not_null
+ //
+
+ // Make sure we've got the correct declaration type.
+ //
+ if (decl != 0 && !check_decl_type (decl, decl_name, p, loc))
+ return;
+
+ tt = pragma_lex (&t);
+ }
else if (p == "inverse")
{
// inverse (name)
@@ -682,6 +705,7 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p)
p == "index_type" ||
p == "key_type" ||
p == "table" ||
+ p == "not_null" ||
p == "inverse" ||
p == "unordered" ||
p == "transient")
@@ -812,6 +836,12 @@ handle_pragma_db_table (cpp_reader* reader)
}
extern "C" void
+handle_pragma_db_not_null (cpp_reader* reader)
+{
+ handle_pragma_qualifier (reader, "not_null");
+}
+
+extern "C" void
handle_pragma_db_inverse (cpp_reader* reader)
{
handle_pragma_qualifier (reader, "inverse");
@@ -847,6 +877,7 @@ register_odb_pragmas (void*, void*)
c_register_pragma_with_expansion ("db", "index_type", handle_pragma_db_itype);
c_register_pragma_with_expansion ("db", "key_type", handle_pragma_db_ktype);
c_register_pragma_with_expansion ("db", "table", handle_pragma_db_table);
+ c_register_pragma_with_expansion ("db", "not_null", handle_pragma_db_not_null);
c_register_pragma_with_expansion ("db", "inverse", handle_pragma_db_inverse);
c_register_pragma_with_expansion ("db", "unordered", handle_pragma_db_unordered);
c_register_pragma_with_expansion ("db", "transient", handle_pragma_db_transient);
diff --git a/odb/type-processor.cxx b/odb/type-processor.cxx
index b47c413..381a4e4 100644
--- a/odb/type-processor.cxx
+++ b/odb/type-processor.cxx
@@ -107,8 +107,12 @@ namespace
if (type.empty () && idt.count ("type"))
type = idt.get<string> ("type");
- type = data_->column_type_impl (
- idt, type, id, ctf_default_null | ctf_object_id_ref);
+ column_type_flags f (ctf_object_id_ref);
+
+ if (null_pointer (m))
+ f |= ctf_default_null;
+
+ type = data_->column_type_impl (idt, type, id, f);
}
else
{
@@ -190,8 +194,12 @@ namespace
if (type.empty () && idt.count ("type"))
type = idt.get<string> ("type");
- type = data_->column_type_impl (
- idt, type, id, ctf_default_null | ctf_object_id_ref);
+ column_type_flags f (ctf_object_id_ref);
+
+ if (null_pointer (m, prefix))
+ f |= ctf_default_null;
+
+ type = data_->column_type_impl (idt, type, id, f);
}
else
type = data_->column_type_impl (t, type, m, ctf_none);
@@ -465,6 +473,12 @@ namespace
m.set (kp + (kp.empty () ? "": "-") + "object-pointer", c);
+ 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.
//