summaryrefslogtreecommitdiff
path: root/odb
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-11-01 09:01:50 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-11-01 09:01:50 +0200
commit727a83dc82fa094aa91630d165d230a9a2dabe60 (patch)
treecf908eef97e4fd5518359bc90dc5839c829475ff /odb
parent56237544eeed76a55190b3fd7cc364d133d4513d (diff)
Factor assignment of database type to separate pass
Diffstat (limited to 'odb')
-rw-r--r--odb/context.cxx16
-rw-r--r--odb/context.hxx8
-rw-r--r--odb/generator.cxx30
-rw-r--r--odb/makefile1
-rw-r--r--odb/mysql/context.cxx4
-rw-r--r--odb/mysql/context.hxx11
-rw-r--r--odb/type-processor.cxx97
-rw-r--r--odb/type-processor.hxx16
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