aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-04-09 16:17:27 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-04-10 18:46:45 +0200
commit399f1212596a4ffa506fcc0e630ade33951b00db (patch)
tree93d4430369ab8a82800299502df571f3d80e1f0e
parent458779f49a789e403cf108ac04b6fa035cb06810 (diff)
Add support for embedded schema migration
-rw-r--r--odb/generator.cxx4
-rw-r--r--odb/relational/generate.hxx2
-rw-r--r--odb/relational/schema-source.cxx124
3 files changed, 121 insertions, 9 deletions
diff --git a/odb/generator.cxx b/odb/generator.cxx
index 1a81780..1ca094f 100644
--- a/odb/generator.cxx
+++ b/odb/generator.cxx
@@ -685,7 +685,7 @@ generate (options const& ops,
if (gen_schema &&
ops.schema_format ()[db].count (schema_format::embedded))
- relational::schema::generate_source ();
+ relational::schema::generate_source (changelog.get ());
break;
}
@@ -749,7 +749,7 @@ generate (options const& ops,
case database::pgsql:
case database::sqlite:
{
- relational::schema::generate_source ();
+ relational::schema::generate_source (changelog.get ());
break;
}
case database::common:
diff --git a/odb/relational/generate.hxx b/odb/relational/generate.hxx
index 3cbc363..864f241 100644
--- a/odb/relational/generate.hxx
+++ b/odb/relational/generate.hxx
@@ -75,7 +75,7 @@ namespace relational
// Generate embedded schema.
//
void
- generate_source ();
+ generate_source (semantics::relational::changelog*);
}
}
diff --git a/odb/relational/schema-source.cxx b/odb/relational/schema-source.cxx
index e20529d..d54ae02 100644
--- a/odb/relational/schema-source.cxx
+++ b/odb/relational/schema-source.cxx
@@ -12,7 +12,7 @@ namespace relational
namespace schema
{
void
- generate_source ()
+ generate_source (sema_rel::changelog* log)
{
context ctx;
ostream& os (ctx.os);
@@ -21,15 +21,22 @@ namespace relational
sema_rel::model& model (*ctx.model);
string const& schema_name (ops.schema_name ()[db]);
+ if (log != 0 && log->contains_changeset_empty ())
+ log = 0;
+
instance<cxx_emitter> emitter;
emitter_ostream emitter_os (*emitter);
schema_format format (schema_format::embedded);
+ if (!model.names_empty () || log != 0)
+ os << "namespace odb"
+ << "{";
+
+ // Schema.
+ //
if (!model.names_empty ())
{
- os << "namespace odb"
- << "{"
- << "static bool" << endl
+ os << "static bool" << endl
<< "create_schema (database& db, unsigned short pass, bool drop)"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (db);"
@@ -110,15 +117,120 @@ namespace relational
os << "return false;"
<< "}";
- os << "static const schema_catalog_entry" << endl
+ os << "static const schema_catalog_create_entry" << endl
<< "create_schema_entry_ (" << endl
<< "id_" << db << "," << endl
<< context::strlit (schema_name) << "," << endl
<< "&create_schema);"
<< endl;
+ }
+
+ // Migration.
+ //
+ if (log != 0)
+ {
+ for (sema_rel::changelog::contains_changeset_iterator i (
+ log->contains_changeset_begin ());
+ i != log->contains_changeset_end (); ++i)
+ {
+ sema_rel::changeset& cs (i->changeset ());
+
+ os << "static bool" << endl
+ << "migrate_schema_" << cs.version () << " (database& db, " <<
+ "unsigned short pass, bool pre)"
+ << "{"
+ << "ODB_POTENTIALLY_UNUSED (db);"
+ << "ODB_POTENTIALLY_UNUSED (pass);"
+ << "ODB_POTENTIALLY_UNUSED (pre);"
+ << endl;
+
+ // Pre.
+ //
+ {
+ bool close (false);
+
+ os << "if (pre)"
+ << "{";
+
+ instance<changeset_pre> changeset (*emitter, emitter_os, format);
+ instance<create_table> ctable (*emitter, emitter_os, format);
+ instance<alter_table_pre> atable (*emitter, emitter_os, format);
+ trav_rel::qnames names;
+ changeset >> names;
+ names >> ctable;
+ names >> atable;
+
+ for (unsigned short pass (1); pass < 3; ++pass)
+ {
+ emitter->pass (pass);
+ changeset->pass (pass);
+ ctable->pass (pass);
+ atable->pass (pass);
+
+ changeset->traverse (cs);
+
+ close = close || !emitter->empty ();
+ }
+
+ if (close) // Close the last case and the switch block.
+ os << "return false;"
+ << "}" // case
+ << "}"; // switch
- os << "}";
+ os << "}";
+ }
+
+ // Post.
+ //
+ {
+ bool close (false);
+
+ os << "else"
+ << "{";
+
+ instance<changeset_post> changeset (*emitter, emitter_os, format);
+ instance<drop_table> dtable (*emitter, emitter_os, format);
+ instance<alter_table_post> atable (*emitter, emitter_os, format);
+ trav_rel::qnames names;
+ changeset >> names;
+ names >> dtable;
+ names >> atable;
+
+ for (unsigned short pass (1); pass < 3; ++pass)
+ {
+ emitter->pass (pass);
+ changeset->pass (pass);
+ dtable->pass (pass);
+ atable->pass (pass);
+
+ changeset->traverse (cs);
+
+ close = close || !emitter->empty ();
+ }
+
+ if (close) // Close the last case and the switch block.
+ os << "return false;"
+ << "}" // case
+ << "}"; // switch
+
+ os << "}";
+ }
+
+ os << "return false;"
+ << "}";
+
+ os << "static const schema_catalog_migrate_entry" << endl
+ << "migrate_schema_entry_" << cs.version () << "_ (" << endl
+ << "id_" << db << "," << endl
+ << context::strlit (schema_name) << "," << endl
+ << cs.version () << "ULL," << endl
+ << "&migrate_schema_" << cs.version () << ");"
+ << endl;
+ }
}
+
+ if (!model.names_empty () || log != 0)
+ os << "}"; // namespace odb
}
}
}