aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-07-20 14:26:23 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-07-27 10:30:15 +0200
commitadfa9bbd04cd3571932ee7675344ca723bfa1eab (patch)
treec47487e8253d71ce0f2dd2e360f872e1e59a6cef
parent526f66e63f23afb40cc01550ca1a3a3592a84254 (diff)
Move indexes from model scope to table scope
Conceptually, indexes belong to tables and some databases (MySQL, MSSQL) indeed treat them as such (i.e., you can have indexes with the same name in different tables).
-rw-r--r--odb/relational/model.hxx7
-rw-r--r--odb/relational/mssql/schema.cxx14
-rw-r--r--odb/relational/mysql/schema.cxx14
-rw-r--r--odb/relational/oracle/schema.cxx20
-rw-r--r--odb/relational/pgsql/schema.cxx8
-rw-r--r--odb/relational/schema.cxx17
-rw-r--r--odb/relational/schema.hxx205
-rw-r--r--odb/relational/sqlite/schema.cxx20
-rw-r--r--odb/semantics/relational/elements.hxx8
-rw-r--r--odb/semantics/relational/foreign-key.hxx4
-rw-r--r--odb/semantics/relational/index.hxx19
-rw-r--r--odb/semantics/relational/key.hxx4
-rw-r--r--odb/semantics/relational/primary-key.hxx7
13 files changed, 164 insertions, 183 deletions
diff --git a/odb/relational/model.hxx b/odb/relational/model.hxx
index d41b701..b95425e 100644
--- a/odb/relational/model.hxx
+++ b/odb/relational/model.hxx
@@ -471,9 +471,7 @@ namespace relational
id_name += '_';
model_.new_edge<sema_rel::unames> (t, fk, id_name + "fk");
-
- model_.new_edge<sema_rel::qnames> (
- model_, in, name + "_" + id_name + "i");
+ model_.new_edge<sema_rel::unames> (t, in, id_name + "i");
}
// index (simple value)
@@ -492,8 +490,7 @@ namespace relational
model_.new_edge<sema_rel::contains> (
in, dynamic_cast<column&> (t.find (col_name)->nameable ()));
- model_.new_edge<sema_rel::qnames> (
- model_, in, name + "_" + col_name + "_i");
+ model_.new_edge<sema_rel::unames> (t, in, col_name + "_i");
}
// key
diff --git a/odb/relational/mssql/schema.cxx b/odb/relational/mssql/schema.cxx
index ebbda2c..47cb250 100644
--- a/odb/relational/mssql/schema.cxx
+++ b/odb/relational/mssql/schema.cxx
@@ -288,20 +288,6 @@ namespace relational
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/schema.cxx b/odb/relational/mysql/schema.cxx
index 6db30ad..4050d70 100644
--- a/odb/relational/mysql/schema.cxx
+++ b/odb/relational/mysql/schema.cxx
@@ -125,20 +125,6 @@ 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/schema.cxx b/odb/relational/oracle/schema.cxx
index ce2c470..29c1130 100644
--- a/odb/relational/oracle/schema.cxx
+++ b/odb/relational/oracle/schema.cxx
@@ -302,6 +302,26 @@ namespace relational
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 Oracle, index names are database-global. Make them unique
+ // by prefixing the index name with table name (preserving the
+ // schema).
+ //
+ sema_rel::qname n (
+ static_cast<sema_rel::table&> (in.scope ()).name ());
+
+ n.uname () += "_" + in.name ();
+ return quote_id (n);
+ }
+ };
+ entry<create_index> create_index_;
}
}
}
diff --git a/odb/relational/pgsql/schema.cxx b/odb/relational/pgsql/schema.cxx
index c774561..2113894 100644
--- a/odb/relational/pgsql/schema.cxx
+++ b/odb/relational/pgsql/schema.cxx
@@ -173,9 +173,13 @@ namespace relational
virtual string
name (sema_rel::index& in)
{
- // In PostgreSQL indexes cannot have a schema.
+ // In PostgreSQL, index names are database-global. Make them unique
+ // by prefixing the index name with table name. Note, however, that
+ // they cannot be qualified with the schema name.
//
- return quote_id (in.name ().uname ());
+ return quote_id (
+ static_cast<sema_rel::table&> (in.scope ()).name ().uname ()
+ + "_" + in.name ());
}
};
entry<create_index> create_index_;
diff --git a/odb/relational/schema.cxx b/odb/relational/schema.cxx
index ea9083d..3dd8507 100644
--- a/odb/relational/schema.cxx
+++ b/odb/relational/schema.cxx
@@ -45,15 +45,11 @@ namespace relational
// Drop.
//
{
-
instance<drop_model> model (*em, emos, f);
- trav_rel::qnames names;
instance<drop_table> table (*em, emos, f);
- instance<drop_index> index (*em, emos, f);
+ trav_rel::qnames names;
- model >> names;
- names >> table;
- names >> index;
+ model >> names >> table;
// Pass 1 and 2.
//
@@ -61,7 +57,6 @@ namespace relational
{
model->pass (pass);
table->pass (pass);
- index->pass (pass);
model->traverse (*ctx.model);
}
@@ -73,13 +68,10 @@ namespace relational
//
{
instance<create_model> model (*em, emos, f);
- trav_rel::qnames names;
instance<create_table> table (*em, emos, f);
- instance<create_index> index (*em, emos, f);
+ trav_rel::qnames names;
- model >> names;
- names >> table;
- names >> index;
+ model >> names >> table;
// Pass 1 and 2.
//
@@ -87,7 +79,6 @@ namespace relational
{
model->pass (pass);
table->pass (pass);
- index->pass (pass);
model->traverse (*ctx.model);
}
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index 4f31dca..6551119 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -58,65 +58,65 @@ namespace relational
// Drop.
//
- struct drop_table: trav_rel::table, common
+ struct drop_index: trav_rel::index, common
{
- typedef drop_table base;
+ typedef drop_index base;
- drop_table (emitter_type& e, ostream& os, schema_format f)
+ drop_index (emitter_type& e, ostream& os, schema_format f)
: common (e, os), format_ (f)
{
}
- virtual void
- drop (sema_rel::qname const& table)
+ virtual string
+ name (sema_rel::index& in)
{
- os << "DROP TABLE IF EXISTS " << quote_id (table) << endl;
+ return quote_id (in.name ());
+ }
+
+ virtual string
+ table_name (sema_rel::index& in)
+ {
+ return quote_id (static_cast<sema_rel::table&> (in.scope ()).name ());
}
virtual void
- traverse (sema_rel::table& t)
+ drop (string const& /*name*/, string const& /*table*/)
{
- // By default we do everything in a single pass. But some
- // databases may require the second pass.
+ // Most database systems drop indexes together with the table.
//
- if (pass_ > 1)
- return;
-
- pre_statement ();
- drop (t.name ());
- post_statement ();
+ // os << "DROP INDEX IF EXISTS " << quote_id (name) << " ON " <<
+ // table << endl;
}
- void
- pass (unsigned short p)
+ virtual void
+ traverse (sema_rel::index& in)
{
- pass_ = p;
+ pre_statement ();
+ drop (name (in), table_name (in));
+ post_statement ();
}
protected:
schema_format format_;
- unsigned short pass_;
};
- struct drop_index: trav_rel::index, common
+ struct drop_table: trav_rel::table, common
{
- typedef drop_index base;
+ typedef drop_table base;
- drop_index (emitter_type& e, ostream& os, schema_format f)
+ drop_table (emitter_type& e, ostream& os, schema_format f)
: common (e, os), format_ (f)
{
}
virtual void
- drop (sema_rel::qname const& /*index*/)
+ drop (sema_rel::qname const& table)
{
- // Most database systems drop indexes together with the table.
- //
- //os << "DROP INDEX IF EXISTS " << quote_id (index);
+ os << "DROP TABLE IF EXISTS " << quote_id (table) << endl;
}
virtual void
- traverse (sema_rel::index& in)
+ traverse (sema_rel::table& t)
{
// By default we do everything in a single pass. But some
// databases may require the second pass.
@@ -124,8 +124,16 @@ namespace relational
if (pass_ > 1)
return;
+ // Drop indexes.
+ //
+ {
+ instance<drop_index> in (emitter (), stream (), format_);
+ trav_rel::unames n (*in);
+ names (t, n);
+ }
+
pre_statement ();
- drop (in.name ());
+ drop (t.name ());
post_statement ();
}
@@ -456,65 +464,6 @@ namespace relational
create_table& create_table_;
};
- struct create_table: trav_rel::table, common
- {
- typedef create_table base;
-
- create_table (emitter_type& e, ostream& os, schema_format f)
- : common (e, os), format_ (f)
- {
- }
-
- virtual void
- create_pre (sema_rel::qname const& table)
- {
- os << "CREATE TABLE " << quote_id (table) << " (" << endl;
- }
-
- virtual void
- create_post ()
- {
- os << ")" << endl;
- }
-
- virtual void
- traverse (sema_rel::table& t)
- {
- // By default we do everything in a single pass. But some
- // databases may require the second pass.
- //
- if (pass_ > 1)
- return;
-
- pre_statement ();
- create_pre (t.name ());
-
- instance<create_column> c (format_, *this);
- instance<create_primary_key> pk (format_, *this);
- instance<create_foreign_key> fk (format_, *this);
- trav_rel::unames n;
-
- n >> c;
- n >> pk;
- n >> fk;
-
- names (t, n);
-
- create_post ();
- post_statement ();
- }
-
- void
- pass (unsigned short p)
- {
- pass_ = p;
- }
-
- protected:
- schema_format format_;
- unsigned short pass_;
- };
-
struct create_index: trav_rel::index, common
{
typedef create_index base;
@@ -527,12 +476,6 @@ namespace relational
virtual void
traverse (sema_rel::index& in)
{
- // By default we do everything in a single pass. But some
- // databases may require the second pass.
- //
- if (pass_ > 1)
- return;
-
pre_statement ();
create (in);
post_statement ();
@@ -547,7 +490,7 @@ namespace relational
virtual string
table_name (sema_rel::index& in)
{
- return quote_id (in.table ().name ());
+ return quote_id (static_cast<sema_rel::table&> (in.scope ()).name ());
}
virtual void
@@ -577,6 +520,66 @@ namespace relational
os << ")" << endl;
}
+ protected:
+ schema_format format_;
+ };
+
+ struct create_table: trav_rel::table, common
+ {
+ typedef create_table base;
+
+ create_table (emitter_type& e, ostream& os, schema_format f)
+ : common (e, os), format_ (f)
+ {
+ }
+
+ virtual void
+ create_pre (sema_rel::qname const& table)
+ {
+ os << "CREATE TABLE " << quote_id (table) << " (" << endl;
+ }
+
+ virtual void
+ create_post ()
+ {
+ os << ")" << endl;
+ }
+
+ virtual void
+ traverse (sema_rel::table& t)
+ {
+ // By default we do everything in a single pass. But some
+ // databases may require the second pass.
+ //
+ if (pass_ > 1)
+ return;
+
+ pre_statement ();
+ create_pre (t.name ());
+
+ instance<create_column> c (format_, *this);
+ instance<create_primary_key> pk (format_, *this);
+ instance<create_foreign_key> fk (format_, *this);
+ trav_rel::unames n;
+
+ n >> c;
+ n >> pk;
+ n >> fk;
+
+ names (t, n);
+
+ create_post ();
+ post_statement ();
+
+ // Create indexes.
+ //
+ {
+ instance<create_index> in (emitter (), stream (), format_);
+ trav_rel::unames n (*in);
+ names (t, n);
+ }
+ }
+
void
pass (unsigned short p)
{
@@ -799,10 +802,8 @@ namespace relational
: stream_ (*emitter_),
drop_model_ (*emitter_, stream_, format_embedded),
drop_table_ (*emitter_, stream_, format_embedded),
- drop_index_ (*emitter_, stream_, format_embedded),
create_model_ (*emitter_, stream_, format_embedded),
- create_table_ (*emitter_, stream_, format_embedded),
- create_index_ (*emitter_, stream_, format_embedded)
+ create_table_ (*emitter_, stream_, format_embedded)
{
init ();
}
@@ -813,10 +814,8 @@ namespace relational
stream_ (*emitter_),
drop_model_ (*emitter_, stream_, format_embedded),
drop_table_ (*emitter_, stream_, format_embedded),
- drop_index_ (*emitter_, stream_, format_embedded),
create_model_ (*emitter_, stream_, format_embedded),
- create_table_ (*emitter_, stream_, format_embedded),
- create_index_ (*emitter_, stream_, format_embedded)
+ create_table_ (*emitter_, stream_, format_embedded)
{
init ();
}
@@ -826,11 +825,9 @@ namespace relational
{
drop_model_ >> drop_names_;
drop_names_ >> drop_table_;
- drop_names_ >> drop_index_;
create_model_ >> create_names_;
create_names_ >> create_table_;
- create_names_ >> create_index_;
}
void
@@ -872,7 +869,6 @@ namespace relational
emitter_->pass (pass);
drop_model_->pass (pass);
drop_table_->pass (pass);
- drop_index_->pass (pass);
drop_model_->traverse (begin, end);
@@ -900,7 +896,6 @@ namespace relational
emitter_->pass (pass);
create_model_->pass (pass);
create_table_->pass (pass);
- create_index_->pass (pass);
create_model_->traverse (begin, end);
@@ -932,12 +927,10 @@ namespace relational
trav_rel::qnames drop_names_;
instance<drop_model> drop_model_;
instance<drop_table> drop_table_;
- instance<drop_index> drop_index_;
trav_rel::qnames create_names_;
instance<create_model> create_model_;
instance<create_table> create_table_;
- instance<create_index> create_index_;
};
}
}
diff --git a/odb/relational/sqlite/schema.cxx b/odb/relational/sqlite/schema.cxx
index b20c7da..8efef66 100644
--- a/odb/relational/sqlite/schema.cxx
+++ b/odb/relational/sqlite/schema.cxx
@@ -54,13 +54,29 @@ namespace relational
create_index (base const& x): base (x) {}
virtual string
+ name (sema_rel::index& in)
+ {
+ // In SQLite, index names are database-global. Make them unique
+ // by prefixing the index name with table name (preserving the
+ // database).
+ //
+ sema_rel::qname n (
+ static_cast<sema_rel::table&> (in.scope ()).name ());
+
+ n.uname () += "_" + in.name ();
+ return quote_id (n);
+ }
+
+ 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).
+ // database name (it has to be in the same database).
//
- return quote_id (in.table ().name ().uname ());
+ return quote_id (
+ static_cast<sema_rel::table&> (in.scope ()).name ().uname ());
}
+
};
entry<create_index> create_index_;
}
diff --git a/odb/semantics/relational/elements.hxx b/odb/semantics/relational/elements.hxx
index 6b4964e..8eb695a 100644
--- a/odb/semantics/relational/elements.hxx
+++ b/odb/semantics/relational/elements.hxx
@@ -174,10 +174,10 @@ namespace semantics
public:
// Id identifies the C++ node (e.g., a class or a data member) that
// this model node corresponds to. The ids are not necessarily unique
- // (e.g., there can be a table and an index with the same id that
- // correspond to a container member). However, in any given scope,
- // the {id,typeid} must be unique. This becomes important when we
- // try to find correspondance between nodes during model diff'ing.
+ // (e.g., there can be a foreign key and an index with the same id that
+ // correspond to a container member). However, in any given scope, the
+ // {id,typeid} must be unique. This becomes important when we try to
+ // find correspondance between nodes during model diff'ing.
//
nameable (string const& id): id_ (id), named_ (0) {}
diff --git a/odb/semantics/relational/foreign-key.hxx b/odb/semantics/relational/foreign-key.hxx
index 83b7071..871c036 100644
--- a/odb/semantics/relational/foreign-key.hxx
+++ b/odb/semantics/relational/foreign-key.hxx
@@ -12,7 +12,7 @@ namespace semantics
{
namespace relational
{
- class foreign_key: public unameable, public key
+ class foreign_key: public key
{
public:
enum action
@@ -25,7 +25,7 @@ namespace semantics
qname const& referenced_table,
bool deferred,
action on_delete = no_action)
- : unameable (id),
+ : key (id),
referenced_table_ (referenced_table),
deferred_ (deferred),
on_delete_ (on_delete)
diff --git a/odb/semantics/relational/index.hxx b/odb/semantics/relational/index.hxx
index dcb8e6e..af90b12 100644
--- a/odb/semantics/relational/index.hxx
+++ b/odb/semantics/relational/index.hxx
@@ -6,31 +6,18 @@
#define ODB_SEMANTICS_RELATIONAL_INDEX_HXX
#include <odb/semantics/relational/elements.hxx>
-#include <odb/semantics/relational/column.hxx>
#include <odb/semantics/relational/key.hxx>
-#include <odb/semantics/relational/table.hxx>
namespace semantics
{
namespace relational
{
- // Note that unlike other keys, indexes are defined in the model
- // scope, not table scope.
+ // Note that in our model indexes are defined in the table scope.
//
- class index: public qnameable, public key
+ class index: public key
{
public:
- relational::table&
- table () const
- {
- return contains_begin ()->column ().table ();
- }
-
- public:
- index (string const& id)
- : qnameable (id)
- {
- }
+ index (string const& id): key (id) {}
virtual string
kind () const
diff --git a/odb/semantics/relational/key.hxx b/odb/semantics/relational/key.hxx
index f5184be..40e7499 100644
--- a/odb/semantics/relational/key.hxx
+++ b/odb/semantics/relational/key.hxx
@@ -50,7 +50,7 @@ namespace semantics
column_type* column_;
};
- class key: public virtual node
+ class key: public unameable
{
typedef std::vector<contains*> contains_list;
@@ -78,6 +78,8 @@ namespace semantics
}
public:
+ key (std::string const& id): unameable (id) {}
+
void
add_edge_left (contains& e)
{
diff --git a/odb/semantics/relational/primary-key.hxx b/odb/semantics/relational/primary-key.hxx
index e35b00f..0aec038 100644
--- a/odb/semantics/relational/primary-key.hxx
+++ b/odb/semantics/relational/primary-key.hxx
@@ -12,7 +12,7 @@ namespace semantics
{
namespace relational
{
- class primary_key: public unameable, public key
+ class primary_key: public key
{
public:
bool
@@ -23,9 +23,8 @@ namespace semantics
public:
primary_key (bool auto_)
- // Primary key has the implicit empty id.
- //
- : unameable (""), auto__ (auto_)
+ : key (""), // Primary key has the implicit empty id.
+ auto__ (auto_)
{
}