summaryrefslogtreecommitdiff
path: root/odb/relational
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-01-26 12:43:16 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-01-26 12:43:16 +0200
commitaf12ffe836de09ec84f666effa4df347eeb07a43 (patch)
treedc0aec9f8fee545c84be098414772cf2b277c30d /odb/relational
parentc1d2ec5bbd5969332f3278f39d2a7a8f0abc0493 (diff)
Implement support for database schema
New pragma qualifier: namespace. New pragma specifier: schema. The table specifier was extended to accept a schema prefix. New option: --default- schema. The common/schema test was extended to cover the new functionality.
Diffstat (limited to 'odb/relational')
-rw-r--r--odb/relational/common.cxx9
-rw-r--r--odb/relational/context.cxx23
-rw-r--r--odb/relational/context.hxx5
-rw-r--r--odb/relational/context.ixx6
-rw-r--r--odb/relational/header.hxx6
-rw-r--r--odb/relational/model.cxx14
-rw-r--r--odb/relational/model.hxx26
-rw-r--r--odb/relational/mssql/context.cxx23
-rw-r--r--odb/relational/mssql/context.hxx2
-rw-r--r--odb/relational/mssql/schema.cxx32
-rw-r--r--odb/relational/mysql/context.cxx23
-rw-r--r--odb/relational/mysql/context.hxx2
-rw-r--r--odb/relational/mysql/schema.cxx22
-rw-r--r--odb/relational/oracle/context.cxx23
-rw-r--r--odb/relational/oracle/context.hxx2
-rw-r--r--odb/relational/oracle/schema.cxx20
-rw-r--r--odb/relational/pgsql/schema.cxx20
-rw-r--r--odb/relational/processor.cxx12
-rw-r--r--odb/relational/schema.cxx4
-rw-r--r--odb/relational/schema.hxx36
-rw-r--r--odb/relational/source.hxx41
-rw-r--r--odb/relational/sqlite/schema.cxx30
22 files changed, 273 insertions, 108 deletions
diff --git a/odb/relational/common.cxx b/odb/relational/common.cxx
index 1ee8449..0c1ecc8 100644
--- a/odb/relational/common.cxx
+++ b/odb/relational/common.cxx
@@ -112,11 +112,11 @@ namespace relational
}
else
{
- // For now use column name as table alias. This will become problematic
- // when we add support for composite ids.
+ // For now use column name as table alias.
+ // @@ This will become problematic when we add support for composite ids.
//
os << "const char " << scope_ << "::" << name << "_alias_[] = " <<
- strlit (column) << ";"
+ strlit (quote_id (column)) << ";"
<< endl;
if (inv)
@@ -299,7 +299,8 @@ namespace relational
{
os << "template <const char* table>" << endl
<< "const typename " << scope_ << "::" << name << "_type_" << endl
- << scope_ << "::" << name << " (" << "table, " << strlit (column);
+ << scope_ << "::" << name << " (" << "table, " <<
+ strlit (quote_id (column));
column_ctor_extra (m);
diff --git a/odb/relational/context.cxx b/odb/relational/context.cxx
index 0ebfbf4..083bfe5 100644
--- a/odb/relational/context.cxx
+++ b/odb/relational/context.cxx
@@ -83,13 +83,26 @@ namespace relational
}
string context::
- quote_id_impl (string const& id) const
+ quote_id_impl (qname const& id) const
{
string r;
- r.reserve (id.size () + 2);
- r += '"';
- r += id;
- r += '"';
+
+ bool f (true);
+ for (qname::iterator i (id.begin ()); i < id.end (); ++i)
+ {
+ if (i->empty ())
+ continue;
+
+ if (f)
+ f = false;
+ else
+ r += '.';
+
+ r += '"';
+ r += *i;
+ r += '"';
+ }
+
return r;
}
}
diff --git a/odb/relational/context.hxx b/odb/relational/context.hxx
index 095f579..6970726 100644
--- a/odb/relational/context.hxx
+++ b/odb/relational/context.hxx
@@ -52,6 +52,9 @@ namespace relational
string
quote_id (string const&) const;
+ string
+ quote_id (qname const&) const;
+
// Quoted column and table names.
//
string
@@ -118,7 +121,7 @@ namespace relational
// The default implementation uses the ISO quoting ("").
//
virtual string
- quote_id_impl (string const&) const;
+ quote_id_impl (qname const&) const;
public:
virtual
diff --git a/odb/relational/context.ixx b/odb/relational/context.ixx
index 8bc10fa..0e1268b 100644
--- a/odb/relational/context.ixx
+++ b/odb/relational/context.ixx
@@ -32,6 +32,12 @@ namespace relational
inline context::string context::
quote_id (string const& id) const
{
+ return current ().quote_id_impl (qname (id));
+ }
+
+ inline context::string context::
+ quote_id (qname const& id) const
+ {
return current ().quote_id_impl (id);
}
}
diff --git a/odb/relational/header.hxx b/odb/relational/header.hxx
index 427b008..b358810 100644
--- a/odb/relational/header.hxx
+++ b/odb/relational/header.hxx
@@ -1407,11 +1407,12 @@ namespace relational
semantics::class_& o (*i->obj);
string const& name (alias ? i->alias : class_name (o));
string const& type (class_fq_name (o));
+ qname const& table (table_name (o));
os << "// " << name << endl
<< "//" << endl;
- if (alias && i->alias != table_name (o))
+ if (alias && (table.qualified () || i->alias != table.uname ()))
os << "static const char " << name << "_alias_[];"
<< endl
<< "typedef" << endl
@@ -1450,8 +1451,9 @@ namespace relational
bool alias (!vo->alias.empty ());
semantics::class_& o (*vo->obj);
string const& type (class_fq_name (o));
+ qname const& table (table_name (o));
- if (alias && vo->alias != table_name (o))
+ if (alias && (table.qualified () || vo->alias != table.uname ()))
os << "static const char query_alias[];"
<< endl
<< "struct query_type:" << endl
diff --git a/odb/relational/model.cxx b/odb/relational/model.cxx
index 9bb6070..7c66387 100644
--- a/odb/relational/model.cxx
+++ b/odb/relational/model.cxx
@@ -144,17 +144,17 @@ namespace relational
}
catch (sema_rel::duplicate_name const& e)
{
- semantics::node& n (*e.nameable.get<semantics::node*> ("cxx-node"));
- semantics::node& d (*e.duplicate.get<semantics::node*> ("cxx-node"));
+ semantics::node& o (*e.orig.get<semantics::node*> ("cxx-node"));
+ semantics::node& d (*e.dup.get<semantics::node*> ("cxx-node"));
cerr << d.file () << ":" << d.line () << ":" << d.column ()
- << ": error: " << e.duplicate.kind () << " name '"
- << e.nameable.name () << "' conflicts with an already defined "
- << e.nameable.kind () << " name"
+ << ": error: " << e.dup.kind () << " name '" << e.orig_name
+ << "' conflicts with an already defined " << e.orig.kind ()
+ << " name"
<< endl;
- cerr << n.file () << ":" << n.line () << ":" << n.column ()
- << ": info: conflicting " << e.nameable.kind () << " is "
+ cerr << o.file () << ":" << o.line () << ":" << o.column ()
+ << ": info: conflicting " << e.orig.kind () << " is "
<< "defined here"
<< endl;
diff --git a/odb/relational/model.hxx b/odb/relational/model.hxx
index 6fe5b0d..51e9b7c 100644
--- a/odb/relational/model.hxx
+++ b/odb/relational/model.hxx
@@ -21,7 +21,7 @@ namespace relational
{
namespace model
{
- typedef std::set<std::string> tables;
+ typedef std::set<qname> tables;
struct object_columns: object_columns_base, virtual context
{
@@ -111,7 +111,7 @@ namespace relational
id, column_type (m, prefix_), context::null (m, prefix_)));
c.set ("cxx-node", static_cast<semantics::node*> (&m));
- model_.new_edge<sema_rel::names> (table_, c, name);
+ model_.new_edge<sema_rel::unames> (table_, c, name);
// An id member cannot have a default value.
//
@@ -205,7 +205,7 @@ namespace relational
// primary key manipulation, then the database-specific code will
// have to come up with a suitable name.
//
- model_.new_edge<sema_rel::names> (table_, pk, "");
+ model_.new_edge<sema_rel::unames> (table_, pk, "");
}
virtual void
@@ -240,7 +240,7 @@ namespace relational
// up-to-and-including composite member prefix? Though it can be
// empty.
//
- model_.new_edge<sema_rel::names> (table_, fk, name + "_fk");
+ model_.new_edge<sema_rel::unames> (table_, fk, name + "_fk");
}
protected:
@@ -319,7 +319,7 @@ namespace relational
container_kind_type ck (container_kind (ct));
type& vt (container_vt (ct));
- string const& name (table_name (m, table_prefix_));
+ qname const& name (table_name (m, table_prefix_));
// Add the [] decorator to distinguish this id from non-container
// ids (we don't want to ever end up comparing, for example, an
@@ -331,7 +331,7 @@ namespace relational
model_.new_node<sema_rel::container_table> (id));
t.set ("cxx-node", static_cast<semantics::node*> (&m));
- model_.new_edge<sema_rel::names> (model_, t, name);
+ model_.new_edge<sema_rel::qnames> (model_, t, name);
// object_id (simple value, for now)
//
@@ -369,7 +369,7 @@ namespace relational
// Derive the constraint name. See the comment for the other
// foreign key code above.
//
- model_.new_edge<sema_rel::names> (t, fk, id_name + "_fk");
+ model_.new_edge<sema_rel::unames> (t, fk, id_name + "_fk");
}
// index (simple value)
@@ -433,8 +433,8 @@ namespace relational
//@@ Once id can be composite, we need to revise this (see
// a comment for the foreign key generation above).
//
- model_.new_edge<sema_rel::names> (
- model_, i, name + '_' + id_name + "_i");
+ model_.new_edge<sema_rel::qnames> (
+ model_, i, name + "_" + id_name + "_i");
}
if (ordered)
@@ -447,8 +447,8 @@ namespace relational
// This is always a single column (simple value).
//
- model_.new_edge<sema_rel::names> (
- model_, i, name + '_' + index_name + "_i");
+ model_.new_edge<sema_rel::qnames> (
+ model_, i, name + "_" + index_name + "_i");
}
}
@@ -475,7 +475,7 @@ namespace relational
if (!object (c) || abstract (c))
return;
- string const& name (table_name (c));
+ qname const& name (table_name (c));
// If the table with this name was already created, assume the
// user knows what they are doing and skip it.
@@ -494,7 +494,7 @@ namespace relational
t.set ("cxx-node", static_cast<semantics::node*> (&c));
- model_.new_edge<sema_rel::names> (model_, t, name);
+ model_.new_edge<sema_rel::qnames> (model_, t, name);
sema_rel::model::names_iterator begin (--model_.names_end ());
diff --git a/odb/relational/mssql/context.cxx b/odb/relational/mssql/context.cxx
index 7832c24..c426d2e 100644
--- a/odb/relational/mssql/context.cxx
+++ b/odb/relational/mssql/context.cxx
@@ -108,13 +108,26 @@ namespace relational
}
string context::
- quote_id_impl (string const& id) const
+ quote_id_impl (qname const& id) const
{
string r;
- r.reserve (130); // Max MSSQL identifier length is 128.
- r += '[';
- r.append (id, 0, 128);
- r += ']';
+
+ bool f (true);
+ for (qname::iterator i (id.begin ()); i < id.end (); ++i)
+ {
+ if (i->empty ())
+ continue;
+
+ if (f)
+ f = false;
+ else
+ r += '.';
+
+ r += '[';
+ r.append (*i, 0, 128); // Max identifier length is 128.
+ r += ']';
+ }
+
return r;
}
diff --git a/odb/relational/mssql/context.hxx b/odb/relational/mssql/context.hxx
index 8f250ea..2074cc3 100644
--- a/odb/relational/mssql/context.hxx
+++ b/odb/relational/mssql/context.hxx
@@ -104,7 +104,7 @@ namespace relational
protected:
virtual string
- quote_id_impl (string const&) const;
+ quote_id_impl (qname const&) const;
protected:
virtual string
diff --git a/odb/relational/mssql/schema.cxx b/odb/relational/mssql/schema.cxx
index 2cbeb5f..66a2278 100644
--- a/odb/relational/mssql/schema.cxx
+++ b/odb/relational/mssql/schema.cxx
@@ -46,15 +46,13 @@ namespace relational
drop_table (base const& x): base (x) {}
virtual void
- drop (string const& table)
+ drop (sema_rel::qname const& table)
{
// SQL Server has no IF EXISTS conditional for dropping table.
// The following approach appears to be the recommended way to
// drop a table if it exists.
//
- string const& qt ();
-
- os << "IF OBJECT_ID(" << quote_string (table) <<
+ os << "IF OBJECT_ID(" << quote_string (table.string ()) <<
", " << quote_string ("U") << ") IS NOT NULL" << endl
<< " DROP TABLE " << quote_id (table) << endl;
}
@@ -88,7 +86,7 @@ namespace relational
private:
friend class create_foreign_key;
- set<string> tables_; // Set of tables we have already defined.
+ set<qname> tables_; // Set of tables we have already defined.
};
entry<create_table> create_table_;
@@ -145,10 +143,12 @@ namespace relational
name (sema_rel::foreign_key& fk)
{
// In SQL Server, foreign key names are schema-global. Make them
- // unique by prefixing the key name with table name.
+ // unique by prefixing the key name with table name. Note, however,
+ // that they cannot have a schema.
//
- return static_cast<sema_rel::table&> (fk.scope ()).name () +
- '_' + fk.name ();
+ return quote_id (
+ static_cast<sema_rel::table&> (fk.scope ()).name ().uname ()
+ + "_" + fk.name ());
}
virtual void
@@ -216,9 +216,23 @@ namespace relational
// Add foreign keys.
//
instance<add_foreign_key> fk (format_, *this);
- trav_rel::names n (*fk);
+ trav_rel::unames n (*fk);
names (t, n);
}
+
+ struct create_index: relational::create_index, context
+ {
+ create_index (base const& x): base (x) {}
+
+ virtual string
+ name (sema_rel::index& in)
+ {
+ // In SQL Server indexes cannot have a schema.
+ //
+ return quote_id (in.name ().uname ());
+ }
+ };
+ entry<create_index> create_index_;
}
}
}
diff --git a/odb/relational/mysql/context.cxx b/odb/relational/mysql/context.cxx
index e7fd790..9ee0843 100644
--- a/odb/relational/mysql/context.cxx
+++ b/odb/relational/mysql/context.cxx
@@ -105,13 +105,26 @@ namespace relational
}
string context::
- quote_id_impl (string const& id) const
+ quote_id_impl (qname const& id) const
{
string r;
- r.reserve (id.size () + 2);
- r += '`';
- r += id;
- r += '`';
+
+ bool f (true);
+ for (qname::iterator i (id.begin ()); i < id.end (); ++i)
+ {
+ if (i->empty ())
+ continue;
+
+ if (f)
+ f = false;
+ else
+ r += '.';
+
+ r += '`';
+ r += *i;
+ r += '`';
+ }
+
return r;
}
diff --git a/odb/relational/mysql/context.hxx b/odb/relational/mysql/context.hxx
index 2615397..c88a525 100644
--- a/odb/relational/mysql/context.hxx
+++ b/odb/relational/mysql/context.hxx
@@ -111,7 +111,7 @@ namespace relational
protected:
virtual string
- quote_id_impl (string const&) const;
+ quote_id_impl (qname const&) const;
protected:
virtual string
diff --git a/odb/relational/mysql/schema.cxx b/odb/relational/mysql/schema.cxx
index 428db1c..1bdb6dd 100644
--- a/odb/relational/mysql/schema.cxx
+++ b/odb/relational/mysql/schema.cxx
@@ -91,10 +91,12 @@ namespace relational
name (sema_rel::foreign_key& fk)
{
// In MySQL, foreign key names are database-global. Make them
- // unique by prefixing the key name with table name.
+ // unique by prefixing the key name with table name. Note,
+ // however, that they cannot be prefixed with the database name.
//
- return static_cast<sema_rel::table&> (fk.scope ()).name () +
- '_' + fk.name ();
+ return quote_id (
+ static_cast<sema_rel::table&> (fk.scope ()).name ().uname ()
+ + "_" + fk.name ());
}
virtual void
@@ -124,6 +126,20 @@ namespace relational
}
};
entry<create_table> create_table_;
+
+ struct create_index: relational::create_index, context
+ {
+ create_index (base const& x): base (x) {}
+
+ virtual string
+ name (sema_rel::index& in)
+ {
+ // In MySQL an index cannot be qualified with the database name.
+ //
+ return quote_id (in.name ().uname ());
+ }
+ };
+ entry<create_index> create_index_;
}
}
}
diff --git a/odb/relational/oracle/context.cxx b/odb/relational/oracle/context.cxx
index d477a19..bb76ee7 100644
--- a/odb/relational/oracle/context.cxx
+++ b/odb/relational/oracle/context.cxx
@@ -103,13 +103,26 @@ namespace relational
}
string context::
- quote_id_impl (string const& id) const
+ quote_id_impl (qname const& id) const
{
string r;
- r.reserve (32);
- r += '"';
- r.append (id, 0, 30);
- r += '"';
+
+ bool f (true);
+ for (qname::iterator i (id.begin ()); i < id.end (); ++i)
+ {
+ if (i->empty ())
+ continue;
+
+ if (f)
+ f = false;
+ else
+ r += '.';
+
+ r += '"';
+ r.append (*i, 0, 30); // Max identifier length is 30.
+ r += '"';
+ }
+
return r;
}
diff --git a/odb/relational/oracle/context.hxx b/odb/relational/oracle/context.hxx
index ea81136..e19264a 100644
--- a/odb/relational/oracle/context.hxx
+++ b/odb/relational/oracle/context.hxx
@@ -98,7 +98,7 @@ namespace relational
protected:
virtual string
- quote_id_impl (string const&) const;
+ quote_id_impl (qname const&) const;
protected:
virtual string
diff --git a/odb/relational/oracle/schema.cxx b/odb/relational/oracle/schema.cxx
index a371235..b98facc 100644
--- a/odb/relational/oracle/schema.cxx
+++ b/odb/relational/oracle/schema.cxx
@@ -94,7 +94,7 @@ namespace relational
drop_table (base const& x): base (x) {}
virtual void
- drop (string const& table)
+ drop (sema_rel::qname const& table)
{
// Oracle has no IF EXISTS conditional for dropping objects. The
// PL/SQL approach below seems to be the least error-prone and the
@@ -142,7 +142,7 @@ namespace relational
private:
friend class create_foreign_key;
- set<string> tables_; // Set of tables we have already defined.
+ set<qname> tables_; // Set of tables we have already defined.
};
entry<create_table> create_table_;
@@ -203,10 +203,12 @@ namespace relational
name (sema_rel::foreign_key& fk)
{
// In Oracle, foreign key names are schema-global. Make them
- // unique by prefixing the key name with table name.
+ // unique by prefixing the key name with table name. Note,
+ // however, that they cannot have a schema.
//
- return static_cast<sema_rel::table&> (fk.scope ()).name () +
- '_' + fk.name ();
+ return quote_id (
+ static_cast<sema_rel::table&> (fk.scope ()).name ().uname ()
+ + "_" + fk.name ());
}
};
entry<create_foreign_key> create_foreign_key_;
@@ -256,11 +258,11 @@ namespace relational
if (pk != 0 && pk->auto_ ())
{
- string const& tname (t.name ());
+ qname const& tname (t.name ());
string const& cname (pk->contains_begin ()->column ().name ());
- string seq_name (tname + "_seq");
- string trg_name (tname + "_trg");
+ qname seq_name (tname + "_seq");
+ qname trg_name (tname + "_trg");
// Sequence.
//
@@ -292,7 +294,7 @@ namespace relational
// Add foreign keys.
//
instance<add_foreign_key> fk (format_, *this);
- trav_rel::names n (*fk);
+ trav_rel::unames n (*fk);
names (t, n);
}
}
diff --git a/odb/relational/pgsql/schema.cxx b/odb/relational/pgsql/schema.cxx
index c723818..fc79c00 100644
--- a/odb/relational/pgsql/schema.cxx
+++ b/odb/relational/pgsql/schema.cxx
@@ -29,7 +29,7 @@ namespace relational
drop_table (base const& x): base (x) {}
virtual void
- drop (string const& table)
+ drop (sema_rel::qname const& table)
{
os << "DROP TABLE IF EXISTS " << quote_id (table) <<
" CASCADE" << endl;
@@ -52,7 +52,7 @@ namespace relational
private:
friend class create_foreign_key;
- set<string> tables_; // Set of tables we have already defined.
+ set<qname> tables_; // Set of tables we have already defined.
};
entry<create_table> create_table_;
@@ -163,9 +163,23 @@ namespace relational
// Add foreign keys.
//
instance<add_foreign_key> fk (format_, *this);
- trav_rel::names n (*fk);
+ trav_rel::unames n (*fk);
names (t, n);
}
+
+ struct create_index: relational::create_index, context
+ {
+ create_index (base const& x): base (x) {}
+
+ virtual string
+ name (sema_rel::index& in)
+ {
+ // In PostgreSQL indexes cannot have a schema.
+ //
+ return quote_id (in.name ().uname ());
+ }
+ };
+ entry<create_index> create_index_;
}
}
}
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx
index 8d80df0..da817b2 100644
--- a/odb/relational/processor.cxx
+++ b/odb/relational/processor.cxx
@@ -1431,7 +1431,7 @@ namespace relational
ep.kind = column_expr_part::reference;
ep.table = am.vo->alias.empty ()
? table_name (*am.vo->obj)
- : am.vo->alias;
+ : qname (am.vo->alias);
ep.member_path.push_back (am.m);
src_m = am.m;
@@ -1745,12 +1745,12 @@ namespace relational
else
obj_count++;
- tree n (TYPE_MAIN_VARIANT (i->node));
+ tree n (TYPE_MAIN_VARIANT (i->obj_node));
if (TREE_CODE (n) != RECORD_TYPE)
{
error (i->loc)
- << "name '" << i->orig_name << "' in db pragma object does "
+ << "name '" << i->obj_name << "' in db pragma object does "
<< "not name a class" << endl;
throw operation_failed ();
@@ -1761,11 +1761,11 @@ namespace relational
if (!object (o))
{
error (i->loc)
- << "name '" << i->orig_name << "' in db pragma object does "
+ << "name '" << i->obj_name << "' in db pragma object does "
<< "not name a persistent class" << endl;
info (o.file (), o.line (), o.column ())
- << "class '" << i->orig_name << "' is defined here" << endl;
+ << "class '" << i->obj_name << "' is defined here" << endl;
throw operation_failed ();
}
@@ -1777,7 +1777,7 @@ namespace relational
if (!omap.insert (view_object_map::value_type (n, &*i)).second)
{
error (i->loc)
- << "persistent class '" << i->orig_name << "' is used in "
+ << "persistent class '" << i->obj_name << "' is used in "
<< "the view more than once" << endl;
info (i->loc)
diff --git a/odb/relational/schema.cxx b/odb/relational/schema.cxx
index 8a06427..a8dc70c 100644
--- a/odb/relational/schema.cxx
+++ b/odb/relational/schema.cxx
@@ -44,7 +44,7 @@ namespace relational
{
instance<drop_model> model (*em, emos, f);
- trav_rel::names names;
+ trav_rel::qnames names;
instance<drop_table> table (*em, emos, f);
instance<drop_index> index (*em, emos, f);
@@ -70,7 +70,7 @@ namespace relational
//
{
instance<create_model> model (*em, emos, f);
- trav_rel::names names;
+ trav_rel::qnames names;
instance<create_table> table (*em, emos, f);
instance<create_index> index (*em, emos, f);
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index 81e1453..67d9a8c 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -121,7 +121,7 @@ namespace relational
}
virtual void
- drop (string const& table)
+ drop (sema_rel::qname const& table)
{
os << "DROP TABLE IF EXISTS " << quote_id (table) << endl;
}
@@ -161,7 +161,7 @@ namespace relational
}
virtual void
- drop (string const& /*index*/)
+ drop (sema_rel::qname const& /*index*/)
{
// Most database systems drop indexes together with the table.
//
@@ -418,7 +418,7 @@ namespace relational
{
using sema_rel::foreign_key;
- os << " CONSTRAINT " << quote_id (name (fk)) << endl
+ os << " CONSTRAINT " << name (fk) << endl
<< " FOREIGN KEY (";
for (foreign_key::contains_iterator i (fk.contains_begin ());
@@ -438,7 +438,7 @@ namespace relational
}
os << ")" << endl
- << " REFERENCES " << quote_id (fk.referenced_table ()) << " (";
+ << " REFERENCES " << table_name (fk) << " (";
foreign_key::columns const& refs (fk.referenced_columns ());
@@ -470,7 +470,13 @@ namespace relational
virtual string
name (sema_rel::foreign_key& fk)
{
- return fk.name ();
+ return quote_id (fk.name ());
+ }
+
+ virtual string
+ table_name (sema_rel::foreign_key& fk)
+ {
+ return quote_id (fk.referenced_table ());
}
virtual void
@@ -513,7 +519,7 @@ namespace relational
}
virtual void
- create_pre (string const& table)
+ create_pre (sema_rel::qname const& table)
{
os << "CREATE TABLE " << quote_id (table) << " (" << endl;
}
@@ -539,7 +545,7 @@ namespace relational
instance<create_column> c (format_, *this);
instance<create_primary_key> pk (format_, *this);
instance<create_foreign_key> fk (format_, *this);
- trav_rel::names n;
+ trav_rel::unames n;
n >> c;
n >> pk;
@@ -585,13 +591,25 @@ namespace relational
post_statement ();
}
+ virtual string
+ name (sema_rel::index& in)
+ {
+ return quote_id (in.name ());
+ }
+
+ virtual string
+ table_name (sema_rel::index& in)
+ {
+ return quote_id (in.table ().name ());
+ }
+
virtual void
create (sema_rel::index& in)
{
using sema_rel::index;
- os << "CREATE INDEX " << quote_id (in.name ()) << endl
- << " ON " << quote_id (in.table ().name ()) << " (";
+ os << "CREATE INDEX " << name (in) << endl
+ << " ON " << table_name (in) << " (";
for (index::contains_iterator i (in.contains_begin ());
i != in.contains_end ();
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index d909f7b..ff62257 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -350,7 +350,7 @@ namespace relational
protected:
statement_columns& sc_;
bool in_composite_;
- string table_prefix_; // Table corresponding to column_prefix_;
+ qname table_prefix_; // Table corresponding to column_prefix_;
};
struct object_joins: object_columns_base, virtual context
@@ -411,7 +411,7 @@ namespace relational
// This container is a direct member of the class so the table
// prefix is just the class table name.
//
- string const& ct (table_name (*c));
+ qname const& ct (table_name (*c));
table_prefix tp (ct + "_", 1);
t = table_qname (*im, tp);
string const& val (column_qname (*im, "value", "value"));
@@ -2818,7 +2818,7 @@ namespace relational
// table_name
//
os << "const char " << traits << "::table_name[] =" << endl
- << strlit (table_name (c)) << ";" // Use unquoted name.
+ << strlit (table_qname (c)) << ";" // Use quoted name.
<< endl;
}
@@ -3682,9 +3682,13 @@ namespace relational
if (i->kind != view_object::object)
continue; // Skip tables.
- if (!i->alias.empty () && i->alias != table_name (*i->obj))
+ qname const& t (table_name (*i->obj));
+
+ if (!i->alias.empty () &&
+ (t.qualified () || i->alias != t.uname ()))
os << "const char " << traits << "::query_columns::" << endl
- << i->alias << "_alias_[] = " << strlit (i->alias) << ";"
+ << i->alias << "_alias_[] = " <<
+ strlit (quote_id (i->alias)) << ";"
<< endl;
}
}
@@ -3702,9 +3706,12 @@ namespace relational
vo = &*i;
}
- if (!vo->alias.empty () && vo->alias != table_name (*vo->obj))
+ qname const& t (table_name (*vo->obj));
+
+ if (!vo->alias.empty () &&
+ (t.qualified () || vo->alias != t.uname ()))
os << "const char " << traits << "::" << endl
- << "query_alias[] = " << strlit (vo->alias) << ";"
+ << "query_alias[] = " << strlit (quote_id (vo->alias)) << ";"
<< endl;
}
}
@@ -3863,7 +3870,7 @@ namespace relational
if (first)
{
l = "FROM ";
- l += quote_id (i->orig_name);
+ l += quote_id (i->tbl_name);
if (!i->alias.empty ())
l += (need_alias_as ? " AS " : " ") + quote_id (i->alias);
@@ -3875,7 +3882,7 @@ namespace relational
}
l = "LEFT JOIN ";
- l += quote_id (i->orig_name);
+ l += quote_id (i->tbl_name);
if (!i->alias.empty ())
l += (need_alias_as ? " AS " : " ") + quote_id (i->alias);
@@ -4045,13 +4052,13 @@ namespace relational
// Left and right-hand side table names.
//
- string lt (e.vo->alias.empty ()
- ? table_name (*e.vo->obj)
- : e.vo->alias);
+ qname lt (e.vo->alias.empty ()
+ ? table_name (*e.vo->obj)
+ : qname (e.vo->alias));
- string rt (vo->alias.empty ()
- ? table_name (*vo->obj)
- : vo->alias);
+ qname rt (vo->alias.empty ()
+ ? table_name (*vo->obj)
+ : qname (vo->alias));
// First join the container table if necessary.
//
@@ -4532,12 +4539,12 @@ namespace relational
schema_emitter emitter_;
emitter_ostream stream_;
- trav_rel::names drop_names_;
+ trav_rel::qnames drop_names_;
instance<schema::drop_model> drop_model_;
instance<schema::drop_table> drop_table_;
instance<schema::drop_index> drop_index_;
- trav_rel::names create_names_;
+ trav_rel::qnames create_names_;
instance<schema::create_model> create_model_;
instance<schema::create_table> create_table_;
instance<schema::create_index> create_index_;
diff --git a/odb/relational/sqlite/schema.cxx b/odb/relational/sqlite/schema.cxx
index 6562905..15d37dc 100644
--- a/odb/relational/sqlite/schema.cxx
+++ b/odb/relational/sqlite/schema.cxx
@@ -34,6 +34,36 @@ namespace relational
}
};
entry<create_column> create_column_;
+
+ struct create_foreign_key: relational::create_foreign_key, context
+ {
+ create_foreign_key (base const& x): base (x) {}
+
+ virtual string
+ table_name (sema_rel::foreign_key& fk)
+ {
+ // In SQLite, the referenced table cannot be qualified with the
+ // database name (it has to be in the same database anyway).
+ //
+ return quote_id (fk.referenced_table ().uname ());
+ }
+ };
+ entry<create_foreign_key> create_foreign_key_;
+
+ struct create_index: relational::create_index, context
+ {
+ create_index (base const& x): base (x) {}
+
+ virtual string
+ table_name (sema_rel::index& in)
+ {
+ // In SQLite, the index table cannot be qualified with the
+ // database name (it has to be in the same database anyway).
+ //
+ return quote_id (in.table ().name ().uname ());
+ }
+ };
+ entry<create_index> create_index_;
}
}
}