From 519010bb77f813971570dceba068272ca2f5b600 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 13 Sep 2012 12:21:06 +0200 Subject: Add --sql-interlude and --sql-interlude-file options --- NEWS | 4 +++ odb/generator.cxx | 55 +++++++++++++++++++++-------- odb/options.cli | 18 ++++++++++ odb/relational/generate.hxx | 11 +++++- odb/relational/schema.cxx | 86 ++++++++++++++++++++++----------------------- 5 files changed, 116 insertions(+), 58 deletions(-) diff --git a/NEWS b/NEWS index a9c8613..475765d 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,10 @@ Version 2.1.0 the ODB compiler command line interface documentation (man pages) for details. + * New options, --sql-interlude and --sql-interlude-file, allow the insertion + of custom SQL between the DROP and CREATE statements in the generated + database schema file. + * New ODB manual section, 6.3 "Circular Relationships", explains how to handle persistent classes with circular dependencies that are defined in separate headers. diff --git a/odb/generator.cxx b/odb/generator.cxx index 630d320..8b03006 100644 --- a/odb/generator.cxx +++ b/odb/generator.cxx @@ -29,11 +29,16 @@ typedef vector paths; namespace { - static char const file_header[] = + static char const cxx_file_header[] = "// This file was generated by ODB, object-relational mapping (ORM)\n" "// compiler for C++.\n" "//\n\n"; + static char const sql_file_header[] = + "/* This file was generated by ODB, object-relational mapping (ORM)\n" + " * compiler for C++.\n" + " */\n\n"; + void open (ifstream& ifs, string const& path) { @@ -228,13 +233,16 @@ generate (options const& ops, // if (gen_cxx) { - hxx << file_header; - ixx << file_header; - cxx << file_header; + hxx << cxx_file_header; + ixx << cxx_file_header; + cxx << cxx_file_header; } if (gen_sep_schema) - sch << file_header; + sch << cxx_file_header; + + if (gen_sql_schema) + sql << sql_file_header; typedef compiler::ostream_filter ind_filter; typedef compiler::ostream_filter sloc_filter; @@ -529,10 +537,6 @@ generate (options const& ops, auto_ptr ctx ( create_context (sql, unit, ops, fts, model.get ())); - // Copy prologue. - // - append (sql, ops.sql_prologue (), ops.sql_prologue_file ()); - switch (ops.database ()) { case database::mssql: @@ -541,14 +545,37 @@ generate (options const& ops, case database::pgsql: case database::sqlite: { - relational::schema::generate (); + relational::schema::generate_prologue (); + + sql << "/* Begin prologue." << endl + << " */" << endl; + append (sql, ops.sql_prologue (), ops.sql_prologue_file ()); + sql << "/*" << endl + << " * End prologue. */" << endl + << endl; + + relational::schema::generate_drop (); + + sql << "/* Begin interlude." << endl + << " */" << endl; + append (sql, ops.sql_interlude (), ops.sql_interlude_file ()); + sql << "/*" << endl + << " * End interlude. */" << endl + << endl; + + relational::schema::generate_create (); + + sql << "/* Begin epilogue." << endl + << " */" << endl; + append (sql, ops.sql_epilogue (), ops.sql_epilogue_file ()); + sql << "/*" << endl + << " * End epilogue. */" << endl + << endl; + + relational::schema::generate_epilogue (); break; } } - - // Copy epilogue. - // - append (sql, ops.sql_epilogue (), ops.sql_epilogue_file ()); } // Communicate the sloc count to the driver. This is necessary to diff --git a/odb/options.cli b/odb/options.cli index e9d76dd..6740572 100644 --- a/odb/options.cli +++ b/odb/options.cli @@ -294,6 +294,15 @@ class options "Insert at the beginning of the generated database schema file." }; + // Interludes. + // + std::vector --sql-interlude + { + "", + "Insert after all the \cb{DROP} and before any \cb{CREATE} + statements in the generated database schema file." + }; + // Epilogues. // std::vector --hxx-epilogue @@ -363,6 +372,15 @@ class options database schema file." }; + // Interlude files. + // + std::string --sql-interlude-file + { + "", + "Insert the content of after all the \cb{DROP} and before any + \cb{CREATE} statements in the generated database schema file." + }; + // Epilogue files. // std::string --hxx-epilogue-file diff --git a/odb/relational/generate.hxx b/odb/relational/generate.hxx index fb29bf4..a895e91 100644 --- a/odb/relational/generate.hxx +++ b/odb/relational/generate.hxx @@ -44,7 +44,16 @@ namespace relational namespace schema { void - generate (); + generate_prologue (); + + void + generate_drop (); + + void + generate_create (); + + void + generate_epilogue (); } } diff --git a/odb/relational/schema.cxx b/odb/relational/schema.cxx index 3dd8507..5c0bdf9 100644 --- a/odb/relational/schema.cxx +++ b/odb/relational/schema.cxx @@ -21,70 +21,70 @@ namespace relational // schema_format cxx_object::format_embedded (schema_format::embedded); - static char const file_header[] = - "/* This file was generated by ODB, object-relational mapping (ORM)\n" - " * compiler for C++.\n" - " */\n\n"; - void - generate () + generate_prologue () { - context ctx; - ostream& os (ctx.os); - - os << file_header; - instance file; file->prologue (); + } + void + generate_epilogue () + { + instance file; + file->epilogue (); + } + + void + generate_drop () + { + context ctx; instance em; emitter_ostream emos (*em); schema_format f (schema_format::sql); - // Drop. + instance model (*em, emos, f); + instance table (*em, emos, f); + trav_rel::qnames names; + + model >> names >> table; + + // Pass 1 and 2. // + for (unsigned short pass (1); pass < 3; ++pass) { - instance model (*em, emos, f); - instance table (*em, emos, f); - trav_rel::qnames names; + model->pass (pass); + table->pass (pass); - model >> names >> table; + model->traverse (*ctx.model); + } + } - // Pass 1 and 2. - // - for (unsigned short pass (1); pass < 3; ++pass) - { - model->pass (pass); - table->pass (pass); + void + generate_create () + { + context ctx; + instance em; + emitter_ostream emos (*em); - model->traverse (*ctx.model); - } - } + schema_format f (schema_format::sql); - os << endl; + instance model (*em, emos, f); + instance table (*em, emos, f); + trav_rel::qnames names; - // Create. + model >> names >> table; + + // Pass 1 and 2. // + for (unsigned short pass (1); pass < 3; ++pass) { - instance model (*em, emos, f); - instance table (*em, emos, f); - trav_rel::qnames names; - - model >> names >> table; + model->pass (pass); + table->pass (pass); - // Pass 1 and 2. - // - for (unsigned short pass (1); pass < 3; ++pass) - { - model->pass (pass); - table->pass (pass); - - model->traverse (*ctx.model); - } + model->traverse (*ctx.model); } - - file->epilogue (); } } } -- cgit v1.1