aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-09-13 12:21:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-09-13 12:21:06 +0200
commit519010bb77f813971570dceba068272ca2f5b600 (patch)
treec95fd514295184a88d4caf62ded3de78ba8f579c
parentdce27fe8994e819a463e83212779d3d43bd2ba2e (diff)
Add --sql-interlude and --sql-interlude-file options
-rw-r--r--NEWS4
-rw-r--r--odb/generator.cxx55
-rw-r--r--odb/options.cli18
-rw-r--r--odb/relational/generate.hxx11
-rw-r--r--odb/relational/schema.cxx86
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<path> 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<compiler::cxx_indenter, char> ind_filter;
typedef compiler::ostream_filter<compiler::sloc_counter, char> sloc_filter;
@@ -529,10 +537,6 @@ generate (options const& ops,
auto_ptr<context> 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 <text> at the beginning of the generated database schema file."
};
+ // Interludes.
+ //
+ std::vector<std::string> --sql-interlude
+ {
+ "<text>",
+ "Insert <text> after all the \cb{DROP} and before any \cb{CREATE}
+ statements in the generated database schema file."
+ };
+
// Epilogues.
//
std::vector<std::string> --hxx-epilogue
@@ -363,6 +372,15 @@ class options
database schema file."
};
+ // Interlude files.
+ //
+ std::string --sql-interlude-file
+ {
+ "<file>",
+ "Insert the content of <file> 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<sql_file> file;
file->prologue ();
+ }
+ void
+ generate_epilogue ()
+ {
+ instance<sql_file> file;
+ file->epilogue ();
+ }
+
+ void
+ generate_drop ()
+ {
+ context ctx;
instance<sql_emitter> em;
emitter_ostream emos (*em);
schema_format f (schema_format::sql);
- // Drop.
+ instance<drop_model> model (*em, emos, f);
+ instance<drop_table> table (*em, emos, f);
+ trav_rel::qnames names;
+
+ model >> names >> table;
+
+ // Pass 1 and 2.
//
+ for (unsigned short pass (1); pass < 3; ++pass)
{
- instance<drop_model> model (*em, emos, f);
- instance<drop_table> 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<sql_emitter> em;
+ emitter_ostream emos (*em);
- model->traverse (*ctx.model);
- }
- }
+ schema_format f (schema_format::sql);
- os << endl;
+ instance<create_model> model (*em, emos, f);
+ instance<create_table> 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<create_model> model (*em, emos, f);
- instance<create_table> 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 ();
}
}
}