summaryrefslogtreecommitdiff
path: root/odb/relational/schema-source.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-04-09 10:03:32 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-04-10 18:46:45 +0200
commit5ebd62ec778bc8c9540e2379e764ac52c060adfc (patch)
treeb751e62fe12599ee1a2553dc9331a03c8c957252 /odb/relational/schema-source.hxx
parent8295d4bd02946b7bdbff2a9cfa7763232e2d2fd0 (diff)
Generate embedded schema in single function instead of one per object
Diffstat (limited to 'odb/relational/schema-source.hxx')
-rw-r--r--odb/relational/schema-source.hxx119
1 files changed, 88 insertions, 31 deletions
diff --git a/odb/relational/schema-source.hxx b/odb/relational/schema-source.hxx
index 798738d..4ed5827 100644
--- a/odb/relational/schema-source.hxx
+++ b/odb/relational/schema-source.hxx
@@ -7,62 +7,119 @@
#include <odb/diagnostics.hxx>
+#include <odb/emitter.hxx>
#include <odb/relational/context.hxx>
#include <odb/relational/schema.hxx>
namespace relational
{
- namespace schema_source
+ namespace schema
{
- struct class_: traversal::class_, virtual context
+ struct cxx_emitter: emitter, virtual context
{
- typedef class_ base;
+ typedef cxx_emitter base;
- virtual void
- traverse (type& c)
+ void
+ pass (unsigned short p)
{
- if (!options.at_once () && class_file (c) != unit.file ())
- return;
-
- if (!object (c))
- return;
-
- if (abstract (c) && !polymorphic (c))
- return;
+ empty_ = true;
+ pass_ = p;
+ new_pass_ = true;
- os << "// " << class_name (c) << endl
- << "//" << endl
- << endl;
+ if (pass_ == 1)
+ empty_passes_ = 0; // New set of passes.
- schema_->traverse (c);
+ // Assume this pass is empty.
+ //
+ empty_passes_++;
}
- private:
- instance<schema::cxx_object> schema_;
- };
-
- struct include: virtual context
- {
- typedef include base;
+ // Did this pass produce anything?
+ //
+ bool
+ empty () const
+ {
+ return empty_;
+ }
virtual void
- generate ()
+ pre ()
{
- extra_pre ();
- os << "#include <odb/schema-catalog-impl.hxx>" << endl;
- extra_post ();
- os << endl;
+ first_ = true;
}
virtual void
- extra_pre ()
+ line (const string& l)
{
+ if (l.empty ())
+ return; // Ignore empty lines.
+
+ if (first_)
+ {
+ first_ = false;
+
+ // If this line starts a new pass, then output the switch/case
+ // blocks.
+ //
+ if (new_pass_)
+ {
+ new_pass_ = false;
+ empty_ = false;
+ empty_passes_--; // This pass is not empty.
+
+ // Output case statements for empty preceeding passes, if any.
+ //
+ if (empty_passes_ != 0)
+ {
+ unsigned short s (pass_ - empty_passes_);
+
+ if (s == 1)
+ os << "switch (pass)"
+ << "{";
+ else
+ os << "return true;" // One more pass.
+ << "}";
+
+ for (; s != pass_; ++s)
+ os << "case " << s << ":" << endl;
+
+ os << "{";
+ empty_passes_ = 0;
+ }
+
+ if (pass_ == 1)
+ os << "switch (pass)"
+ << "{";
+ else
+ os << "return true;" // One more pass.
+ << "}";
+
+ os << "case " << pass_ << ":" << endl
+ << "{";
+ }
+
+ os << "db.execute (";
+ }
+ else
+ os << strlit (line_ + '\n') << endl;
+
+ line_ = l;
}
virtual void
- extra_post ()
+ post ()
{
+ if (!first_) // Ignore empty statements.
+ os << strlit (line_) << ");";
}
+
+ private:
+ std::string line_;
+ bool first_;
+ bool empty_;
+ bool new_pass_;
+ unsigned short pass_;
+ unsigned short empty_passes_; // Number of preceding empty passes.
};
}
}