diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-01-26 12:43:16 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-01-26 12:43:16 +0200 |
commit | af12ffe836de09ec84f666effa4df347eeb07a43 (patch) | |
tree | dc0aec9f8fee545c84be098414772cf2b277c30d /odb/relational | |
parent | c1d2ec5bbd5969332f3278f39d2a7a8f0abc0493 (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.cxx | 9 | ||||
-rw-r--r-- | odb/relational/context.cxx | 23 | ||||
-rw-r--r-- | odb/relational/context.hxx | 5 | ||||
-rw-r--r-- | odb/relational/context.ixx | 6 | ||||
-rw-r--r-- | odb/relational/header.hxx | 6 | ||||
-rw-r--r-- | odb/relational/model.cxx | 14 | ||||
-rw-r--r-- | odb/relational/model.hxx | 26 | ||||
-rw-r--r-- | odb/relational/mssql/context.cxx | 23 | ||||
-rw-r--r-- | odb/relational/mssql/context.hxx | 2 | ||||
-rw-r--r-- | odb/relational/mssql/schema.cxx | 32 | ||||
-rw-r--r-- | odb/relational/mysql/context.cxx | 23 | ||||
-rw-r--r-- | odb/relational/mysql/context.hxx | 2 | ||||
-rw-r--r-- | odb/relational/mysql/schema.cxx | 22 | ||||
-rw-r--r-- | odb/relational/oracle/context.cxx | 23 | ||||
-rw-r--r-- | odb/relational/oracle/context.hxx | 2 | ||||
-rw-r--r-- | odb/relational/oracle/schema.cxx | 20 | ||||
-rw-r--r-- | odb/relational/pgsql/schema.cxx | 20 | ||||
-rw-r--r-- | odb/relational/processor.cxx | 12 | ||||
-rw-r--r-- | odb/relational/schema.cxx | 4 | ||||
-rw-r--r-- | odb/relational/schema.hxx | 36 | ||||
-rw-r--r-- | odb/relational/source.hxx | 41 | ||||
-rw-r--r-- | odb/relational/sqlite/schema.cxx | 30 |
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_; } } } |