aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-07-21 11:02:40 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-07-22 17:56:59 +0200
commit0d61aca198f1a5a71a791b892ef55fe2947d7aa0 (patch)
tree3e7edb0df78928e619860540651d8d36b0443986
parent5d8f5cc0e6d658ae1f74bdf977988bbe995701bb (diff)
Add support for specifying extra column options
New pragmas: options, id_options, index_options, key_options, and value_options.
-rw-r--r--odb/context.cxx54
-rw-r--r--odb/context.hxx6
-rw-r--r--odb/pragma.cxx219
-rw-r--r--odb/relational/schema.hxx7
4 files changed, 240 insertions, 46 deletions
diff --git a/odb/context.cxx b/odb/context.cxx
index 520caea..0227763 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -247,6 +247,11 @@ 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 ("options");
+ r = r && !c.count ("value-options");
+ r = r && !c.count ("index-options");
+ r = r && !c.count ("key-options");
+ r = r && !c.count ("id-options");
r = r && !c.count ("null");
r = r && !c.count ("not-null");
r = r && !c.count ("value-null");
@@ -313,6 +318,55 @@ column_type (semantics::data_member& m, string const& kp)
}
string context::
+column_options (semantics::data_member& m)
+{
+ // Accumulate options from both type and member.
+ //
+ semantics::type& t (m.type ());
+
+ string mo (m.get<string> ("options", string ()));
+ string to (t.get<string> ("options", string ()));
+
+ return to + (mo.empty () || to.empty () ? "" : " ") + mo;
+}
+
+string context::
+column_options (semantics::data_member& m, string const& kp)
+{
+ if (kp.empty ())
+ return column_options (m);
+
+ string k (kp + "-options");
+
+ // Accumulate options from type, container, and member.
+ //
+ semantics::type& c (m.type ());
+ semantics::type& t (member_type (m, kp));
+
+ string r (t.get<string> ("options", string ()));
+
+ string o (c.get<string> (k, string ()));
+ if (!o.empty ())
+ {
+ if (!r.empty ())
+ r += ' ';
+
+ r += o;
+ }
+
+ o = m.get<string> (k, string ());
+ if (!o.empty ())
+ {
+ if (!r.empty ())
+ r += ' ';
+
+ r += o;
+ }
+
+ return r;
+}
+
+string context::
database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
type_map_type::const_iterator end (data_->type_map_.end ()), i (end);
diff --git a/odb/context.hxx b/odb/context.hxx
index a256866..5962133 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -160,6 +160,12 @@ public:
string
column_type (semantics::data_member&, string const& key_prefix = string ());
+ string
+ column_options (semantics::data_member&);
+
+ string
+ column_options (semantics::data_member&, string const& key_prefix);
+
// Cleaned-up member name that can be used for database names.
//
string
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index 8408489..6fea208 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -198,6 +198,21 @@ check_decl_type (tree d, string const& name, string const& p, location_t l)
return false;
}
}
+ else if (p == "options" ||
+ p == "value_options" ||
+ p == "index_options" ||
+ p == "key_options" ||
+ p == "id_options")
+ {
+ // Options can be used for both members and types.
+ //
+ if (tc != FIELD_DECL && !TYPE_P (d))
+ {
+ error (l) << "name '" << name << "' in db pragma '" << p << "' does "
+ << "not refer to a type or data member" << endl;
+ return false;
+ }
+ }
else if (p == "null" ||
p == "not_null" ||
p == "value_null" ||
@@ -480,6 +495,48 @@ handle_pragma (cpp_reader* reader,
tt = pragma_lex (&t);
}
+ else if (p == "options" ||
+ p == "value_options" ||
+ p == "index_options" ||
+ p == "key_options" ||
+ p == "id_options")
+ {
+ // options ("<name>")
+ // value_options ("<name>")
+ // index_options ("<name>")
+ // key_options ("<name>")
+ // id_options ("<name>")
+ //
+
+ // Make sure we've got the correct declaration type.
+ //
+ if (decl != 0 && !check_decl_type (decl, decl_name, p, loc))
+ return;
+
+ if (pragma_lex (&t) != CPP_OPEN_PAREN)
+ {
+ error () << "'(' expected after db pragma '" << p << "'" << endl;
+ return;
+ }
+
+ tt = pragma_lex (&t);
+
+ if (tt != CPP_STRING)
+ {
+ error () << "options string expected in db pragma '" << p << "'" << endl;
+ return;
+ }
+
+ val = TREE_STRING_POINTER (t);
+
+ if (pragma_lex (&t) != CPP_CLOSE_PAREN)
+ {
+ error () << "')' expected at the end of db pragma '" << p << "'" << endl;
+ return;
+ }
+
+ tt = pragma_lex (&t);
+ }
else if (p == "type" ||
p == "id_type" ||
p == "value_type" ||
@@ -771,6 +828,11 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p)
p == "index_column" ||
p == "key_column" ||
p == "id_column" ||
+ p == "options" ||
+ p == "value_options" ||
+ p == "index_options" ||
+ p == "key_options" ||
+ p == "id_options" ||
p == "type" ||
p == "value_type" ||
p == "index_type" ||
@@ -820,146 +882,205 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p)
}
extern "C" void
-handle_pragma_db_object (cpp_reader* reader)
+handle_pragma_db_object (cpp_reader* r)
+{
+ handle_pragma_qualifier (r, "object");
+}
+
+extern "C" void
+handle_pragma_db_value (cpp_reader* r)
+{
+ handle_pragma_qualifier (r, "value");
+}
+
+extern "C" void
+handle_pragma_db_member (cpp_reader* r)
+{
+ handle_pragma_qualifier (r, "member");
+}
+
+extern "C" void
+handle_pragma_db_id (cpp_reader* r)
+{
+ handle_pragma_qualifier (r, "id");
+}
+
+extern "C" void
+handle_pragma_db_auto (cpp_reader* r)
+{
+ handle_pragma_qualifier (r, "auto");
+}
+
+extern "C" void
+handle_pragma_db_column (cpp_reader* r)
+{
+ handle_pragma_qualifier (r, "column");
+}
+
+extern "C" void
+handle_pragma_db_vcolumn (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "object");
+ handle_pragma_qualifier (r, "value_column");
}
extern "C" void
-handle_pragma_db_value (cpp_reader* reader)
+handle_pragma_db_icolumn (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "value");
+ handle_pragma_qualifier (r, "index_column");
}
extern "C" void
-handle_pragma_db_member (cpp_reader* reader)
+handle_pragma_db_kcolumn (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "member");
+ handle_pragma_qualifier (r, "key_column");
}
extern "C" void
-handle_pragma_db_id (cpp_reader* reader)
+handle_pragma_db_idcolumn (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "id");
+ handle_pragma_qualifier (r, "id_column");
}
extern "C" void
-handle_pragma_db_auto (cpp_reader* reader)
+handle_pragma_db_options (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "auto");
+ handle_pragma_qualifier (r, "options");
}
extern "C" void
-handle_pragma_db_column (cpp_reader* reader)
+handle_pragma_db_voptions (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "column");
+ handle_pragma_qualifier (r, "value_options");
}
extern "C" void
-handle_pragma_db_vcolumn (cpp_reader* reader)
+handle_pragma_db_ioptions (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "value_column");
+ handle_pragma_qualifier (r, "index_options");
}
extern "C" void
-handle_pragma_db_icolumn (cpp_reader* reader)
+handle_pragma_db_koptions (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "index_column");
+ handle_pragma_qualifier (r, "key_options");
}
extern "C" void
-handle_pragma_db_kcolumn (cpp_reader* reader)
+handle_pragma_db_idoptions (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "key_column");
+ handle_pragma_qualifier (r, "id_options");
}
extern "C" void
-handle_pragma_db_idcolumn (cpp_reader* reader)
+handle_pragma_db_type (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "id_column");
+ handle_pragma_qualifier (r, "type");
}
extern "C" void
-handle_pragma_db_type (cpp_reader* reader)
+handle_pragma_db_id_type (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "type");
+ handle_pragma_qualifier (r, "id_type");
}
extern "C" void
-handle_pragma_db_id_type (cpp_reader* reader)
+handle_pragma_db_vtype (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "id_type");
+ handle_pragma_qualifier (r, "value_type");
}
extern "C" void
-handle_pragma_db_vtype (cpp_reader* reader)
+handle_pragma_db_itype (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "value_type");
+ handle_pragma_qualifier (r, "index_type");
}
extern "C" void
-handle_pragma_db_itype (cpp_reader* reader)
+handle_pragma_db_ktype (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "index_type");
+ handle_pragma_qualifier (r, "key_type");
}
extern "C" void
-handle_pragma_db_ktype (cpp_reader* reader)
+handle_pragma_db_table (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "key_type");
+ handle_pragma_qualifier (r, "table");
}
extern "C" void
-handle_pragma_db_table (cpp_reader* reader)
+handle_pragma_db_null (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "table");
+ handle_pragma_qualifier (r, "null");
}
extern "C" void
-handle_pragma_db_null (cpp_reader* reader)
+handle_pragma_db_not_null (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "null");
+ handle_pragma_qualifier (r, "not_null");
}
extern "C" void
-handle_pragma_db_not_null (cpp_reader* reader)
+handle_pragma_db_value_null (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "not_null");
+ handle_pragma_qualifier (r, "value_null");
}
extern "C" void
-handle_pragma_db_value_null (cpp_reader* reader)
+handle_pragma_db_value_not_null (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "value_null");
+ handle_pragma_qualifier (r, "value_not_null");
}
extern "C" void
-handle_pragma_db_value_not_null (cpp_reader* reader)
+handle_pragma_db_inverse (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "value_not_null");
+ handle_pragma_qualifier (r, "inverse");
}
extern "C" void
-handle_pragma_db_inverse (cpp_reader* reader)
+handle_pragma_db_unordered (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "inverse");
+ handle_pragma_qualifier (r, "unordered");
}
extern "C" void
-handle_pragma_db_unordered (cpp_reader* reader)
+handle_pragma_db_transient (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "unordered");
+ handle_pragma_qualifier (r, "transient");
}
extern "C" void
-handle_pragma_db_transient (cpp_reader* reader)
+handle_pragma_db (cpp_reader* r)
{
- handle_pragma_qualifier (reader, "transient");
+ tree t;
+ cpp_ttype tt (pragma_lex (&t));
+
+ if (tt != CPP_NAME)
+ {
+ if (tt == CPP_EOF)
+ error () << "expected specifier after db pragma" << endl;
+ else
+ error () << "unexpected token after db pragma" << endl;
+ return;
+ }
+
+ handle_pragma_qualifier (r, IDENTIFIER_POINTER (t));
}
extern "C" void
register_odb_pragmas (void*, void*)
{
+ // GCC has a limited number of pragma slots and we have exhausted them.
+ // A workaround is to make 'db' a pragma rather than a namespace. This
+ // way we only have one pragma but the drawback of this approach is the
+ // fact that the specifier or qualifier name will now be macro-expanded
+ // (though this happens anyway if we have multiple specifiers in a single
+ // pragma). Once the GCC folks fix this, we can go back to the namespace
+ // approach.
+ //
+ c_register_pragma_with_expansion (0, "db", handle_pragma_db);
+
+ /*
c_register_pragma_with_expansion ("db", "object", handle_pragma_db_object);
c_register_pragma_with_expansion ("db", "value", handle_pragma_db_value);
c_register_pragma_with_expansion ("db", "member", handle_pragma_db_member);
@@ -970,6 +1091,11 @@ register_odb_pragmas (void*, void*)
c_register_pragma_with_expansion ("db", "index_column", handle_pragma_db_icolumn);
c_register_pragma_with_expansion ("db", "key_column", handle_pragma_db_kcolumn);
c_register_pragma_with_expansion ("db", "id_column", handle_pragma_db_idcolumn);
+ c_register_pragma_with_expansion ("db", "options", handle_pragma_db_options);
+ c_register_pragma_with_expansion ("db", "value_options", handle_pragma_db_voptions);
+ c_register_pragma_with_expansion ("db", "index_options", handle_pragma_db_ioptions);
+ c_register_pragma_with_expansion ("db", "key_options", handle_pragma_db_koptions);
+ c_register_pragma_with_expansion ("db", "id_options", handle_pragma_db_idoptions);
c_register_pragma_with_expansion ("db", "type", handle_pragma_db_type);
c_register_pragma_with_expansion ("db", "id_type", handle_pragma_db_id_type);
c_register_pragma_with_expansion ("db", "value_type", handle_pragma_db_vtype);
@@ -983,4 +1109,5 @@ register_odb_pragmas (void*, void*)
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/relational/schema.hxx b/odb/relational/schema.hxx
index 9d64276..b218c2b 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -193,6 +193,13 @@ namespace relational
constraints (m);
reference (m);
+ // If we have options, add them.
+ //
+ string const& o (column_options (m, prefix_));
+
+ if (!o.empty ())
+ os << " " << o;
+
return true;
}