summaryrefslogtreecommitdiff
path: root/odb/relational/common.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational/common.cxx')
-rw-r--r--odb/relational/common.cxx178
1 files changed, 178 insertions, 0 deletions
diff --git a/odb/relational/common.cxx b/odb/relational/common.cxx
new file mode 100644
index 0000000..0bcc676
--- /dev/null
+++ b/odb/relational/common.cxx
@@ -0,0 +1,178 @@
+// file : odb/relational/common.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v3; see accompanying LICENSE file
+
+#include <string>
+#include <cstddef> // std::size_
+#include <cstdlib> // abort
+#include <sstream>
+#include <cxxabi.h> // abi::__cxa_demangle
+
+#include <odb/relational/common.hxx>
+
+using namespace std;
+
+namespace relational
+{
+ // query_columns
+ //
+
+ query_columns::
+ query_columns ()
+ : ptr_ (true), decl_ (true)
+ {
+ }
+
+ query_columns::
+ query_columns (semantics::class_& cl) //@@ context::object
+ : ptr_ (true), decl_ (false)
+ {
+ scope_ = "access::object_traits< " + cl.fq_name () + " >::query_type";
+ table_ = table_name (cl);
+ }
+
+ void query_columns::
+ composite (semantics::data_member& m, semantics::class_& c)
+ {
+ string name (public_name (m));
+
+ if (decl_)
+ {
+ os << "// " << name << endl
+ << "//" << endl
+ << "struct " << name
+ << "{";
+
+ object_columns_base::composite (m, c);
+
+ os << "};";
+ }
+ else
+ {
+ string old_scope (scope_);
+ scope_ += "::" + name;
+
+ object_columns_base::composite (m, c);
+
+ scope_ = old_scope;
+ }
+ }
+
+ bool query_columns::
+ column (semantics::data_member& m, string const& col_name, bool)
+ {
+ string name (public_name (m));
+
+ if (semantics::class_* c = object_pointer (m.type ()))
+ {
+ // We cannot just typedef the query_type from the referenced
+ // object for two reasons: (1) it may not be defined yet and
+ // (2) it will contain columns for its own pointers which
+ // won't work (for now we only support one level of indirection
+ // in queries). So we will have to duplicate the columns (sans
+ // the pointers).
+ //
+ if (ptr_)
+ {
+ ptr_ = false;
+
+ if (decl_)
+ {
+ os << "// " << name << endl
+ << "//" << endl
+ << "struct " << name
+ << "{";
+
+ traverse (*c);
+
+ os << "};";
+ }
+ else
+ {
+ string old_scope (scope_), old_table (table_);
+ scope_ += "::" + name;
+ table_ = table_name (*c);
+ traverse (*c);
+ table_ = old_table;
+ scope_ = old_scope;
+ }
+
+ ptr_ = true;
+ }
+ }
+ else
+ {
+ string im_type (image_type (m));
+ string db_type (database_type (m));
+
+ string type (
+ "mysql::value_traits< "
+ + m.type ().fq_name (m.belongs ().hint ()) + ", "
+ + im_type + ", "
+ + db_type
+ + " >::query_type");
+
+ if (decl_)
+ {
+ os << "// " << name << endl
+ << "//" << endl
+ << "static const mysql::query_column<" << endl
+ << " " << type << "," << endl
+ << " " << db_type << ">" << endl
+ << name << ";"
+ << endl;
+ }
+ else
+ {
+ string column ("\"`" + table_ + "`.`" + col_name + "`\"");
+
+ os << "const mysql::query_column<" << endl
+ << " " << type << "," << endl
+ << " " << db_type << ">" << endl
+ << scope_ << "::" << name << " (" << endl
+ << column << ");"
+ << endl;
+ }
+ }
+
+ return true;
+ }
+
+ //
+ // Dynamic traversal support.
+ //
+
+ struct demangled_name
+ {
+ demangled_name (): s (0), n (0) {}
+ ~demangled_name () {free (s);}
+ char* s;
+ size_t n;
+ };
+
+ static demangled_name name_;
+
+ database entry_base::
+ db (type_info const& ti)
+ {
+ char*& s (name_.s);
+
+ int r;
+ s = abi::__cxa_demangle (ti.name (), s, &name_.n, &r);
+
+ if (r != 0)
+ abort (); // We are in static initialization, so this is fatal.
+
+ //
+ //
+ string str (s + 12); // 12 for "relational::"
+ istringstream is (string (str, str.find (':')));
+
+ database d;
+ if (!is >> d)
+ abort ();
+
+ return d;
+ }
+}