diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2010-11-01 09:01:50 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2010-11-01 09:01:50 +0200 |
commit | 727a83dc82fa094aa91630d165d230a9a2dabe60 (patch) | |
tree | cf908eef97e4fd5518359bc90dc5839c829475ff | |
parent | 56237544eeed76a55190b3fd7cc364d133d4513d (diff) |
Factor assignment of database type to separate pass
-rw-r--r-- | odb/context.cxx | 16 | ||||
-rw-r--r-- | odb/context.hxx | 8 | ||||
-rw-r--r-- | odb/generator.cxx | 30 | ||||
-rw-r--r-- | odb/makefile | 1 | ||||
-rw-r--r-- | odb/mysql/context.cxx | 4 | ||||
-rw-r--r-- | odb/mysql/context.hxx | 11 | ||||
-rw-r--r-- | odb/type-processor.cxx | 97 | ||||
-rw-r--r-- | odb/type-processor.hxx | 16 |
8 files changed, 166 insertions, 17 deletions
diff --git a/odb/context.cxx b/odb/context.cxx index c578cd9..1eb597f 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -159,6 +159,12 @@ column_name (semantics::data_member& m) const string context:: column_type (semantics::data_member& m) const { + return m.get<string> ("column-type"); +} + +string context:: +column_type_impl (semantics::data_member& m) const +{ if (m.count ("type")) return m.get<string> ("type"); @@ -176,15 +182,7 @@ column_type (semantics::data_member& m) const if (i != data_->type_map_.end ()) return m.count ("id") ? i->second.id_type : i->second.type; - cerr << m.file () << ":" << m.line () << ":" << m.column () << ":" - << " error: unable to map C++ type '" << name << "' used in " - << "data member '" << m.name () << "' to a database type" << endl; - - cerr << m.file () << ":" << m.line () << ":" << m.column () << ":" - << " info: use '#pragma db type' to specify the database type" - << endl; - - throw generation_failed (); + return string (); } string context:: diff --git a/odb/context.hxx b/odb/context.hxx index b8a33c5..1a1595d 100644 --- a/odb/context.hxx +++ b/odb/context.hxx @@ -87,6 +87,14 @@ public: static size_t column_count (semantics::class_&); + // Per-database customizable functionality. + // +public: + // Return empty string if there is no mapping. + // + virtual string + column_type_impl (semantics::data_member&) const; + protected: struct data; typedef cutl::shared_ptr<data> data_ptr; diff --git a/odb/generator.cxx b/odb/generator.cxx index 5d8c47c..be01886 100644 --- a/odb/generator.cxx +++ b/odb/generator.cxx @@ -18,6 +18,8 @@ #include <odb/context.hxx> #include <odb/generator.hxx> +#include <odb/type-processor.hxx> + #include <odb/include.hxx> #include <odb/header.hxx> #include <odb/inline.hxx> @@ -108,13 +110,37 @@ generate (options const& ops, semantics::unit& unit, path const& p) { try { + // Process types. + // + { + auto_ptr<context> ctx; + + switch (ops.database ()) + { + case database::mysql: + { + ctx.reset (new mysql::context (cerr, unit, ops)); + break; + } + case database::tracer: + { + // Do not assign database types for tracer. + // + break; + } + } + + if (ctx.get () != 0) + process_types (*ctx); + } + + // Output files. + // path file (p.leaf ()); string base (file.base ().string ()); fs::auto_removes auto_rm; - // C++ output. - // string hxx_name (base + ops.odb_file_suffix () + ops.hxx_suffix ()); string ixx_name (base + ops.odb_file_suffix () + ops.ixx_suffix ()); string cxx_name (base + ops.odb_file_suffix () + ops.cxx_suffix ()); diff --git a/odb/makefile b/odb/makefile index c6cec8c..761dcb0 100644 --- a/odb/makefile +++ b/odb/makefile @@ -11,6 +11,7 @@ cxx_ptun := \ sql-lexer.cxx \ context.cxx \ common.cxx \ +type-processor.cxx \ include.cxx \ header.cxx \ inline.cxx \ diff --git a/odb/mysql/context.cxx b/odb/mysql/context.cxx index f33916e..e896f68 100644 --- a/odb/mysql/context.cxx +++ b/odb/mysql/context.cxx @@ -184,9 +184,9 @@ namespace mysql // string context:: - column_type (semantics::data_member& m) const + column_type_impl (semantics::data_member& m) const { - string r (::context::column_type (m)); + string r (::context::column_type_impl (m)); if (m.count ("auto")) r += " AUTO_INCREMENT"; diff --git a/odb/mysql/context.hxx b/odb/mysql/context.hxx index 266d38f..40facae 100644 --- a/odb/mysql/context.hxx +++ b/odb/mysql/context.hxx @@ -86,6 +86,12 @@ namespace mysql bool grow (semantics::class_&); + // + // + public: + sql_type const& + db_type (semantics::data_member&); + private: typedef ::context base_context; @@ -98,10 +104,7 @@ namespace mysql public: virtual string - column_type (semantics::data_member&) const; - - sql_type const& - db_type (semantics::data_member&); + column_type_impl (semantics::data_member&) const; public: context (std::ostream&, semantics::unit&, options_type const&); diff --git a/odb/type-processor.cxx b/odb/type-processor.cxx new file mode 100644 index 0000000..c8e58a1 --- /dev/null +++ b/odb/type-processor.cxx @@ -0,0 +1,97 @@ +// file : odb/type-processor.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v3; see accompanying LICENSE file + +#include <odb/type-processor.hxx> + +namespace +{ + struct data_member: traversal::data_member, context + { + data_member (context& c) + : context (c) + { + } + + virtual void + traverse (type& m) + { + if (m.count ("transient")) + return; + + semantics::type& t (m.type ()); + + // Nothing to do if this is a composite value type. + // + if (comp_value (t)) + return; + + string const& type (column_type_impl (m)); + + if (!type.empty ()) + { + m.set ("column-type", type); + return; + } + + // See if this is a container type. + // + + // If it is none of the above then we have an error. + // + string const& fq_type (t.fq_name (m.belongs ().hint ())); + + cerr << m.file () << ":" << m.line () << ":" << m.column () << ":" + << " error: unable to map C++ type '" << fq_type << "' used in " + << "data member '" << m.name () << "' to a database type" << endl; + + cerr << m.file () << ":" << m.line () << ":" << m.column () << ":" + << " info: use '#pragma db type' to specify the database type" + << endl; + + throw generation_failed (); + } + }; + + struct class_: traversal::class_, context + { + class_ (context& c) + : context (c), member_ (c) + { + *this >> member_names_ >> member_; + } + + virtual void + traverse (type& c) + { + if (!(c.count ("object") || comp_value (c))) + return; + + names (c); + } + + private: + data_member member_; + traversal::names member_names_; + }; +} + +void +process_types (context& ctx) +{ + traversal::unit unit; + traversal::defines unit_defines; + traversal::namespace_ ns; + class_ c (ctx); + + unit >> unit_defines >> ns; + unit_defines >> c; + + traversal::defines ns_defines; + + ns >> ns_defines >> ns; + ns_defines >> c; + + unit.dispatch (ctx.unit); +} diff --git a/odb/type-processor.hxx b/odb/type-processor.hxx new file mode 100644 index 0000000..2cd8b3b --- /dev/null +++ b/odb/type-processor.hxx @@ -0,0 +1,16 @@ +// file : odb/type-processor.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v3; see accompanying LICENSE file + +#ifndef ODB_TYPE_PROCESSOR_HXX +#define ODB_TYPE_PROCESSOR_HXX + +#include <odb/context.hxx> + +// Issues diagnostics and throws generation_failed in case of an error. +// +void +process_types (context&); + +#endif // ODB_TYPE_PROCESSOR_HXX |