diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-09 10:03:32 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-04-10 18:46:45 +0200 |
commit | 5ebd62ec778bc8c9540e2379e764ac52c060adfc (patch) | |
tree | b751e62fe12599ee1a2553dc9331a03c8c957252 /odb/relational/schema-source.hxx | |
parent | 8295d4bd02946b7bdbff2a9cfa7763232e2d2fd0 (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.hxx | 119 |
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. }; } } |