From 16ebe8f2b2464c682848cb3d8ef7168586779700 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 1 Dec 2010 14:36:39 +0200 Subject: Implement not_null pointer pragma New exception: null_pointer. --- odb/context.cxx | 1 + odb/context.hxx | 18 ++++++++++++++++++ odb/mysql/source.cxx | 17 ++++++++++++++--- odb/pragma.cxx | 31 +++++++++++++++++++++++++++++++ odb/type-processor.cxx | 22 ++++++++++++++++++---- 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 (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 ( + "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 ("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 ("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. // -- cgit v1.1