From 399f1212596a4ffa506fcc0e630ade33951b00db Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 9 Apr 2013 16:17:27 +0200 Subject: Add support for embedded schema migration --- odb/generator.cxx | 4 +- odb/relational/generate.hxx | 2 +- odb/relational/schema-source.cxx | 124 +++++++++++++++++++++++++++++++++++++-- 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 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 (*emitter, emitter_os, format); + instance ctable (*emitter, emitter_os, format); + instance 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 (*emitter, emitter_os, format); + instance dtable (*emitter, emitter_os, format); + instance 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 } } } -- cgit v1.1