aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/common.cxx15
-rw-r--r--odb/context.cxx96
-rw-r--r--odb/context.hxx12
-rw-r--r--odb/pragma.cxx10
-rw-r--r--odb/relational/source.hxx25
5 files changed, 118 insertions, 40 deletions
diff --git a/odb/common.cxx b/odb/common.cxx
index 6261b85..e1aa2d0 100644
--- a/odb/common.cxx
+++ b/odb/common.cxx
@@ -104,7 +104,8 @@ traverse (semantics::class_& c)
if (table_prefix_.level == 0)
{
- table_prefix_.schema = schema (c.scope ());
+ table_prefix_.ns_schema = schema (c.scope ());
+ table_prefix_.ns_prefix = table_name_prefix (c.scope ());
table_prefix_.prefix = table_name (c);
table_prefix_.prefix += "_";
table_prefix_.level = 1;
@@ -120,7 +121,8 @@ traverse (semantics::class_& c)
{
table_prefix_.level = 0;
table_prefix_.prefix.clear ();
- table_prefix_.schema.clear ();
+ table_prefix_.ns_prefix.clear ();
+ table_prefix_.ns_schema.clear ();
}
}
else
@@ -218,6 +220,8 @@ append (semantics::data_member& m, table_prefix& tp)
{
context& ctx (context::current ());
+ assert (tp.level > 0);
+
// If a custom table prefix was specified, then ignore the top-level
// table prefix (this corresponds to a container directly inside an
// object) but keep the schema unless the alternative schema is fully
@@ -233,14 +237,14 @@ append (semantics::data_member& m, table_prefix& tp)
{
if (n.qualified ())
{
- p = tp.schema;
+ p = tp.ns_schema;
p.append (n.qualifier ());
}
else
p = tp.prefix.qualifier ();
}
- p.append (tp.level <= 1 ? ctx.options.table_prefix () : tp.prefix.uname ());
+ p.append (tp.level == 1 ? tp.ns_prefix : tp.prefix.uname ());
p += n.uname ();
tp.prefix.swap (p);
@@ -253,9 +257,6 @@ append (semantics::data_member& m, table_prefix& tp)
string name (ctx.public_name_db (m));
size_t n (name.size ());
- if (tp.prefix.empty ())
- tp.prefix.append (ctx.options.table_prefix ());
-
tp.prefix += name;
if (n != 0 && name[n - 1] != '_')
diff --git a/odb/context.cxx b/odb/context.cxx
index 15579f3..86cca9d 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -605,17 +605,39 @@ schema (semantics::scope& s) const
if (ns->extension ())
ns = &ns->original ();
- if (ns->count ("schema"))
+ bool sf (ns->count ("schema"));
+ bool tf (ns->count ("table"));
+
+ if (tf)
+ {
+ qname n (ns->get<qname> ("table"));
+ tf = n.qualified ();
+
+ // If we have both schema and qualified table prefix, see which
+ // takes precedence based on order.
+ //
+
+ if (tf && sf)
+ {
+ if (ns->get<location_t> ("table-location") >
+ ns->get<location_t> ("schema-location"))
+ sf = false;
+ else
+ tf = false;
+ }
+ }
+
+ if (sf || tf)
{
- qname n (ns->get<qname> ("schema"));
+ qname n (
+ sf
+ ? ns->get<qname> ("schema")
+ : ns->get<qname> ("table").qualifier ());
n.append (r);
n.swap (r);
-
- if (r.fully_qualified ())
- break;
}
- if (ns->global_scope ())
+ if (r.fully_qualified () || ns->global_scope ())
break;
}
@@ -633,6 +655,45 @@ schema (semantics::scope& s) const
return r;
}
+string context::
+table_name_prefix (semantics::scope& s) const
+{
+ if (s.count ("table-prefix"))
+ return s.get<string> ("table-prefix");
+
+ string r;
+
+ for (semantics::scope* ps (&s);; ps = &ps->scope_ ())
+ {
+ using semantics::namespace_;
+
+ namespace_* ns (dynamic_cast<namespace_*> (ps));
+
+ if (ns == 0)
+ continue; // Some other scope.
+
+ if (ns->extension ())
+ ns = &ns->original ();
+
+ if (ns->count ("table"))
+ {
+ qname n (ns->get<qname> ("table"));
+ r = n.uname () + r;
+ }
+
+ if (ns->global_scope ())
+ break;
+ }
+
+ // Add the prefix that was specified on the command line.
+ //
+ if (options.table_prefix_specified ())
+ r = options.table_prefix () + r;
+
+ s.set ("table-prefix", r);
+ return r;
+}
+
qname context::
table_name (semantics::class_& c) const
{
@@ -679,10 +740,9 @@ table_name (semantics::class_& c) const
n.swap (r);
}
- // Add the table prefix if specified.
+ // Add the table prefix if any.
//
- if (options.table_prefix_specified ())
- r.uname () = options.table_prefix () + r.uname ();
+ r.uname () = table_name_prefix (c.scope ()) + r.uname ();
c.set ("qualified-table", r);
return r;
@@ -691,7 +751,9 @@ table_name (semantics::class_& c) const
qname context::
table_name (semantics::class_& obj, data_member_path const& mp) const
{
- table_prefix tp (schema (obj.scope ()), table_name (obj) + "_", 1);
+ table_prefix tp (schema (obj.scope ()),
+ table_name_prefix (obj.scope ()),
+ table_name (obj) + "_");
if (mp.size () == 1)
{
@@ -712,15 +774,13 @@ table_name (semantics::class_& obj, data_member_path const& mp) const
}
}
+// The table prefix passed as the second argument must include the table
+// prefix specified on namespaces and with the --table-prefix option.
+//
qname context::
table_name (semantics::data_member& m, table_prefix const& p) const
{
- // The table prefix passed as the second argument must include
- // the table prefix specified with the --table-prefix option.
- //
- string const& gp (options.table_prefix ());
- assert (p.prefix.uname ().compare (0, gp.size (), gp) == 0);
-
+ assert (p.level > 0);
qname r;
// If a custom table name was specified, then ignore the top-level
@@ -740,14 +800,14 @@ table_name (semantics::data_member& m, table_prefix const& p) const
{
if (n.qualified ())
{
- r = p.schema;
+ r = p.ns_schema;
r.append (n.qualifier ());
}
else
r = p.prefix.qualifier ();
}
- r.append (p.level == 1 ? gp : p.prefix.uname ());
+ r.append (p.level == 1 ? p.ns_prefix : p.prefix.uname ());
r += n.uname ();
}
else
diff --git a/odb/context.hxx b/odb/context.hxx
index 7e62161..3865e88 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -474,6 +474,11 @@ public:
qname
schema (semantics::scope&) const;
+ // Table name prefix for a namespace.
+ //
+ string
+ table_name_prefix (semantics::scope&) const;
+
//
//
qname
@@ -485,10 +490,11 @@ public:
struct table_prefix
{
table_prefix (): level (0) {}
- table_prefix (qname const& s, qname const& p, size_t l)
- : schema (s), prefix (p), level (l) {}
+ table_prefix (qname const& ns_s, string const& ns_p, qname const& p)
+ : ns_schema (ns_s), ns_prefix (ns_p), prefix (p), level (1) {}
- qname schema; // Object's namespace schema.
+ qname ns_schema; // Object's namespace schema.
+ string ns_prefix; // Object's namespace table prefix.
qname prefix;
size_t level;
};
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index 6c92f0f..010706e 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -472,13 +472,13 @@ check_spec_decl_type (tree d,
}
else if (p == "table")
{
- // Table can be used for both members (container) and types (container,
- // object, or view).
+ // Table can be used for namespaces, members (container), and types
+ // (container, object, or view).
//
- if (tc != FIELD_DECL && !TYPE_P (d))
+ if (tc != NAMESPACE_DECL && tc != FIELD_DECL && !TYPE_P (d))
{
error (l) << "name '" << name << "' in db pragma " << p << " does "
- << "not refer to a type or data member" << endl;
+ << "not refer to a namespace, type, or data member" << endl;
return false;
}
}
@@ -612,7 +612,7 @@ handle_pragma (cpp_reader* reader,
string const& qualifier,
tree decl,
string const& decl_name,
- bool ns) // True is this is a position namespace pragma.
+ bool ns) // True if this is a position namespace pragma.
{
tree t;
cpp_ttype tt;
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index 7f94410..ab5220a 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -118,7 +118,9 @@ namespace relational
if (!table_name_.empty ())
{
- table_prefix tp (schema (c.scope ()), table_name (c) + "_", 1);
+ table_prefix tp (schema (c.scope ()),
+ table_name_prefix (c.scope ()),
+ table_name (c) + "_");
table = table_qname (*im, tp);
}
@@ -476,7 +478,9 @@ namespace relational
// prefix is just the class table name.
//
qname const& ct (table_name (c));
- table_prefix tp (schema (c.scope ()), ct + "_", 1);
+ table_prefix tp (schema (c.scope ()),
+ table_name_prefix (c.scope ()),
+ ct + "_");
t = table_qname (*im, tp);
// Container's value is our id.
@@ -1256,7 +1260,11 @@ namespace relational
typedef container_traits base;
container_traits (semantics::class_& c)
- : object_members_base (true, true, false), c_ (c)
+ : object_members_base (
+ true,
+ object (c), // Only build table prefix for objects.
+ false),
+ c_ (c)
{
string const& type (class_fq_name (c));
@@ -1431,7 +1439,9 @@ namespace relational
// This other container is a direct member of the class so the
// table prefix is just the class table name.
//
- table_prefix tp (schema (c->scope ()), table_name (*c) + "_", 1);
+ table_prefix tp (schema (c->scope ()),
+ table_name_prefix (c->scope ()),
+ table_name (*c) + "_");
inv_table = table_qname (*im, tp);
inv_id_cols->traverse (*im, utype (inv_id), "id", "object_id", c);
@@ -4629,9 +4639,10 @@ namespace relational
// function would have to return a member path instead
// of just a single member.
//
- table_prefix tp (context::schema (vo->obj->scope ()),
- table_name (*vo->obj) + "_",
- 1);
+ table_prefix tp (
+ context::schema (vo->obj->scope ()),
+ context::table_name_prefix (vo->obj->scope ()),
+ table_name (*vo->obj) + "_");
ct = table_qname (*im, tp);
}
else