summaryrefslogtreecommitdiff
path: root/odb/mysql
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-03-10 08:44:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-03-21 15:39:59 +0200
commit7ae497743c7b042904fe1f6b4153ab3f4763ff2b (patch)
tree08ba3f742f20d16d893856ccceb070094bd69225 /odb/mysql
parent2436f20262a41bd1cafa5107ab6d6799c03e0964 (diff)
Split MySQL code generator into common and db-specific parts
The common part (in relational/) still has some MySQL-specific parts. Also, add the notion of the current context which is used to avoid explicitly passing the context object to every generator's c-tor.
Diffstat (limited to 'odb/mysql')
-rw-r--r--odb/mysql/common.cxx566
-rw-r--r--odb/mysql/common.hxx270
-rw-r--r--odb/mysql/context.cxx637
-rw-r--r--odb/mysql/context.hxx127
-rw-r--r--odb/mysql/header.cxx1031
-rw-r--r--odb/mysql/header.hxx17
-rw-r--r--odb/mysql/inline.cxx129
-rw-r--r--odb/mysql/inline.hxx17
-rw-r--r--odb/mysql/schema.cxx11
-rw-r--r--odb/mysql/schema.hxx325
-rw-r--r--odb/mysql/source.cxx3266
-rw-r--r--odb/mysql/source.hxx17
-rw-r--r--odb/mysql/sql-schema.cxx98
-rw-r--r--odb/mysql/sql-schema.hxx17
14 files changed, 0 insertions, 6528 deletions
diff --git a/odb/mysql/common.cxx b/odb/mysql/common.cxx
deleted file mode 100644
index b771990..0000000
--- a/odb/mysql/common.cxx
+++ /dev/null
@@ -1,566 +0,0 @@
-// file : odb/mysql/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 <cassert>
-
-#include <odb/mysql/common.hxx>
-
-using namespace std;
-
-namespace mysql
-{
- //
- // member_base
- //
-
- void member_base::
- traverse (semantics::data_member& m)
- {
- if (m.count ("transient"))
- return;
-
- string var;
-
- if (!var_override_.empty ())
- var = var_override_;
- else
- {
- string const& name (m.name ());
- var = name + (name[name.size () - 1] == '_' ? "" : "_");
- }
-
- semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
-
- if (comp_value (t))
- {
- member_info mi (m, t, var, fq_type_override_);
- if (pre (mi))
- {
- traverse_composite (mi);
- post (mi);
- }
- }
- else if (container (t))
- {
- member_info mi (m, t, var, fq_type_override_);
- if (pre (mi))
- {
- traverse_container (mi);
- post (mi);
- }
- }
- else
- {
- sql_type const& st (db_type (m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (t))
- {
- member_info mi (m, id_member (*c).type (), var, fq_type_override_);
- mi.st = &st;
- if (pre (mi))
- {
- traverse_object_pointer (mi);
- post (mi);
- }
- }
- else
- {
- member_info mi (m, t, var, fq_type_override_);
- mi.st = &st;
- if (pre (mi))
- {
- traverse_simple (mi);
- post (mi);
- }
- }
- }
- }
-
- void member_base::
- traverse_simple (member_info& mi)
- {
- switch (mi.st->type)
- {
- // Integral types.
- //
- case sql_type::TINYINT:
- case sql_type::SMALLINT:
- case sql_type::MEDIUMINT:
- case sql_type::INT:
- case sql_type::BIGINT:
- {
- traverse_integer (mi);
- break;
- }
-
- // Float types.
- //
- case sql_type::FLOAT:
- case sql_type::DOUBLE:
- {
- traverse_float (mi);
- break;
- }
- case sql_type::DECIMAL:
- {
- traverse_decimal (mi);
- break;
- }
-
- // Data-time types.
- //
- case sql_type::DATE:
- case sql_type::TIME:
- case sql_type::DATETIME:
- case sql_type::TIMESTAMP:
- case sql_type::YEAR:
- {
- traverse_date_time (mi);
- break;
- }
-
- // String and binary types.
- //
- case sql_type::CHAR:
- case sql_type::VARCHAR:
- case sql_type::TINYTEXT:
- case sql_type::TEXT:
- case sql_type::MEDIUMTEXT:
- case sql_type::LONGTEXT:
- {
- // For string types the limit is in characters rather
- // than in bytes. The fixed-length pre-allocated buffer
- // optimization can only be used for 1-byte encodings.
- // To support this we will need the character encoding
- // in sql_type.
- //
- traverse_long_string (mi);
- break;
- }
- case sql_type::BINARY:
- case sql_type::TINYBLOB:
- {
- // BINARY's range is always 255 or less from MySQL 5.0.3.
- // TINYBLOB can only store up to 255 bytes.
- //
- traverse_short_string (mi);
- break;
- }
- case sql_type::VARBINARY:
- case sql_type::BLOB:
- case sql_type::MEDIUMBLOB:
- case sql_type::LONGBLOB:
- {
- if (mi.st->range && mi.st->range_value <= 255)
- traverse_short_string (mi);
- else
- traverse_long_string (mi);
-
- break;
- }
-
- // Other types.
- //
- case sql_type::BIT:
- {
- traverse_bit (mi);
- break;
- }
- case sql_type::ENUM:
- {
- traverse_enum (mi);
- break;
- }
- case sql_type::SET:
- {
- traverse_set (mi);
- break;
- }
- case sql_type::invalid:
- {
- assert (false);
- break;
- }
- }
- }
-
- //
- // member_image_type
- //
-
- namespace
- {
- const char* integer_types[] =
- {
- "char",
- "short",
- "int",
- "int",
- "long long"
- };
-
- const char* float_types[] =
- {
- "float",
- "double"
- };
- }
-
- member_image_type::
- member_image_type (context& c)
- : member_base (c)
- {
- }
-
- member_image_type::
- member_image_type (context& c,
- semantics::type& type,
- string const& fq_type,
- string const& key_prefix)
- : member_base (c, "", type, fq_type, key_prefix)
- {
- }
-
- string member_image_type::
- image_type (semantics::data_member& m)
- {
- type_.clear ();
- member_base::traverse (m);
- return type_;
- }
-
- void member_image_type::
- traverse_composite (member_info& mi)
- {
- type_ = "composite_value_traits< " + mi.fq_type () + " >::image_type";
- }
-
- void member_image_type::
- traverse_integer (member_info& mi)
- {
- if (mi.st->unsign)
- type_ = "unsigned ";
- else if (mi.st->type == sql_type::TINYINT)
- type_ = "signed ";
-
- type_ += integer_types[mi.st->type - sql_type::TINYINT];
- }
-
- void member_image_type::
- traverse_float (member_info& mi)
- {
- type_ = float_types[mi.st->type - sql_type::FLOAT];
- }
-
- void member_image_type::
- traverse_decimal (member_info&)
- {
- type_ = "details::buffer";
- }
-
- void member_image_type::
- traverse_date_time (member_info& mi)
- {
- if (mi.st->type == sql_type::YEAR)
- type_ = "short";
- else
- type_ = "MYSQL_TIME";
- }
-
- void member_image_type::
- traverse_string (member_info&)
- {
- type_ = "details::buffer";
- }
-
- void member_image_type::
- traverse_bit (member_info&)
- {
- type_ = "unsigned char*";
- }
-
- void member_image_type::
- traverse_enum (member_info&)
- {
- // Represented as string.
- //
- type_ = "details::buffer";
- }
-
- void member_image_type::
- traverse_set (member_info&)
- {
- // Represented as string.
- //
- type_ = "details::buffer";
- }
-
- //
- // member_database_type
- //
-
- namespace
- {
- const char* integer_database_id[] =
- {
- "id_tiny",
- "id_utiny",
- "id_short",
- "id_ushort",
- "id_long", // INT24
- "id_ulong", // INT24 UNSIGNED
- "id_long",
- "id_ulong",
- "id_longlong",
- "id_ulonglong"
- };
-
- const char* float_database_id[] =
- {
- "id_float",
- "id_double"
- };
-
- const char* date_time_database_id[] =
- {
- "id_date",
- "id_time",
- "id_datetime",
- "id_timestamp",
- "id_year"
- };
-
- const char* char_bin_database_id[] =
- {
- "id_string", // CHAR
- "id_blob", // BINARY,
- "id_string", // VARCHAR
- "id_blob", // VARBINARY
- "id_string", // TINYTEXT
- "id_blob", // TINYBLOB
- "id_string", // TEXT
- "id_blob", // BLOB
- "id_string", // MEDIUMTEXT
- "id_blob", // MEDIUMBLOB
- "id_string", // LONGTEXT
- "id_blob" // LONGBLOB
- };
- }
-
- member_database_type::
- member_database_type (context& c)
- : member_base (c)
- {
- }
-
- member_database_type::
- member_database_type (context& c,
- semantics::type& type,
- string const& fq_type,
- string const& key_prefix)
- : member_base (c, "", type, fq_type, key_prefix)
- {
- }
-
- string member_database_type::
- database_type (type& m)
- {
- type_.clear ();
- member_base::traverse (m);
- return type_;
- }
-
- void member_database_type::
- traverse_composite (member_info&)
- {
- assert (false);
- }
-
- void member_database_type::
- traverse_integer (member_info& mi)
- {
- size_t i ((mi.st->type - sql_type::TINYINT) * 2 + (mi.st->unsign ? 1 : 0));
- type_ = string ("mysql::") + integer_database_id[i];
- }
-
- void member_database_type::
- traverse_float (member_info& mi)
- {
- type_ = string ("mysql::") +
- float_database_id[mi.st->type - sql_type::FLOAT];
- }
-
- void member_database_type::
- traverse_decimal (member_info&)
- {
- type_ = "mysql::id_decimal";
- }
-
- void member_database_type::
- traverse_date_time (member_info& mi)
- {
- type_ = string ("mysql::") +
- date_time_database_id[mi.st->type - sql_type::DATE];
- }
-
- void member_database_type::
- traverse_string (member_info& mi)
- {
- type_ = string ("mysql::") +
- char_bin_database_id[mi.st->type - sql_type::CHAR];
- }
-
- void member_database_type::
- traverse_bit (member_info&)
- {
- type_ = "mysql::id_bit";
- }
-
- void member_database_type::
- traverse_enum (member_info&)
- {
- type_ = "mysql::id_enum";
- }
-
- void member_database_type::
- traverse_set (member_info&)
- {
- type_ = "mysql::id_set";
- }
-
- //
- // query_columns
- //
-
- query_columns::
- query_columns (context& c)
- : object_columns_base (c),
- context (c),
- ptr_ (true),
- decl_ (true),
- member_image_type_ (c),
- member_database_type_ (c)
- {
- }
-
- query_columns::
- query_columns (context& c, semantics::class_& cl)
- : object_columns_base (c),
- context (c),
- ptr_ (true),
- decl_ (false),
- member_image_type_ (c),
- member_database_type_ (c)
- {
- 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 db_type (member_database_type_.database_type (m));
-
- string type (
- "mysql::value_traits< "
- + m.type ().fq_name (m.belongs ().hint ()) + ", "
- + member_image_type_.image_type (m) + ", "
- + 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;
- }
-}
diff --git a/odb/mysql/common.hxx b/odb/mysql/common.hxx
deleted file mode 100644
index df01e5f..0000000
--- a/odb/mysql/common.hxx
+++ /dev/null
@@ -1,270 +0,0 @@
-// file : odb/mysql/common.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_MYSQL_COMMON_HXX
-#define ODB_MYSQL_COMMON_HXX
-
-#include <odb/common.hxx>
-#include <odb/mysql/context.hxx>
-
-namespace mysql
-{
- struct member_base: traversal::data_member, context
- {
- member_base (context& c, string const& var = string ())
- : context (c), var_override_ (var), type_override_ (0)
- {
- }
-
- member_base (context& c,
- string const& var,
- semantics::type& type,
- string const& fq_type,
- string const& key_prefix)
- : context (c),
- var_override_ (var),
- type_override_ (&type),
- fq_type_override_ (fq_type),
- key_prefix_ (key_prefix)
- {
- }
-
- virtual void
- traverse (semantics::data_member& m);
-
- struct member_info
- {
- semantics::data_member& m; // Member.
- semantics::type& t; // Member C++ type (m.type () may != t).
- sql_type const* st; // Member SQL type (only simple value types).
- string& var; // Member variable name with trailing '_'.
-
- // C++ type fq-name.
- //
- string
- fq_type () const
- {
- // Use the original type from 'm' instead of 't' since the hint
- // may be invalid for a different type. Plus, if a type is
- // overriden, then the fq_type must be as well.
- //
- return fq_type_.empty ()
- ? m.type ().fq_name (m.belongs ().hint ())
- : fq_type_;
- }
-
- string const& fq_type_;
-
- member_info (semantics::data_member& m_,
- semantics::type& t_,
- string& var_,
- string const& fq_type)
- : m (m_), t (t_), st (0), var (var_), fq_type_ (fq_type)
- {
- }
- };
-
- // The false return value indicates that no further callbacks
- // should be called for this member.
- //
- virtual bool
- pre (member_info&)
- {
- return true;
- }
-
- virtual void
- post (member_info&)
- {
- }
-
- virtual void
- traverse_composite (member_info&)
- {
- }
-
- virtual void
- traverse_container (member_info&)
- {
- }
-
- virtual void
- traverse_object_pointer (member_info& mi)
- {
- traverse_simple (mi);
- }
-
- virtual void
- traverse_simple (member_info&);
-
- virtual void
- traverse_integer (member_info&)
- {
- }
-
- virtual void
- traverse_float (member_info&)
- {
- }
-
- virtual void
- traverse_decimal (member_info&)
- {
- }
-
- virtual void
- traverse_date_time (member_info&)
- {
- }
-
- virtual void
- traverse_string (member_info&)
- {
- }
-
- virtual void
- traverse_short_string (member_info& mi)
- {
- traverse_string (mi);
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- traverse_string (mi);
- }
-
- virtual void
- traverse_bit (member_info&)
- {
- }
-
- virtual void
- traverse_enum (member_info&)
- {
- }
-
- virtual void
- traverse_set (member_info&)
- {
- }
-
- protected:
- string var_override_;
- semantics::type* type_override_;
- string fq_type_override_;
- string key_prefix_;
- };
-
- struct member_image_type: member_base
- {
- member_image_type (context&);
-
- member_image_type (context& c,
- semantics::type& type,
- string const& fq_type,
- string const& key_prefix);
-
- string
- image_type (semantics::data_member&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_integer (member_info&);
-
- virtual void
- traverse_float (member_info&);
-
- virtual void
- traverse_decimal (member_info&);
-
- virtual void
- traverse_date_time (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_bit (member_info&);
-
- virtual void
- traverse_enum (member_info&);
-
- virtual void
- traverse_set (member_info&);
-
- private:
- string type_;
- };
-
- struct member_database_type: member_base
- {
- member_database_type (context&);
-
- member_database_type (context& c,
- semantics::type& type,
- string const& fq_type,
- string const& key_prefix);
-
- string
- database_type (type&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_integer (member_info&);
-
- virtual void
- traverse_float (member_info&);
-
- virtual void
- traverse_decimal (member_info&);
-
- virtual void
- traverse_date_time (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_bit (member_info&);
-
- virtual void
- traverse_enum (member_info&);
-
- virtual void
- traverse_set (member_info&);
-
- private:
- string type_;
- };
-
- struct query_columns: object_columns_base, context
- {
- query_columns (context&);
- query_columns (context&, semantics::class_&);
-
- virtual void
- composite (semantics::data_member&, semantics::class_&);
-
- virtual bool
- column (semantics::data_member&, string const&, bool);
-
- private:
- bool ptr_;
- bool decl_;
-
- string scope_;
- string table_;
-
- member_image_type member_image_type_;
- member_database_type member_database_type_;
- };
-}
-
-#endif // ODB_MYSQL_COMMON_HXX
diff --git a/odb/mysql/context.cxx b/odb/mysql/context.cxx
deleted file mode 100644
index b7d6540..0000000
--- a/odb/mysql/context.cxx
+++ /dev/null
@@ -1,637 +0,0 @@
-// file : odb/mysql/context.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 <sstream>
-
-#include <odb/sql-token.hxx>
-#include <odb/sql-lexer.hxx>
-
-#include <odb/mysql/context.hxx>
-#include <odb/mysql/common.hxx>
-
-using namespace std;
-
-namespace mysql
-{
- namespace
- {
- struct type_map_entry
- {
- const char* const cxx_type;
- const char* const db_type;
- const char* const db_id_type;
- };
-
- type_map_entry type_map[] =
- {
- {"bool", "TINYINT(1)", 0},
-
- {"char", "TINYINT", 0},
- {"signed char", "TINYINT", 0},
- {"unsigned char", "TINYINT UNSIGNED", 0},
-
- {"short int", "SMALLINT", 0},
- {"short unsigned int", "SMALLINT UNSIGNED", 0},
-
- {"int", "INT", 0},
- {"unsigned int", "INT UNSIGNED", 0},
-
- {"long int", "BIGINT", 0},
- {"long unsigned int", "BIGINT UNSIGNED", 0},
-
- {"long long int", "BIGINT", 0},
- {"long long unsigned int", "BIGINT UNSIGNED", 0},
-
- {"float", "FLOAT", 0},
- {"double", "DOUBLE", 0},
-
- {"::std::string", "TEXT", "VARCHAR (255)"}
- };
- }
-
- context::
- context (ostream& os, semantics::unit& u, options_type const& ops)
- : base_context (os, u, ops, data_ptr (new (shared) data)),
- data_ (static_cast<data*> (base_context::data_.get ()))
- {
- // Populate the C++ type to DB type map.
- //
- for (size_t i (0); i < sizeof (type_map) / sizeof (type_map_entry); ++i)
- {
- type_map_entry const& e (type_map[i]);
-
- type_map_type::value_type v (
- e.cxx_type,
- db_type_type (e.db_type, e.db_id_type ? e.db_id_type : e.db_type));
-
- data_->type_map_.insert (v);
- }
- }
-
- context::
- context (context& c)
- : base_context (c),
- data_ (c.data_)
- {
- }
-
- context::
- context (context& c, ostream& os)
- : base_context (c, os),
- data_ (c.data_)
- {
- }
-
- namespace
- {
- struct has_grow: traversal::class_
- {
- has_grow (bool& r)
- : r_ (r)
- {
- *this >> inherits_ >> *this;
- }
-
- virtual void
- traverse (type& c)
- {
- // Ignore transient bases.
- //
- if (!(c.count ("object") || context::comp_value (c)))
- return;
-
- if (c.count ("mysql::grow"))
- r_ = c.get<bool> ("mysql::grow");
- else
- {
- // r_ should be false.
- //
- inherits (c);
-
- if (!r_)
- names (c);
-
- c.set ("mysql::grow", r_);
- }
- }
-
- private:
- bool& r_;
- traversal::inherits inherits_;
- };
-
- struct has_grow_member: member_base
- {
- has_grow_member (context& c, bool& r)
- : member_base (c), r_ (r)
- {
- }
-
- has_grow_member (context& c,
- bool& r,
- semantics::type& type,
- string const& key_prefix)
- : member_base (c, "", type, "", key_prefix), r_ (r)
- {
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- // By calling grow() instead of recursing, we reset any overrides.
- //
- r_ = r_ || context::grow (dynamic_cast<semantics::class_&> (mi.t));
- }
-
- virtual void
- traverse_decimal (member_info&)
- {
- r_ = true;
- }
-
- virtual void
- traverse_long_string (member_info&)
- {
- r_ = true;
- }
-
- virtual void
- traverse_short_string (member_info&)
- {
- r_ = true; // @@ Short string optimization disabled.
- }
-
- virtual void
- traverse_enum (member_info&)
- {
- r_ = true;
- }
-
- virtual void
- traverse_set (member_info&)
- {
- r_ = true;
- }
-
- private:
- bool& r_;
- };
- }
-
- bool context::
- grow (semantics::class_& c)
- {
- if (c.count ("mysql::grow"))
- return c.get<bool> ("mysql::grow");
-
- bool r (false);
- has_grow ct (r);
- has_grow_member mt (*this, r);
- traversal::names names;
- ct >> names >> mt;
- ct.traverse (c);
- return r;
- }
-
- bool context::
- grow (semantics::data_member& m)
- {
- bool r (false);
- has_grow_member mt (*this, r);
- mt.traverse (m);
- return r;
- }
-
- bool context::
- grow (semantics::data_member& m, semantics::type& t, string const& kp)
- {
- bool r (false);
- has_grow_member mt (*this, r, t, kp);
- mt.traverse (m);
- return r;
- }
-
- //
- // SQL type parsing.
- //
-
- string context::data::
- column_type_impl (semantics::type& t,
- string const& type,
- semantics::context& ctx,
- column_type_flags f) const
- {
- string r (::context::data::column_type_impl (t, type, ctx, f));
-
- if (!r.empty () && ctx.count ("auto") && (f & ctf_object_id_ref) == 0)
- r += " AUTO_INCREMENT";
-
- return r;
- }
-
- static sql_type
- parse_sql_type (semantics::data_member& m, std::string const& sql);
-
- sql_type const& context::
- db_type (semantics::data_member& m, string const& kp)
- {
- string key (kp.empty () ? string ("db-type") : kp + "-db-type");
-
- if (!m.count (key))
- m.set (key, parse_sql_type (m, column_type (m, kp)));
-
- return m.get<sql_type> (key);
- }
-
- static sql_type
- parse_sql_type (semantics::data_member& m, string const& sql)
- {
- try
- {
- sql_type r;
- sql_lexer l (sql);
-
- // While most type names use single identifier, there are
- // a couple of exceptions to this rule:
- //
- // NATIONAL CHAR|VARCHAR
- // CHAR BYTE (BINARY)
- // CHARACTER VARYING (VARCHAR)
- // LONG VARBINARY (MEDIUMBLOB)
- // LONG VARCHAR (MEDIUMTEXT)
- //
- //
- enum state
- {
- parse_prefix,
- parse_name,
- parse_range,
- parse_sign,
- parse_done
- };
-
- state s (parse_prefix);
- string prefix;
-
- for (sql_token t (l.next ());
- s != parse_done && t.type () != sql_token::t_eos;
- t = l.next ())
- {
- sql_token::token_type tt (t.type ());
-
- switch (s)
- {
- case parse_prefix:
- {
- if (tt == sql_token::t_identifier)
- {
- string const& id (context::upcase (t.identifier ()));
-
- if (id == "NATIONAL" ||
- id == "CHAR" ||
- id == "CHARACTER" ||
- id == "LONG")
- {
- prefix = id;
- s = parse_name;
- continue;
- }
- }
-
- // Fall through.
- //
- s = parse_name;
- }
- case parse_name:
- {
- if (tt == sql_token::t_identifier)
- {
- bool match (true);
- string const& id (context::upcase (t.identifier ()));
-
- // Numeric types.
- //
- if (id == "BIT")
- {
- r.type = sql_type::BIT;
- }
- else if (id == "TINYINT" || id == "INT1")
- {
- r.type = sql_type::TINYINT;
- }
- else if (id == "BOOL" || id == "BOOLEAN")
- {
- r.type = sql_type::TINYINT;
- r.range = true;
- r.range_value = 1;
- }
- else if (id == "SMALLINT" || id == "INT2")
- {
- r.type = sql_type::SMALLINT;
- }
- else if (id == "MEDIUMINT" || id == "INT3" || id == "MIDDLEINT")
- {
- r.type = sql_type::MEDIUMINT;
- }
- else if (id == "INT" || id == "INTEGER" || id == "INT4")
- {
- r.type = sql_type::INT;
- }
- else if (id == "BIGINT" || id == "INT8")
- {
- r.type = sql_type::BIGINT;
- }
- else if (id == "SERIAL")
- {
- r.type = sql_type::BIGINT;
- r.unsign = true;
- }
- else if (id == "FLOAT" || id == "FLOAT4")
- {
- r.type = sql_type::FLOAT;
- }
- else if (id == "DOUBLE" || id == "FLOAT8")
- {
- r.type = sql_type::DOUBLE;
- }
- else if (id == "DECIMAL" ||
- id == "DEC" ||
- id == "NUMERIC" ||
- id == "FIXED")
- {
- r.type = sql_type::DECIMAL;
- }
- //
- // Date-time types.
- //
- else if (id == "DATE")
- {
- r.type = sql_type::DATE;
- }
- else if (id == "TIME")
- {
- r.type = sql_type::TIME;
- }
- else if (id == "DATETIME")
- {
- r.type = sql_type::DATETIME;
- }
- else if (id == "TIMESTAMP")
- {
- r.type = sql_type::TIMESTAMP;
- }
- else if (id == "YEAR")
- {
- r.type = sql_type::YEAR;
- }
- //
- // String and binary types.
- //
- else if (id == "NCHAR")
- {
- r.type = sql_type::CHAR;
- }
- else if (id == "VARCHAR")
- {
- r.type = prefix == "LONG"
- ? sql_type::MEDIUMTEXT
- : sql_type::VARCHAR;
- }
- else if (id == "NVARCHAR")
- {
- r.type = sql_type::VARCHAR;
- }
- else if (id == "VARYING" && prefix == "CHARACTER")
- {
- r.type = sql_type::VARCHAR;
- }
- else if (id == "BINARY")
- {
- r.type = sql_type::BINARY;
- }
- else if (id == "BYTE" && prefix == "CHAR")
- {
- r.type = sql_type::BINARY;
- }
- else if (id == "VARBINARY")
- {
- r.type = prefix == "LONG"
- ? sql_type::MEDIUMBLOB
- : sql_type::VARBINARY;
- }
- else if (id == "TINYBLOB")
- {
- r.type = sql_type::TINYBLOB;
- }
- else if (id == "TINYTEXT")
- {
- r.type = sql_type::TINYTEXT;
- }
- else if (id == "BLOB")
- {
- r.type = sql_type::BLOB;
- }
- else if (id == "TEXT")
- {
- r.type = sql_type::TEXT;
- }
- else if (id == "MEDIUMBLOB")
- {
- r.type = sql_type::MEDIUMBLOB;
- }
- else if (id == "MEDIUMTEXT")
- {
- r.type = sql_type::MEDIUMTEXT;
- }
- else if (id == "LONGBLOB")
- {
- r.type = sql_type::LONGBLOB;
- }
- else if (id == "LONGTEXT")
- {
- r.type = sql_type::LONGTEXT;
- }
- else if (id == "ENUM")
- {
- r.type = sql_type::ENUM;
- }
- else if (id == "SET")
- {
- r.type = sql_type::SET;
- }
- else
- match = false;
-
- if (match)
- {
- s = parse_range;
- continue;
- }
- }
-
- // Some prefixes can also be type names if not followed
- // by the actual type name.
- //
- if (!prefix.empty ())
- {
- if (prefix == "CHAR" || prefix == "CHARACTER")
- {
- r.type = sql_type::CHAR;
- }
- else if (prefix == "LONG")
- {
- r.type = sql_type::MEDIUMTEXT;
- }
- }
-
- if (r.type == sql_type::invalid)
- {
- cerr << m.file () << ":" << m.line () << ":" <<
- m.column () << ":";
-
- if (tt == sql_token::t_identifier)
- cerr << " error: unknown MySQL type '" <<
- t.identifier () << "'" << endl;
- else
- cerr << " error: expected MySQL type name" << endl;
-
- throw generation_failed ();
- }
-
- // Fall through.
- //
- s = parse_range;
- }
- case parse_range:
- {
- if (t.punctuation () == sql_token::p_lparen)
- {
- t = l.next ();
-
- // ENUM and SET have a list of members instead of the range.
- //
- if (r.type == sql_type::ENUM || r.type == sql_type::SET)
- {
- // Skip tokens until we get the closing paren.
- //
- while (t.type () != sql_token::t_eos &&
- t.punctuation () != sql_token::p_rparen)
- t = l.next ();
- }
- else
- {
- if (t.type () != sql_token::t_int_lit)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: integer range expected in MySQL type "
- << "declaration" << endl;
-
- throw generation_failed ();
- }
-
- unsigned int v;
- istringstream is (t.literal ());
-
- if (!(is >> v && is.eof ()))
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: invalid range value '" << t.literal ()
- << "'in MySQL type declaration" << endl;
-
- throw generation_failed ();
- }
-
- r.range = true;
- r.range_value = v;
-
- t = l.next ();
-
- if (t.punctuation () == sql_token::p_comma)
- {
- // We have the second range value. Skip it.
- //
- l.next ();
- t = l.next ();
- }
- }
-
- if (t.punctuation () != sql_token::p_rparen)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: expected ')' in MySQL type declaration"
- << endl;
-
- throw generation_failed ();
- }
-
- s = parse_sign;
- continue;
- }
-
- // Fall through.
- //
- s = parse_sign;
- }
- case parse_sign:
- {
- if (tt == sql_token::t_identifier &&
- context::upcase (t.identifier ()) == "UNSIGNED")
- {
- r.unsign = true;
- }
-
- s = parse_done;
- break;
- }
- case parse_done:
- {
- assert (false);
- break;
- }
- }
- }
-
- if (s == parse_name && !prefix.empty ())
- {
- // Some prefixes can also be type names if not followed
- // by the actual type name.
- //
- if (prefix == "CHAR" || prefix == "CHARACTER")
- {
- r.type = sql_type::CHAR;
- }
- else if (prefix == "LONG")
- {
- r.type = sql_type::MEDIUMTEXT;
- }
- }
-
- if (r.type == sql_type::invalid)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: incomplete MySQL type declaration" << endl;
-
- throw generation_failed ();
- }
-
- // If range is omitted for CHAR or BIT types, it defaults to 1.
- //
- if ((r.type == sql_type::CHAR || r.type == sql_type::BIT) && !r.range)
- {
- r.range = true;
- r.range_value = 1;
- }
-
- return r;
- }
- catch (sql_lexer::invalid_input const& e)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: invalid MySQL type declaration: " << e.message << endl;
-
- throw generation_failed ();
- }
- }
-}
diff --git a/odb/mysql/context.hxx b/odb/mysql/context.hxx
deleted file mode 100644
index 05b6639..0000000
--- a/odb/mysql/context.hxx
+++ /dev/null
@@ -1,127 +0,0 @@
-// file : odb/mysql/context.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_MYSQL_CONTEXT_HXX
-#define ODB_MYSQL_CONTEXT_HXX
-
-#include <string>
-
-#include <odb/context.hxx>
-
-namespace mysql
-{
- struct sql_type
- {
- // Keep the order in each block of types.
- //
- enum core_type
- {
- // Integral types.
- //
- TINYINT,
- SMALLINT,
- MEDIUMINT,
- INT,
- BIGINT,
-
- // Float types.
- //
- FLOAT,
- DOUBLE,
- DECIMAL,
-
- // Data-time types.
- //
- DATE,
- TIME,
- DATETIME,
- TIMESTAMP,
- YEAR,
-
- // String and binary types.
- //
- CHAR,
- BINARY,
- VARCHAR,
- VARBINARY,
- TINYTEXT,
- TINYBLOB,
- TEXT,
- BLOB,
- MEDIUMTEXT,
- MEDIUMBLOB,
- LONGTEXT,
- LONGBLOB,
-
- // Other types.
- //
- BIT,
- ENUM,
- SET,
-
- // Invalid type.
- //
- invalid
- };
-
- sql_type () : type (invalid), unsign (false), range (false) {}
-
- core_type type;
- bool unsign;
- bool range;
- unsigned int range_value; // MySQL max value is 2^32 - 1 (LONGBLOG/TEXT).
- };
-
- class context: public ::context
- {
- // Predicates.
- //
- public:
-
- // Return true if an object or value type has members for which
- // the image can grow.
- //
- bool
- grow (semantics::class_&);
-
- // The same for a member's value type.
- //
- bool
- grow (semantics::data_member&);
-
- bool
- grow (semantics::data_member&, semantics::type&, string const& key_prefix);
-
- //
- //
- public:
- sql_type const&
- db_type (semantics::data_member&, string const& key_prefix = string ());
-
- private:
- typedef ::context base_context;
-
- struct data: base_context::data
- {
- virtual string
- column_type_impl (semantics::type&,
- string const& type,
- semantics::context&,
- column_type_flags) const;
- };
-
- private:
- data* data_;
-
- public:
-
- public:
- context (std::ostream&, semantics::unit&, options_type const&);
- context (context&);
- context (context&, std::ostream&);
- };
-}
-
-#endif // ODB_MYSQL_CONTEXT_HXX
diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx
deleted file mode 100644
index 59793b0..0000000
--- a/odb/mysql/header.cxx
+++ /dev/null
@@ -1,1031 +0,0 @@
-// file : odb/mysql/header.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 <odb/gcc.hxx>
-
-#include <odb/mysql/common.hxx>
-#include <odb/mysql/header.hxx>
-
-namespace mysql
-{
- namespace
- {
- struct image_member: member_base
- {
- image_member (context& c, string const& var = string ())
- : member_base (c, var), member_image_type_ (c)
- {
- }
-
- image_member (context& c,
- string const& var,
- semantics::type& t,
- string const& fq_type,
- string const& key_prefix)
- : member_base (c, var, t, fq_type, key_prefix),
- member_image_type_ (c, t, fq_type, key_prefix)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- if (container (mi.t))
- return false;
-
- image_type = member_image_type_.image_type (mi.m);
-
- if (var_override_.empty ())
- os << "// " << mi.m.name () << endl
- << "//" << endl;
-
- return true;
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << endl;
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- // Exchanged as strings. Can have up to 65 digits not counting
- // '-' and '.'. If range is not specified, the default is 10.
- //
-
- /*
- @@ Disabled.
- os << "char " << mi.var << "value[" <<
- (t.range ? t.range_value : 10) + 3 << "];"
- */
-
- os << image_type << " " << mi.var << "value;"
- << "unsigned long " << mi.var << "size;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "my_bool " << mi.var << "null;"
- << endl;
-
- }
-
- virtual void
- traverse_short_string (member_info& mi)
- {
- // If range is not specified, the default buffer size is 255.
- //
- /*
- @@ Disabled.
- os << "char " << mi.var << "value[" <<
- (t.range ? t.range_value : 255) + 1 << "];"
- */
-
- os << image_type << " " << mi.var << "value;"
- << "unsigned long " << mi.var << "size;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "unsigned long " << mi.var << "size;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- // Valid range is 1 to 64.
- //
- unsigned int n (mi.st->range / 8 + (mi.st->range % 8 ? 1 : 0));
-
- os << "unsigned char " << mi.var << "value[" << n << "];"
- << "unsigned long " << mi.var << "size;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_enum (member_info& mi)
- {
- // Represented as string.
- //
- os << image_type << " " << mi.var << "value;"
- << "unsigned long " << mi.var << "size;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- virtual void
- traverse_set (member_info& mi)
- {
- // Represented as string.
- //
- os << image_type << " " << mi.var << "value;"
- << "unsigned long " << mi.var << "size;"
- << "my_bool " << mi.var << "null;"
- << endl;
- }
-
- private:
- string image_type;
-
- member_image_type member_image_type_;
- };
-
- struct image_base: traversal::class_, context
- {
- image_base (context& c): context (c), first_ (true) {}
-
- virtual void
- traverse (type& c)
- {
- // Ignore transient bases.
- //
- if (!(c.count ("object") || comp_value (c)))
- return;
-
- if (first_)
- {
- os << ": ";
- first_ = false;
- }
- else
- {
- os << "," << endl
- << " ";
- }
-
- os << "composite_value_traits< " << c.fq_name () << " >::image_type";
- }
-
- private:
- bool first_;
- };
-
- struct image_type: traversal::class_, context
- {
- image_type (context& c)
- : context (c), member_ (c)
- {
- *this >> names_member_ >> member_;
- }
-
- virtual void
- traverse (type& c)
- {
- os << "struct image_type";
-
- {
- image_base b (*this);
- traversal::inherits i (b);
- inherits (c, i);
- }
-
- os << "{";
-
- names (c);
-
- if (!comp_value (c))
- os << "std::size_t version;";
-
- os << "};";
- }
-
- private:
- image_member member_;
- traversal::names names_member_;
- };
-
- // Member-specific traits types for container members.
- //
- struct container_traits: object_members_base, context
- {
- container_traits (context& c, semantics::class_& obj)
- : object_members_base (c, true, false), context (c)
- {
- scope_ = "object_traits< " + obj.fq_name () + " >";
- }
-
- virtual void
- container (semantics::data_member& m)
- {
- using semantics::type;
- using semantics::class_;
-
- type& t (m.type ());
- container_kind_type ck (container_kind (t));
-
- type& vt (container_vt (t));
- type* it (0);
- type* kt (0);
-
- bool ordered (false);
- bool inverse (context::inverse (m, "value"));
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (!unordered (m))
- {
- it = &container_it (t);
- ordered = true;
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- kt = &container_kt (t);
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- string name (prefix_ + public_name (m) + "_traits");
-
- // Figure out column counts.
- //
- size_t data_columns (1), cond_columns (1); // One for object id.
-
- switch (ck)
- {
- case ck_ordered:
- {
- // Add one for the index.
- //
- if (ordered)
- {
- data_columns++;
- cond_columns++;
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- // Add some for the key.
- //
- size_t n;
-
- if (class_* kc = comp_value (*kt))
- n = in_column_count (*kc);
- else
- n = 1;
-
- data_columns += n;
- cond_columns += n;
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- // Value is also a key.
- //
- if (class_* vc = comp_value (vt))
- cond_columns += in_column_count (*vc);
- else
- cond_columns++;
-
- break;
- }
- }
-
- if (class_* vc = comp_value (vt))
- data_columns += in_column_count (*vc);
- else
- data_columns++;
-
- // Store column counts for the source generator.
- //
- m.set ("cond-column-count", cond_columns);
- m.set ("data-column-count", data_columns);
-
- os << "// " << m.name () << endl
- << "//" << endl
- << "struct " << name
- << "{";
-
- // container_type
- // container_traits
- // index_type
- // key_type
- // value_type
- //
-
- os << "typedef " << t.fq_name (m.belongs ().hint ()) <<
- " container_type;";
- os << "typedef odb::access::container_traits< container_type > " <<
- "container_traits;";
-
- switch (ck)
- {
- case ck_ordered:
- {
- os << "typedef container_traits::index_type index_type;";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "typedef container_traits::key_type key_type;";
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- os << "typedef container_traits::value_type value_type;"
- << endl;
-
- // functions_type
- //
- switch (ck)
- {
- case ck_ordered:
- {
- os << "typedef ordered_functions<index_type, value_type> " <<
- "functions_type;";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "typedef map_functions<key_type, value_type> " <<
- "functions_type;";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "typedef set_functions<value_type> functions_type;";
- break;
- }
- }
-
- os << "typedef mysql::container_statements< " << name <<
- " > statements_type;"
- << endl;
-
- // column_count
- //
- os << "static const std::size_t cond_column_count = " <<
- cond_columns << "UL;"
- << "static const std::size_t data_column_count = " <<
- data_columns << "UL;"
- << endl;
-
- // id_image_type
- //
- os << "typedef " << scope_ << "::id_image_type id_image_type;"
- << endl;
-
- // cond_image_type (object id is taken from the object image)
- //
- os << "struct cond_image_type"
- << "{";
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- {
- os << "// index" << endl
- << "//" << endl;
- image_member im (*this, "index_", *it, "index_type", "index");
- im.traverse (m);
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "// key" << endl
- << "//" << endl;
- image_member im (*this, "key_", *kt, "key_type", "key");
- im.traverse (m);
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "// value" << endl
- << "//" << endl;
- image_member im (*this, "value_", vt, "value_type", "value");
- im.traverse (m);
- break;
- }
- }
-
- os << "std::size_t version;"
- << "};";
-
- // data_image_type (object id is taken from the object image)
- //
- os << "struct data_image_type"
- << "{";
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- {
- os << "// index" << endl
- << "//" << endl;
- image_member im (*this, "index_", *it, "index_type", "index");
- im.traverse (m);
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "// key" << endl
- << "//" << endl;
- image_member im (*this, "key_", *kt, "key_type", "key");
- im.traverse (m);
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- os << "// value" << endl
- << "//" << endl;
- image_member im (*this, "value_", vt, "value_type", "value");
- im.traverse (m);
-
- os << "std::size_t version;"
- << "};";
-
- // Statements.
- //
- os << "static const char* const insert_one_statement;"
- << "static const char* const select_all_statement;"
- << "static const char* const delete_all_statement;"
- << endl;
-
- // bind (cond_image)
- //
- os << "static void" << endl
- << "bind (MYSQL_BIND*, id_image_type*, cond_image_type&);"
- << endl;
-
- // bind (data_image)
- //
- os << "static void" << endl
- << "bind (MYSQL_BIND*, id_image_type*, data_image_type&);"
- << endl;
-
- // grow()
- //
- os << "static void" << endl
- << "grow (data_image_type&, my_bool*);"
- << endl;
-
- // init (data_image)
- //
- if (!inverse)
- {
- os << "static void" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- os << "init (data_image_type&, index_type, const value_type&);";
- else
- os << "init (data_image_type&, const value_type&);";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "init (data_image_type&, const key_type&, const value_type&);";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "init (data_image_type&, const value_type&);";
- break;
- }
- }
-
- os << endl;
- }
-
- // init (data)
- //
- os << "static void" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- os << "init (index_type&, value_type&, ";
- else
- os << "init (value_type&, ";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "init (key_type&, value_type&, ";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "init (value_type&, ";
- break;
- }
- }
-
- os << "const data_image_type&, database&);"
- << endl;
-
- // insert_one
- //
- os << "static void" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- os << "insert_one (index_type, const value_type&, void*);";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "insert_one (const key_type&, const value_type&, void*);";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "insert_one (const value_type&, void*);";
- break;
- }
- }
-
- os << endl;
-
- // load_all
- //
- os << "static bool" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- os << "load_all (index_type&, value_type&, void*);";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "load_all (key_type&, value_type&, void*);";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "load_all (value_type&, void*);";
- break;
- }
- }
-
- os << endl;
-
- // delete_all
- //
- os << "static void" << endl
- << "delete_all (void*);"
- << endl;
-
- // persist
- //
- if (!inverse)
- os << "static void" << endl
- << "persist (const container_type&," << endl
- << "id_image_type&," << endl
- << "statements_type&);"
- << endl;
-
- // load
- //
- os << "static void" << endl
- << "load (container_type&," << endl
- << "id_image_type&," << endl
- << "statements_type&);"
- << endl;
-
- // update
- //
- if (!inverse)
- os << "static void" << endl
- << "update (const container_type&," << endl
- << "id_image_type&," << endl
- << "statements_type&);"
- << endl;
-
- // erase
- //
- if (!inverse)
- os << "static void" << endl
- << "erase (id_image_type&, statements_type&);"
- << endl;
-
- os << "};";
- }
-
- private:
- string scope_;
- };
-
- //
- //
- struct class_: traversal::class_, context
- {
- class_ (context& c)
- : context (c), image_type_ (c), id_image_member_ (c, "id_")
- {
- }
-
- virtual void
- traverse (type& c)
- {
- if (c.file () != unit.file ())
- return;
-
- if (c.count ("object"))
- traverse_object (c);
- else if (comp_value (c))
- traverse_value (c);
- }
-
- virtual void
- traverse_object (type& c)
- {
- string const& type (c.fq_name ());
- bool def_ctor (TYPE_HAS_DEFAULT_CONSTRUCTOR (c.tree_node ()));
-
- semantics::data_member& id (id_member (c));
- bool auto_id (id.count ("auto"));
-
- os << "// " << c.name () << endl
- << "//" << endl;
-
- os << "template <>" << endl
- << "class access::object_traits< " << type << " >"
- << "{"
- << "public:" << endl;
-
- // object_type & pointer_type
- //
- os << "typedef " << type << " object_type;"
- << "typedef " << c.get<string> ("object-pointer") << " pointer_type;";
-
- // id_type
- //
- os << "typedef " << id.type ().fq_name (id.belongs ().hint ()) <<
- " id_type;"
- << endl;
-
- // image_type
- //
- image_type_.traverse (c);
-
- // id_image_type
- //
- os << "struct id_image_type"
- << "{";
-
- id_image_member_.traverse (id);
-
- os << "std::size_t version;"
- << "};";
-
- // query_type & query_base_type
- //
- if (options.generate_query ())
- {
- // query_base_type
- //
- os << "typedef mysql::query query_base_type;"
- << endl;
-
- // query_type
- //
- os << "struct query_type: query_base_type"
- << "{";
-
- {
- query_columns t (*this);
- t.traverse (c);
- }
-
- os << "query_type ();"
- << "query_type (const std::string&);"
- << "query_type (const query_base_type&);"
- << "};";
- }
-
- // column_count
- //
- os << "static const std::size_t in_column_count = " <<
- in_column_count (c) << "UL;"
- << "static const std::size_t out_column_count = " <<
- out_column_count (c) << "UL;"
- << endl;
-
- // Statements.
- //
- os << "static const char* const persist_statement;"
- << "static const char* const find_statement;"
- << "static const char* const update_statement;"
- << "static const char* const erase_statement;";
-
- if (options.generate_query ())
- os << "static const char* const query_clause;";
-
- os << endl;
-
- //
- // Containers.
- //
-
- // Traits types.
- //
- {
- container_traits t (*this, c);
- t.traverse (c);
- }
-
- // Statement cache (forward declaration).
- //
- os << "struct container_statement_cache_type;"
- << endl;
-
- //
- // Functions.
- //
-
- // id ()
- //
- os << "static id_type" << endl
- << "id (const object_type&);"
- << endl;
-
- if (options.generate_query ())
- os << "static id_type" << endl
- << "id (const image_type&);"
- << endl;
-
- // grow ()
- //
- os << "static void" << endl
- << "grow (image_type&, my_bool*);"
- << endl;
-
- // bind (image_type)
- //
- os << "static void" << endl
- << "bind (MYSQL_BIND*, image_type&, bool);"
- << endl;
-
- // bind (id_image_type)
- //
- os << "static void" << endl
- << "bind (MYSQL_BIND*, id_image_type&);"
- << endl;
-
- // init (image, object)
- //
- os << "static void" << endl
- << "init (image_type&, const object_type&);"
- << endl;
-
- // init (object, image)
- //
- os << "static void" << endl
- << "init (object_type&, const image_type&, database&);"
- << endl;
-
- // init (id_image, id)
- //
- os << "static void" << endl
- << "init (id_image_type&, const id_type&);"
- << endl;
-
- // persist ()
- //
- os << "static void" << endl
- << "persist (database&, " << (auto_id ? "" : "const ") <<
- "object_type&);"
- << endl;
-
- // update ()
- //
- os << "static void" << endl
- << "update (database&, const object_type&);"
- << endl;
-
- // erase ()
- //
- os << "static void" << endl
- << "erase (database&, const id_type&);"
- << endl;
-
- // find ()
- //
- if (def_ctor)
- os << "static pointer_type" << endl
- << "find (database&, const id_type&);"
- << endl;
-
- os << "static bool" << endl
- << "find (database&, const id_type&, object_type&);"
- << endl;
-
- // query ()
- //
- if (options.generate_query ())
- os << "template<typename T>" << endl
- << "static result<T>" << endl
- << "query (database&, const query_type&);"
- << endl;
-
- // create_schema ()
- //
- if (embedded_schema)
- {
- os << "static void" << endl
- << "create_schema (database&);"
- << endl;
- }
-
- // Implementation details.
- //
- os << "public:" << endl;
-
- // Load the object image.
- //
- os << "static bool" << endl
- << "find_ (mysql::object_statements< object_type >&, const id_type&);"
- << endl;
-
- // Load the rest of the object (containers, etc). Expects the id
- // image in the object statements to be initialized to the object
- // id.
- //
- os << "static void" << endl
- << "load_ (mysql::object_statements< object_type >&, object_type&);"
- << endl;
-
- if (options.generate_query ())
- os << "static void" << endl
- << "query_ (database&," << endl
- << "const query_type&," << endl
- << "mysql::object_statements< object_type >&," << endl
- << "details::shared_ptr< mysql::select_statement >&);"
- << endl;
-
- os << "};";
- }
-
- virtual void
- traverse_value (type& c)
- {
- string const& type (c.fq_name ());
-
- os << "// " << c.name () << endl
- << "//" << endl;
-
- os << "template <>" << endl
- << "class access::composite_value_traits< " << type << " >"
- << "{"
- << "public:" << endl;
-
- // object_type
- //
- os << "typedef " << type << " value_type;"
- << endl;
-
- // image_type
- //
- image_type_.traverse (c);
-
- // grow ()
- //
- os << "static bool" << endl
- << "grow (image_type&, my_bool*);"
- << endl;
-
- // bind (image_type)
- //
- os << "static void" << endl
- << "bind (MYSQL_BIND*, image_type&);"
- << endl;
-
- // init (image, object)
- //
- os << "static bool" << endl
- << "init (image_type&, const value_type&);"
- << endl;
-
- // init (object, image)
- //
- os << "static void" << endl
- << "init (value_type&, const image_type&, database&);"
- << endl;
-
- os << "};";
- }
-
- private:
- image_type image_type_;
- image_member id_image_member_;
- };
- }
-
- void
- generate_header (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;
-
- ctx.os << "#include <odb/mysql/version.hxx>" << endl
- << "#include <odb/mysql/forward.hxx>" << endl
- << "#include <odb/mysql/mysql-types.hxx>" << endl;
-
- if (ctx.options.generate_query ())
- ctx.os << "#include <odb/mysql/query.hxx>" << endl;
-
- ctx.os << endl
- << "#include <odb/details/buffer.hxx>" << endl
- << endl;
-
- ctx.os << "namespace odb"
- << "{";
-
- unit.dispatch (ctx.unit);
-
- ctx.os << "}";
- }
-}
diff --git a/odb/mysql/header.hxx b/odb/mysql/header.hxx
deleted file mode 100644
index ec7cbf1..0000000
--- a/odb/mysql/header.hxx
+++ /dev/null
@@ -1,17 +0,0 @@
-// file : odb/mysql/header.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_MYSQL_HEADER_HXX
-#define ODB_MYSQL_HEADER_HXX
-
-#include <odb/mysql/context.hxx>
-
-namespace mysql
-{
- void
- generate_header (context&);
-}
-
-#endif // ODB_MYSQL_HEADER_HXX
diff --git a/odb/mysql/inline.cxx b/odb/mysql/inline.cxx
deleted file mode 100644
index 1ab16ca..0000000
--- a/odb/mysql/inline.cxx
+++ /dev/null
@@ -1,129 +0,0 @@
-// file : odb/mysql/inline.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 <odb/mysql/common.hxx>
-#include <odb/mysql/inline.hxx>
-
-namespace mysql
-{
- namespace
- {
- struct class_: traversal::class_, context
- {
- class_ (context& c)
- : context (c)
- {
- }
-
- virtual void
- traverse (type& c)
- {
- if (c.file () != unit.file ())
- return;
-
- if (c.count ("object"))
- traverse_object (c);
- else if (comp_value (c))
- traverse_value (c);
- }
-
- virtual void
- traverse_object (type& c)
- {
- string const& type (c.fq_name ());
- string traits ("access::object_traits< " + type + " >");
- semantics::data_member& id (id_member (c));
-
- os << "// " << c.name () << endl
- << "//" << endl
- << endl;
-
- // query_type
- //
- if (options.generate_query ())
- {
- os << "inline" << endl
- << traits << "::query_type::" << endl
- << "query_type ()"
- << "{"
- << "}";
-
- os << "inline" << endl
- << traits << "::query_type::" << endl
- << "query_type (const std::string& q)" << endl
- << " : query_base_type (q)"
- << "{"
- << "}";
-
- os << "inline" << endl
- << traits << "::query_type::" << endl
- << "query_type (const query_base_type& q)" << endl
- << " : query_base_type (q)"
- << "{"
- << "}";
- }
-
- // id ()
- //
- os << "inline" << endl
- << traits << "::id_type" << endl
- << traits << "::" << endl
- << "id (const object_type& obj)"
- << "{"
- << "return obj." << id.name () << ";" << endl
- << "}";
-
- // load_()
- //
- if (!has_a (c, test_container))
- {
- os << "inline" << endl
- << "void " << traits << "::" << endl
- << "load_ (mysql::object_statements< object_type >&, object_type&)"
- << "{"
- << "}";
- }
- }
-
- virtual void
- traverse_value (type&)
- {
- /*
- string const& type (c.fq_name ());
- string traits ("access::composite_value_traits< " + type + " >");
-
- os << "// " << c.name () << endl
- << "//" << endl
- << endl;
-
- */
- }
- };
- }
-
- void
- generate_inline (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;
-
- ctx.os << "namespace odb"
- << "{";
-
- unit.dispatch (ctx.unit);
-
- ctx.os << "}";
- }
-}
diff --git a/odb/mysql/inline.hxx b/odb/mysql/inline.hxx
deleted file mode 100644
index e902ef3..0000000
--- a/odb/mysql/inline.hxx
+++ /dev/null
@@ -1,17 +0,0 @@
-// file : odb/mysql/inline.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_MYSQL_INLINE_HXX
-#define ODB_MYSQL_INLINE_HXX
-
-#include <odb/mysql/context.hxx>
-
-namespace mysql
-{
- void
- generate_inline (context&);
-}
-
-#endif // ODB_MYSQL_INLINE_HXX
diff --git a/odb/mysql/schema.cxx b/odb/mysql/schema.cxx
deleted file mode 100644
index b40a019..0000000
--- a/odb/mysql/schema.cxx
+++ /dev/null
@@ -1,11 +0,0 @@
-// file : odb/mysql/schema.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 <odb/mysql/schema.hxx>
-
-namespace mysql
-{
-
-}
diff --git a/odb/mysql/schema.hxx b/odb/mysql/schema.hxx
deleted file mode 100644
index 1defad7..0000000
--- a/odb/mysql/schema.hxx
+++ /dev/null
@@ -1,325 +0,0 @@
-// file : odb/mysql/schema.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_MYSQL_SCHEMA_HXX
-#define ODB_MYSQL_SCHEMA_HXX
-
-#include <set>
-
-#include <odb/emitter.hxx>
-#include <odb/mysql/common.hxx>
-
-namespace mysql
-{
- struct schema_context: context
- {
- typedef std::set<string> tables;
-
- schema_context (context& c, std::ostream& os, emitter& e)
- : context (c, os), e_ (e)
- {
- }
-
- schema_context (schema_context& c) : context (c), e_ (c.e_) {}
-
- emitter& e_;
- };
-
- //
- // Drop.
- //
-
- struct member_drop: object_members_base, schema_context
- {
- member_drop (schema_context& c, tables& t)
- : object_members_base (c, false, true),
- schema_context (c),
- tables_ (t)
- {
- }
-
- virtual void
- container (semantics::data_member& m)
- {
- // Ignore inverse containers of object pointers.
- //
- if (inverse (m, "value"))
- return;
-
- string const& name (table_name (m, table_prefix_));
-
- if (tables_.count (name))
- return;
-
- e_.pre ();
- os << "DROP TABLE IF EXISTS `" << name << "`" << endl;
- e_.post ();
-
- tables_.insert (name);
- }
-
- private:
- tables& tables_;
- };
-
- struct class_drop: traversal::class_, schema_context
- {
- class_drop (context& c, emitter& e)
- : schema_context (c, os, e), os (e),
- member_drop_ (*this, tables_)
- {
- }
-
- virtual void
- traverse (type& c)
- {
- if (c.file () != unit.file ())
- return;
-
- if (!c.count ("object"))
- return;
-
- string const& name (table_name (c));
-
- if (tables_.count (name))
- return;
-
- e_.pre ();
- os << "DROP TABLE IF EXISTS `" << name << "`" << endl;
- e_.post ();
-
- tables_.insert (name);
-
- // Drop tables for members.
- //
- member_drop_.traverse (c);
- }
-
- private:
- tables tables_;
- emitter_ostream os;
- member_drop member_drop_;
- };
-
- //
- // Create.
- //
-
- struct object_columns: object_columns_base, schema_context
- {
- object_columns (schema_context& c, string const& prefix = string ())
- : object_columns_base (c), schema_context (c), prefix_ (prefix)
- {
- }
-
- virtual bool
- column (semantics::data_member& m, string const& name, bool first)
- {
- // Ignore inverse object pointers.
- //
- if (inverse (m))
- return false;
-
- if (!first)
- os << "," << endl;
-
- os << " `" << name << "` " << column_type (m, prefix_);
-
- if (m.count ("id"))
- os << " PRIMARY KEY";
-
- using semantics::class_;
- if (class_* c = object_pointer (member_type (m, prefix_)))
- {
- os << " REFERENCES `" << table_name (*c) << "` (`" <<
- column_name (id_member (*c)) << "`)";
- }
-
- return true;
- }
-
- private:
- string prefix_;
- };
-
- struct member_create: object_members_base, schema_context
- {
- member_create (schema_context& c, semantics::class_& object, tables& t)
- : object_members_base (c, false, true),
- schema_context (c),
- id_member_ (id_member (object)),
- tables_ (t)
- {
- }
-
- virtual void
- container (semantics::data_member& m)
- {
- using semantics::type;
- using semantics::data_member;
-
- // Ignore inverse containers of object pointers.
- //
- if (inverse (m, "value"))
- return;
-
- type& t (m.type ());
- container_kind_type ck (container_kind (t));
- type& vt (container_vt (t));
-
- string const& name (table_name (m, table_prefix_));
-
- if (tables_.count (name))
- return;
-
- e_.pre ();
- os << "CREATE TABLE `" << name << "` (" << endl;
-
- // object_id (simple value)
- //
- string id_name (column_name (m, "id", "object_id"));
- os << " `" << id_name << "` " << column_type (id_member_, "ref");
-
- // index (simple value)
- //
- string index_name;
- bool ordered (ck == ck_ordered && !unordered (m));
- if (ordered)
- {
- index_name = column_name (m, "index", "index");
-
- os << "," << endl
- << " `" << index_name << "` " << column_type (m, "index");
- }
-
- // key (simple or composite value)
- //
- if (ck == ck_map || ck == ck_multimap)
- {
- type& kt (container_kt (t));
-
- os << "," << endl;
-
- if (semantics::class_* ckt = comp_value (kt))
- {
- object_columns oc (*this);
- oc.traverse_composite (m, *ckt, "key", "key");
- }
- else
- {
- object_columns oc (*this, "key");
- string const& name (column_name (m, "key", "key"));
- oc.column (m, name, true);
- }
- }
-
- // value (simple or composite value)
- //
- {
- os << "," << endl;
-
- if (semantics::class_* cvt = comp_value (vt))
- {
- object_columns oc (*this);
- oc.traverse_composite (m, *cvt, "value", "value");
- }
- else
- {
- object_columns oc (*this, "value");
- string const& name (column_name (m, "value", "value"));
- oc.column (m, name, true);
- }
- }
-
- // object_id index
- //
- os << "," << endl
- << " INDEX (`" << id_name << "`)";
-
- // index index
- //
- if (ordered)
- os << "," << endl
- << " INDEX (`" << index_name << "`)";
-
- os << ")";
-
- string const& engine (options.mysql_engine ());
-
- if (engine != "default")
- os << endl
- << " ENGINE=" << engine;
-
- os << endl;
- e_.post ();
-
- tables_.insert (name);
- }
-
- private:
- semantics::data_member& id_member_;
- tables& tables_;
- };
-
- struct class_create: traversal::class_, schema_context
- {
- class_create (context& c, emitter& e)
- : schema_context (c, os, e), os (e)
- {
- }
-
- virtual void
- traverse (type& c)
- {
- if (c.file () != unit.file ())
- return;
-
- if (!c.count ("object"))
- return;
-
- string const& name (table_name (c));
-
- // If the table with this name was already created, assume the
- // user knows what they are doing and skip it.
- //
- if (tables_.count (name))
- return;
-
- e_.pre ();
- os << "CREATE TABLE `" << name << "` (" << endl;
-
- {
- object_columns oc (*this);
- oc.traverse (c);
- }
-
- os << ")";
-
- string const& engine (options.mysql_engine ());
-
- if (engine != "default")
- os << endl
- << " ENGINE=" << engine;
-
- os << endl;
- e_.post ();
-
- tables_.insert (name);
-
- // Create tables for members.
- //
- {
- member_create mc (*this, c, tables_);
- mc.traverse (c);
- }
- }
-
- private:
- tables tables_;
- emitter_ostream os;
- };
-}
-
-#endif // ODB_MYSQL_SCHEMA_HXX
diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx
deleted file mode 100644
index bc7340a..0000000
--- a/odb/mysql/source.cxx
+++ /dev/null
@@ -1,3266 +0,0 @@
-// file : odb/mysql/source.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 <odb/gcc.hxx>
-
-#include <map>
-#include <set>
-#include <vector>
-#include <sstream>
-
-#include <odb/mysql/common.hxx>
-#include <odb/mysql/schema.hxx>
-#include <odb/mysql/source.hxx>
-
-using namespace std;
-
-namespace mysql
-{
- namespace
- {
- struct schema_emitter: emitter, context
- {
- schema_emitter (context& c): context (c) {}
-
- virtual void
- pre ()
- {
- first_ = true;
- os << "db.execute (";
- }
-
- virtual void
- line (const std::string& l)
- {
- if (first_)
- first_ = false;
- else
- os << endl;
-
- os << strlit (l);
- }
-
- virtual void
- post ()
- {
- os << ");" << endl;
- }
-
- private:
- bool first_;
- };
-
- struct object_columns: object_columns_base, context
- {
- object_columns (context& c,
- std::string const& table_name,
- bool out,
- char const* suffix = "")
- : object_columns_base (c),
- context (c),
- table_name_ (table_name),
- out_ (out),
- first_ (true),
- suffix_ (suffix)
- {
- }
-
- object_columns (context& c,
- std::string const& table_name,
- bool out,
- bool first,
- char const* suffix = "")
- : object_columns_base (c),
- context (c),
- table_name_ (table_name),
- out_ (out),
- first_ (first),
- suffix_ (suffix)
- {
- }
-
- virtual bool
- column (semantics::data_member& m, string const& name, bool first)
- {
- semantics::data_member* im (inverse (m));
-
- // Ignore inverse object pointers if we are generating 'in' columns.
- //
- if (im != 0 && !out_)
- return false;
-
- if (!first || !first_)
- os << ",\"" << endl;
-
- // Inverse object pointers come from a joined table.
- //
- if (im != 0)
- {
- semantics::class_* c (object_pointer (m.type ()));
-
- if (container (im->type ()))
- {
- // This container is a direct member of the class so the table
- // prefix is just the class table name.
- //
- table_prefix tp (table_name (*c) + "_", 1);
- string const& it (table_name (*im, tp));
- string const& id (column_name (*im, "id", "object_id"));
-
- os << "\"`" << it << "`.`" << id << "`" << suffix_;
- }
- else
- {
- os << "\"`" << table_name (*c) << "`.`" <<
- column_name (id_member (*c)) << "`" << suffix_;
- }
- }
- else
- os << "\"`" << table_name_ << "`.`" << name << "`" << suffix_;
-
- return true;
- }
-
- private:
- string table_name_;
- bool out_;
- bool first_;
- string suffix_;
- };
-
- struct object_joins: object_columns_base, context
- {
- object_joins (context& c, semantics::class_& scope, bool query)
- : object_columns_base (c),
- context (c),
- query_ (query),
- table_ (table_name (scope)),
- id_ (id_member (scope))
- {
- }
-
- size_t
- count () const
- {
- return joins_.size ();
- }
-
- void
- write ()
- {
- for (joins::iterator i (joins_.begin ()); i != joins_.end (); ++i)
- {
- if (i->table.empty ())
- continue;
-
- os << "\" LEFT JOIN `" << i->table << "` ON ";
-
- for (conditions::iterator b (i->cond.begin ()), j (b);
- j != i->cond.end (); ++j)
- {
- if (j != b)
- os << " OR ";
-
- os << *j;
- }
-
- os << "\"" << endl;
- }
- }
-
- virtual bool
- column (semantics::data_member& m, string const& col_name, bool)
- {
- semantics::class_* c (object_pointer (m.type ()));
-
- if (c == 0)
- return true;
-
- string t, dt;
- ostringstream cond, dcond;
-
- if (semantics::data_member* im = inverse (m))
- {
- if (container (im->type ()))
- {
- // This container is a direct member of the class so the table
- // prefix is just the class table name.
- //
- string const& ct (table_name (*c));
- table_prefix tp (ct + "_", 1);
- t = table_name (*im, tp);
- string const& val (column_name (*im, "value", "value"));
-
- cond << "`" << t << "`.`" << val << "` = `" <<
- table_ << "`.`" << column_name (id_) << "`";
-
- // Add the join for the object itself so that we are able to
- // use it in the WHERE clause.
- //
- if (query_)
- {
- dt = ct;
- string const& id (column_name (*im, "id", "object_id"));
-
- dcond << "`" << dt << "`.`" << column_name (id_member (*c)) <<
- "` = `" << t << "`.`" << id << "`";
- }
- }
- else
- {
- t = table_name (*c);
-
- cond << "`" << t << "`.`" << column_name (*im) << "` = `" <<
- table_ << "`.`" << column_name (id_) << "`";
- }
- }
- else if (query_)
- {
- // We need the join to be able to use the referenced object
- // in the WHERE clause.
- //
- t = table_name (*c);
-
- cond << "`" << t << "`.`" << column_name (id_member (*c)) <<
- "` = `" << table_ << "`.`" << col_name << "`";
- }
-
- if (!t.empty ())
- {
- size_t i;
- table_map::iterator it (table_map_.find (t));
-
- if (it != table_map_.end ())
- i = it->second;
- else
- {
- i = joins_.size ();
- joins_.push_back (join ());
- table_map_[t] = i;
- }
-
- joins_[i].table = t;
- joins_[i].cond.insert (cond.str ());
- }
-
- if (!dt.empty ())
- {
- // Add dependent join. If one already exists, move it to the
- // bottom.
- //
- size_t i;
- table_map::iterator it (table_map_.find (dt));
-
- if (it != table_map_.end ())
- {
- i = joins_.size ();
- joins_.push_back (join ());
- joins_[it->second].swap (joins_.back ());
- it->second = i;
- }
- else
- {
- i = joins_.size ();
- joins_.push_back (join ());
- table_map_[dt] = i;
- }
-
- joins_[i].table = dt;
- joins_[i].cond.insert (dcond.str ());
- }
-
- return true;
- }
-
- private:
- bool query_;
- string table_;
- semantics::data_member& id_;
-
- typedef set<string> conditions;
-
- struct join
- {
- string table;
- conditions cond;
-
- void
- swap (join& o)
- {
- table.swap (o.table);
- cond.swap (o.cond);
- }
- };
-
- typedef vector<join> joins;
- typedef map<string, size_t> table_map;
-
- joins joins_;
- table_map table_map_;
- };
-
- const char* integer_buffer_types[] =
- {
- "MYSQL_TYPE_TINY",
- "MYSQL_TYPE_SHORT",
- "MYSQL_TYPE_LONG", // *_bind_param() doesn't support INT24.
- "MYSQL_TYPE_LONG",
- "MYSQL_TYPE_LONGLONG"
- };
-
- const char* float_buffer_types[] =
- {
- "MYSQL_TYPE_FLOAT",
- "MYSQL_TYPE_DOUBLE"
- };
-
- const char* date_time_buffer_types[] =
- {
- "MYSQL_TYPE_DATE",
- "MYSQL_TYPE_TIME",
- "MYSQL_TYPE_DATETIME",
- "MYSQL_TYPE_TIMESTAMP",
- "MYSQL_TYPE_SHORT"
- };
-
- const char* char_bin_buffer_types[] =
- {
- "MYSQL_TYPE_STRING", // CHAR
- "MYSQL_TYPE_BLOB", // BINARY,
- "MYSQL_TYPE_STRING", // VARCHAR
- "MYSQL_TYPE_BLOB", // VARBINARY
- "MYSQL_TYPE_STRING", // TINYTEXT
- "MYSQL_TYPE_BLOB", // TINYBLOB
- "MYSQL_TYPE_STRING", // TEXT
- "MYSQL_TYPE_BLOB", // BLOB
- "MYSQL_TYPE_STRING", // MEDIUMTEXT
- "MYSQL_TYPE_BLOB", // MEDIUMBLOB
- "MYSQL_TYPE_STRING", // LONGTEXT
- "MYSQL_TYPE_BLOB" // LONGBLOB
- };
-
- //
- // bind
- //
-
- struct bind_member: member_base
- {
- bind_member (context& c,
- string const& var = string (),
- string const& arg = string ())
- : member_base (c, var), arg_override_ (arg)
- {
- }
-
- bind_member (context& c,
- string const& var,
- string const& arg,
- semantics::type& t,
- string const& fq_type,
- string const& key_prefix)
- : member_base (c, var, t, fq_type, key_prefix), arg_override_ (arg)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- if (container (mi.t))
- return false;
-
- ostringstream ostr;
- ostr << "b[n]";
- b = ostr.str ();
-
- arg = arg_override_.empty () ? string ("i") : arg_override_;
-
- if (var_override_.empty ())
- {
- os << "// " << mi.m.name () << endl
- << "//" << endl;
-
- if (inverse (mi.m, key_prefix_))
- os << "if (out)"
- << "{";
- }
-
- return true;
- }
-
- virtual void
- post (member_info& mi)
- {
- if (var_override_.empty ())
- {
- if (semantics::class_* c = comp_value (mi.t))
- os << "n += " << in_column_count (*c) << "UL;";
- else
- os << "n++;";
-
- if (inverse (mi.m, key_prefix_))
- os << "}";
- else
- os << endl;
- }
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- os << "composite_value_traits< " << mi.fq_type () <<
- " >::bind (b + n, " << arg << "." << mi.var << "value);";
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- // While the is_unsigned should indicate whether the
- // buffer variable is unsigned, rather than whether the
- // database type is unsigned, in case of the image types,
- // this is the same.
- //
- os << b << ".buffer_type = " <<
- integer_buffer_types[mi.st->type - sql_type::TINYINT] << ";"
- << b << ".is_unsigned = " << (mi.st->unsign ? "1" : "0") << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << b << ".buffer_type = " <<
- float_buffer_types[mi.st->type - sql_type::FLOAT] << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- os << b << ".buffer_type = MYSQL_TYPE_NEWDECIMAL;"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "" << arg << "." << mi.var << "value.capacity ());"
- << b << ".length = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << b << ".buffer_type = " <<
- date_time_buffer_types[mi.st->type - sql_type::DATE] << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;";
-
- if (mi.st->type == sql_type::YEAR)
- os << b << ".is_unsigned = 0;";
-
- os << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_short_string (member_info& mi)
- {
- // MySQL documentation is quite confusing about the use of
- // buffer_length and length when it comes to input parameters.
- // Source code, however, tells us that it uses buffer_length
- // only if length is NULL.
- //
- os << b << ".buffer_type = " <<
- char_bin_buffer_types[mi.st->type - sql_type::CHAR] << ";"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "" << arg << "." << mi.var << "value.capacity ());"
- << b << ".length = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << b << ".buffer_type = " <<
- char_bin_buffer_types[mi.st->type - sql_type::CHAR] << ";"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "" << arg << "." << mi.var << "value.capacity ());"
- << b << ".length = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- // Treated as a BLOB.
- //
- os << b << ".buffer_type = MYSQL_TYPE_BLOB;"
- << b << ".buffer = " << arg << "." << mi.var << "value;"
- << b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "sizeof (" << arg << "." << mi.var << "value));"
- << b << ".length = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_enum (member_info& mi)
- {
- // Represented as a string.
- //
- os << b << ".buffer_type = MYSQL_TYPE_STRING;"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "" << arg << "." << mi.var << "value.capacity ());"
- << b << ".length = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- virtual void
- traverse_set (member_info& mi)
- {
- // Represented as a string.
- //
- os << b << ".buffer_type = MYSQL_TYPE_STRING;"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
- << b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "" << arg << "." << mi.var << "value.capacity ());"
- << b << ".length = &" << arg << "." << mi.var << "size;"
- << b << ".is_null = &" << arg << "." << mi.var << "null;";
- }
-
- private:
- string b;
- string arg;
- string arg_override_;
- };
-
- struct bind_base: traversal::class_, context
- {
- bind_base (context& c)
- : context (c)
- {
- }
-
- virtual void
- traverse (type& c)
- {
- // Ignore transient bases.
- //
- if (!(c.count ("object") || comp_value (c)))
- return;
-
- os << "// " << c.name () << " base" << endl
- << "//" << endl
- << "composite_value_traits< " << c.fq_name () <<
- " >::bind (b + n, i);"
- << "n += " << in_column_count (c) << "UL;"
- << endl;
- }
- };
-
- //
- // grow
- //
-
- struct grow_member: member_base
- {
- grow_member (context& c, size_t& index)
- : member_base (c), index_ (index)
- {
- }
-
- grow_member (context& c,
- size_t& index,
- string const& var,
- semantics::type& t,
- string const& fq_type,
- string const& key_prefix)
- : member_base (c, var, t, fq_type, key_prefix), index_ (index)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- if (container (mi.t))
- return false;
-
- ostringstream ostr;
- ostr << "e[" << index_ << "UL]";
- e = ostr.str ();
-
- if (var_override_.empty ())
- os << "// " << mi.m.name () << endl
- << "//" << endl;
-
- return true;
- }
-
- virtual void
- post (member_info& mi)
- {
- if (semantics::class_* c = comp_value (mi.t))
- index_ += in_column_count (*c);
- else
- index_++;
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- os << "if (composite_value_traits< " << mi.fq_type () <<
- " >::grow (" << endl
- << "i." << mi.var << "value, e + " << index_ << "UL))"
- << "{"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_integer (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_float (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- // @@ Optimization disabled.
- //
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_date_time (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_short_string (member_info& mi)
- {
- // @@ Optimization disabled.
- //
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_bit (member_info&)
- {
- os << e << " = 0;"
- << endl;
- }
-
- virtual void
- traverse_enum (member_info& mi)
- {
- // Represented as a string.
- //
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_set (member_info& mi)
- {
- // Represented as a string.
- //
- os << "if (" << e << ")" << endl
- << "{"
- << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
- << "grew = true;"
- << "}";
- }
-
- private:
- string e;
- size_t& index_;
- };
-
- struct grow_base: traversal::class_, context
- {
- grow_base (context& c, size_t& index)
- : context (c), index_ (index)
- {
- }
-
- virtual void
- traverse (type& c)
- {
- // Ignore transient bases.
- //
- if (!(c.count ("object") || comp_value (c)))
- return;
-
- os << "// " << c.name () << " base" << endl
- << "//" << endl
- << "if (composite_value_traits< " << c.fq_name () <<
- " >::grow (i, e + " << index_ << "UL))"
- << "{"
- << "grew = true;"
- << "}";
-
- index_ += in_column_count (c);
- }
-
- private:
- size_t& index_;
- };
-
- //
- // init image
- //
-
- struct init_image_member: member_base
- {
- init_image_member (context& c,
- string const& var = string (),
- string const& member = string ())
- : member_base (c, var),
- member_image_type_ (c),
- member_database_type_ (c),
- member_override_ (member)
- {
- }
-
- init_image_member (context& c,
- string const& var,
- string const& member,
- semantics::type& t,
- string const& fq_type,
- string const& key_prefix)
- : member_base (c, var, t, fq_type, key_prefix),
- member_image_type_ (c, t, fq_type, key_prefix),
- member_database_type_ (c, t, fq_type, key_prefix),
- member_override_ (member)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- // Ignore containers (they get their own table) and inverse
- // object pointers (they are not present in the 'in' binding).
- //
- if (container (mi.t) || inverse (mi.m, key_prefix_))
- return false;
-
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- string const& name (mi.m.name ());
- member = "o." + name;
-
- os << "// " << name << endl
- << "//" << endl;
- }
-
- if (comp_value (mi.t))
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_type (mi.m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (mt))
- {
- type = "obj_traits::id_type";
- image_type = member_image_type_.image_type (mi.m);
- db_type = member_database_type_.database_type (mi.m);
-
- // Handle NULL pointers and extract the id.
- //
- os << "{"
- << "typedef object_traits< " << c->fq_name () <<
- " > obj_traits;";
-
- if (weak_pointer (mt))
- {
- os << "typedef pointer_traits< " << mi.fq_type () <<
- " > wptr_traits;"
- << "typedef pointer_traits< wptr_traits::" <<
- "strong_pointer_type > ptr_traits;"
- << endl
- << "wptr_traits::strong_pointer_type sp (" <<
- "wptr_traits::lock (" << member << "));";
-
- member = "sp";
- }
- else
- os << "typedef pointer_traits< " << mi.fq_type () <<
- " > ptr_traits;"
- << endl;
-
- os << "bool is_null (ptr_traits::null_ptr (" << member << "));"
- << "if (!is_null)"
- << "{"
- << "const " << type << "& id (" << endl;
-
- if (lazy_pointer (mt))
- os << "ptr_traits::object_id< ptr_traits::element_type > (" <<
- member << ")";
- else
- os << "obj_traits::id (ptr_traits::get_ref (" << member << "))";
-
- os << ");"
- << endl;
-
- member = "id";
- }
- else
- {
- type = mi.fq_type ();
- image_type = member_image_type_.image_type (mi.m);
- db_type = member_database_type_.database_type (mi.m);
-
- os << "{"
- << "bool is_null;";
- }
-
- traits = "mysql::value_traits<\n "
- + type + ",\n "
- + image_type + ",\n "
- + db_type + " >";
- }
-
- return true;
- }
-
- virtual void
- post (member_info& mi)
- {
- if (!comp_value (mi.t))
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- if (object_pointer (member_type (mi.m, key_prefix_)))
- {
- os << "}";
-
- if (!null_pointer (mi.m, key_prefix_))
- os << "else" << endl
- << "throw null_pointer ();";
- }
-
- os << "i." << mi.var << "null = is_null;"
- << "}";
- }
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- os << "if (" << traits << "::init (i." << mi.var << "value, " <<
- member << "))"
- << "{"
- << "grew = true;"
- << "}";
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");";
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");";
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- // @@ Optimization: can remove growth check if buffer is fixed.
- //
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");";
- }
-
- virtual void
- traverse_short_string (member_info& mi)
- {
- // @@ Optimization: can remove growth check if buffer is fixed.
- //
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- // Represented as a BLOB.
- //
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "sizeof (i." << mi.var << "value)," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size = static_cast<unsigned long> (size);";
- }
-
- virtual void
- traverse_enum (member_info& mi)
- {
- // Represented as a string.
- //
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- virtual void
- traverse_set (member_info& mi)
- {
- // Represented as a string.
- //
- os << "std::size_t size (0);"
- << "std::size_t cap (i." << mi.var << "value.capacity ());"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
- }
-
- private:
- string type;
- string db_type;
- string member;
- string image_type;
- string traits;
-
- member_image_type member_image_type_;
- member_database_type member_database_type_;
-
- string member_override_;
- };
-
- struct init_image_base: traversal::class_, context
- {
- init_image_base (context& c)
- : context (c)
- {
- }
-
- virtual void
- traverse (type& c)
- {
- // Ignore transient bases.
- //
- if (!(c.count ("object") || comp_value (c)))
- return;
-
- os << "// " << c.name () << " base" << endl
- << "//" << endl
- << "if (composite_value_traits< " << c.fq_name () <<
- " >::init (i, o))"
- << "{"
- << "grew = true;"
- << "}";
- }
- };
-
- //
- // init value
- //
-
- struct init_value_member: member_base
- {
- init_value_member (context& c, string const& member = string ())
- : member_base (c),
- member_image_type_ (c),
- member_database_type_ (c),
- member_override_ (member)
- {
- }
-
- init_value_member (context& c,
- string const& var,
- string const& member,
- semantics::type& t,
- string const& fq_type,
- string const& key_prefix)
- : member_base (c, var, t, fq_type, key_prefix),
- member_image_type_ (c, t, fq_type, key_prefix),
- member_database_type_ (c, t, fq_type, key_prefix),
- member_override_ (member)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- if (container (mi.t))
- return false;
-
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- string const& name (mi.m.name ());
- member = "o." + name;
-
- os << "// " << name << endl
- << "//" << endl;
- }
-
- if (comp_value (mi.t))
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_type (mi.m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (mt))
- {
- type = "obj_traits::id_type";
- image_type = member_image_type_.image_type (mi.m);
- db_type = member_database_type_.database_type (mi.m);
-
- // Handle NULL pointers and extract the id.
- //
- os << "{"
- << "typedef object_traits< " << c->fq_name () <<
- " > obj_traits;"
- << "typedef pointer_traits< " << mi.fq_type () <<
- " > ptr_traits;"
- << endl
- << "if (i." << mi.var << "null)" << endl;
-
- if (null_pointer (mi.m, key_prefix_))
- os << member << " = ptr_traits::pointer_type ();";
- else
- os << "throw null_pointer ();";
-
- os << "else"
- << "{"
- << type << " id;";
-
- member = "id";
- }
- else
- {
- type = mi.fq_type ();
- image_type = member_image_type_.image_type (mi.m);
- db_type = member_database_type_.database_type (mi.m);
- }
-
- traits = "mysql::value_traits<\n "
- + type + ",\n "
- + image_type + ",\n "
- + db_type + " >";
- }
-
- return true;
- }
-
- virtual void
- post (member_info& mi)
- {
- if (comp_value (mi.t))
- return;
-
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_type (mi.m, key_prefix_));
-
- if (object_pointer (mt))
- {
- member = member_override_.empty ()
- ? "o." + mi.m.name ()
- : member_override_;
-
- if (lazy_pointer (mt))
- os << member << " = ptr_traits::pointer_type (db, id);";
- else
- os << "// If a compiler error points to the line below, then" << endl
- << "// it most likely means that a pointer used in a member" << endl
- << "// cannot be initialized from an object pointer." << endl
- << "//" << endl
- << member << " = ptr_traits::pointer_type (" << endl
- << "db.load< ptr_traits::element_type > (id));";
-
- os << "}"
- << "}";
- }
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- os << traits << "::init (" << member << ", i." <<
- mi.var << "value, db);"
- << endl;
- }
-
- virtual void
- traverse_integer (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << ", i." << mi.var << "value, " <<
- "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << ", i." << mi.var << "value, " <<
- "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_decimal (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_date_time (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << ", i." << mi.var << "value, " <<
- "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_short_string (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_long_string (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_bit (member_info& mi)
- {
- // Represented as a BLOB.
- //
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_enum (member_info& mi)
- {
- // Represented as a string.
- //
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- virtual void
- traverse_set (member_info& mi)
- {
- // Represented as a string.
- //
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "null);"
- << endl;
- }
-
- private:
- string type;
- string db_type;
- string image_type;
- string traits;
- string member;
-
- member_image_type member_image_type_;
- member_database_type member_database_type_;
-
- string member_override_;
- };
-
- struct init_value_base: traversal::class_, context
- {
- init_value_base (context& c)
- : context (c)
- {
- }
-
- virtual void
- traverse (type& c)
- {
- // Ignore transient bases.
- //
- if (!(c.count ("object") || comp_value (c)))
- return;
-
- os << "// " << c.name () << " base" << endl
- << "//" << endl
- << "composite_value_traits< " << c.fq_name () <<
- " >::init (o, i, db);"
- << endl;
- }
- };
-
- // Member-specific traits types for container members.
- //
- struct container_traits: object_members_base, context
- {
- container_traits (context& c, semantics::class_& obj)
- : object_members_base (c, true, true),
- context (c),
- object_ (obj),
- id_member_ (id_member (obj))
- {
- obj_scope_ = "access::object_traits< " + obj.fq_name () + " >";
- }
-
- virtual void
- container (semantics::data_member& m)
- {
- using semantics::type;
-
- type& t (m.type ());
- container_kind_type ck (container_kind (t));
-
- type& vt (container_vt (t));
- type* it (0);
- type* kt (0);
-
- semantics::data_member* im (context::inverse (m, "value"));
-
- bool ordered (false);
- bool inverse (im != 0);
- bool grow (false);
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (!unordered (m))
- {
- it = &container_it (t);
- ordered = true;
- grow = grow || context::grow (m, *it, "index");
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- kt = &container_kt (t);
- grow = grow || context::grow (m, *kt, "key");
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- grow = grow || context::grow (m, vt, "value");
-
- bool eager_ptr (is_a (m, test_eager_pointer, vt, "value") ||
- has_a (vt, test_eager_pointer));
-
- string name (prefix_ + public_name (m) + "_traits");
- string scope (obj_scope_ + "::" + name);
-
- os << "// " << m.name () << endl
- << "//" << endl
- << endl;
-
- //
- // Statements.
- //
- string table (table_name (m, table_prefix_));
-
- // select_all_statement
- //
- os << "const char* const " << scope <<
- "::select_all_statement =" << endl;
-
- if (inverse)
- {
- semantics::class_* c (object_pointer (vt));
-
- string inv_table; // Other table name.
- string inv_id; // Other id column.
- string inv_fid; // Other foreign id column (ref to us).
-
- if (context::container (im->type ()))
- {
- // many(i)-to-many
- //
-
- // This other container is a direct member of the class so the
- // table prefix is just the class table name.
- //
- table_prefix tp (table_name (*c) + "_", 1);
- inv_table = table_name (*im, tp);
- inv_id = column_name (*im, "id", "object_id");
- inv_fid = column_name (*im, "value", "value");
- }
- else
- {
- // many(i)-to-one
- //
- inv_table = table_name (*c);
- inv_id = column_name (id_member (*c));
- inv_fid = column_name (*im);
- }
-
- os << "\"SELECT \"" << endl
- << "\"`" << inv_fid << "`,\"" << endl
- << "\"`" << inv_id << "`\"" << endl
- << "\" FROM `" << inv_table << "` WHERE `" <<
- inv_fid << "` = ?\"";
- }
- else
- {
- os << "\"SELECT \"" << endl
- << "\"`" << column_name (m, "id", "object_id") << "`";
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- {
- os << ",\"" << endl
- << "\"`" << column_name (m, "index", "index") << "`";
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- if (semantics::class_* ckt = comp_value (*kt))
- {
- object_columns t (*this, table, false, false);
- t.traverse_composite (m, *ckt, "key", "key");
- }
- else
- {
- os << ",\"" << endl
- << "\"`" << column_name (m, "key", "key") << "`";
- }
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- if (semantics::class_* cvt = comp_value (vt))
- {
- object_columns t (*this, table, false, false);
- t.traverse_composite (m, *cvt, "value", "value");
- }
- else
- {
- os << ",\"" << endl
- << "\"`" << column_name (m, "value", "value") << "`";
- }
-
- os << "\"" << endl
- << "\" FROM `" << table << "` WHERE `" <<
- column_name (m, "id", "object_id") << "` = ?\"" << endl;
-
- if (ordered)
- os << "\" ORDER BY `" << column_name (m, "index", "index") <<
- "`\"";
- }
-
- os << ";"
- << endl;
-
- // insert_one_statement
- //
- os << "const char* const " << scope <<
- "::insert_one_statement =" << endl;
-
- if (inverse)
- os << " \"\";"
- << endl;
- else
- {
- os << "\"INSERT INTO `" << table << "` (\"" << endl
- << "\"`" << column_name (m, "id", "object_id") << "`";
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- {
- os << ",\"" << endl
- << "\"`" << column_name (m, "index", "index") << "`";
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- if (semantics::class_* ckt = comp_value (*kt))
- {
- object_columns t (*this, table, false, false);
- t.traverse_composite (m, *ckt, "key", "key");
- }
- else
- {
- os << ",\"" << endl
- << "\"`" << column_name (m, "key", "key") << "`";
- }
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- if (semantics::class_* cvt = comp_value (vt))
- {
- object_columns t (*this, table, false, false);
- t.traverse_composite (m, *cvt, "value", "value");
- }
- else
- {
- os << ",\"" << endl
- << "\"`" << column_name (m, "value", "value") << "`";
- }
-
- os << "\"" << endl
- << "\") VALUES (";
-
- for (size_t i (0), n (m.get<size_t> ("data-column-count")); i < n; ++i)
- os << (i != 0 ? "," : "") << '?';
-
- os << ")\";"
- << endl;
- }
-
- // delete_all_statement
- //
- os << "const char* const " << scope <<
- "::delete_all_statement =" << endl;
-
- if (inverse)
- os << " \"\";"
- << endl;
- else
- {
- os << "\"DELETE FROM `" << table << "`\"" << endl
- << "\" WHERE `" << column_name (m, "id", "object_id") << "` = ?\";"
- << endl;
- }
-
- //
- // Functions.
- //
-
- // bind()
- //
- {
- bind_member bind_id (*this, "id_", "id");
-
- // bind (cond_image_type)
- //
- os << "void " << scope << "::" << endl
- << "bind (MYSQL_BIND* b, id_image_type* p, cond_image_type& c)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (c);"
- << endl
- << "std::size_t n (0);"
- << endl;
-
- os << "// object_id" << endl
- << "//" << endl
- << "if (p != 0)"
- << "{"
- << "id_image_type& id (*p);";
- bind_id.traverse (id_member_);
- os << "}"
- << "n++;"
- << endl;
-
- // We don't need to update the bind index since this is the
- // last element.
- //
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- {
- os << "// index" << endl
- << "//" << endl;
- bind_member bm (
- *this, "index_", "c", *it, "index_type", "index");
- bm.traverse (m);
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "// key" << endl
- << "//" << endl;
- bind_member bm (*this, "key_", "c", *kt, "key_type", "key");
- bm.traverse (m);
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "// value" << endl
- << "//" << endl;
- bind_member bm (*this, "value_", "c", vt, "value_type", "value");
- bm.traverse (m);
- break;
- }
- }
-
- os << "}";
-
- // bind (data_image_type)
- //
- os << "void " << scope << "::" << endl
- << "bind (MYSQL_BIND* b, id_image_type* p, data_image_type& d)"
- << "{"
- << "size_t n (0);"
- << endl;
-
- os << "// object_id" << endl
- << "//" << endl
- << "if (p != 0)"
- << "{"
- << "id_image_type& id (*p);";
- bind_id.traverse (id_member_);
- os << "}"
- << "n++;"
- << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- {
- os << "// index" << endl
- << "//" << endl;
- bind_member bm (
- *this, "index_", "d", *it, "index_type", "index");
- bm.traverse (m);
- os << "n++;" // Simple value.
- << endl;
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "// key" << endl
- << "//" << endl;
- bind_member bm (*this, "key_", "d", *kt, "key_type", "key");
- bm.traverse (m);
-
- if (semantics::class_* c = comp_value (*kt))
- os << "n += " << in_column_count (*c) << "UL;"
- << endl;
- else
- os << "n++;"
- << endl;
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- // We don't need to update the bind index since this is the
- // last element.
- //
- os << "// value" << endl
- << "//" << endl;
- bind_member bm (*this, "value_", "d", vt, "value_type", "value");
- bm.traverse (m);
-
- os << "}";
- }
-
- // grow ()
- //
- {
- size_t index (0);
-
- os << "void " << scope << "::" << endl
- << "grow (data_image_type& i, my_bool* e)"
- << "{"
- << "bool grew (false);"
- << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- {
- os << "// index" << endl
- << "//" << endl;
- grow_member gm (
- *this, index, "index_", *it, "index_type", "index");
- gm.traverse (m);
- }
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "// key" << endl
- << "//" << endl;
- grow_member gm (*this, index, "key_", *kt, "key_type", "key");
- gm.traverse (m);
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- break;
- }
- }
-
- os << "// value" << endl
- << "//" << endl;
- grow_member gm (*this, index, "value_", vt, "value_type", "value");
- gm.traverse (m);
-
- os << "if (grew)" << endl
- << "i.version++;"
- << "}";
- }
-
- // init (data_image)
- //
- if (!inverse)
- {
- os << "void " << scope << "::" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- os << "init (data_image_type& i, index_type j, " <<
- "const value_type& v)";
- else
- os << "init (data_image_type& i, const value_type& v)";
-
- os<< "{"
- << "bool grew (false);"
- << endl;
-
- if (ordered)
- {
- os << "// index" << endl
- << "//" << endl;
-
- init_image_member im (
- *this, "index_", "j", *it, "index_type", "index");
- im.traverse (m);
- }
-
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "init (data_image_type& i, const key_type& k, " <<
- "const value_type& v)"
- << "{"
- << "bool grew (false);"
- << endl
- << "// key" << endl
- << "//" << endl;
-
- init_image_member im (
- *this, "key_", "k", *kt, "key_type", "key");
- im.traverse (m);
-
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "init (data_image_type& i, const value_type& v)"
- << "{"
- << "bool grew (false);"
- << endl;
- break;
- }
- }
-
- os << "// value" << endl
- << "//" << endl;
- {
- init_image_member im (
- *this, "value_", "v", vt, "value_type", "value");
- im.traverse (m);
- }
-
- os << "if (grew)" << endl
- << "i.version++;"
- << "}";
- }
-
- // init (data)
- //
- os << "void " << scope << "::" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- if (ordered)
- os << "init (index_type& j, value_type& v, " <<
- "const data_image_type& i, database& db)";
- else
- os << "init (value_type& v, const data_image_type& i, " <<
- "database& db)";
-
- os << "{"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl;
-
- if (ordered)
- {
- os << "// index" << endl
- << "//" << endl;
-
- init_value_member im (
- *this, "index_", "j", *it, "index_type", "index");
- im.traverse (m);
- }
-
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "init (key_type& k, value_type& v, " <<
- "const data_image_type& i, database& db)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl
- << "// key" << endl
- << "//" << endl;
-
- init_value_member im (*this, "key_", "k", *kt, "key_type", "key");
- im.traverse (m);
-
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "init (value_type& v, const data_image_type& i, " <<
- "database& db)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl;
- break;
- }
- }
-
- os << "// value" << endl
- << "//" << endl;
- {
- // If the value is an object pointer, pass the id type as a
- // type override.
- //
- init_value_member im (
- *this, "value_", "v", vt, "value_type", "value");
- im.traverse (m);
- }
- os << "}";
-
- // insert_one
- //
- {
- string ia, ka, va, da;
-
- if (!inverse)
- {
- ia = ordered ? " i" : "";
- ka = " k";
- va = " v";
- da = " d";
- }
-
- os << "void " << scope << "::" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- os << "insert_one (index_type" << ia << ", " <<
- "const value_type&" << va << ", " <<
- "void*" << da << ")";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "insert_one (const key_type&" << ka << ", " <<
- "const value_type&" << va << ", " <<
- "void*" << da << ")";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "insert_one (const value_type&" << va << ", " <<
- "void*" << da << ")";
- break;
- }
- }
-
- os << "{";
-
- if (!inverse)
- {
- os << "using namespace mysql;"
- << endl
- << "typedef container_statements< " << name << " > statements;"
- << "statements& sts (*static_cast< statements* > (d));"
- << "binding& b (sts.data_image_binding ());"
- << "data_image_type& di (sts.data_image ());"
- << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- os << "init (di, " << (ordered ? "i, " : "") << "v);";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "init (di, k, v);";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "init (di, v);";
- break;
- }
- }
-
- os << endl
- << "if (di.version != sts.data_image_version () || " <<
- "b.version == 0)"
- << "{"
- << "bind (b.bind, 0, di);"
- << "sts.data_image_version (di.version);"
- << "b.version++;"
- << "}"
- << "if (!sts.insert_one_statement ().execute ())" << endl
- << "throw object_already_persistent ();";
- }
-
- os << "}";
- }
-
-
- // load_all
- //
- os << "bool " << scope << "::" << endl;
-
- switch (ck)
- {
- case ck_ordered:
- {
- os << "load_all (index_type&" << (ordered ? " i" : "") <<
- ", value_type& v, void* d)";
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "load_all (key_type& k, value_type& v, void* d)";
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "load_all (value_type& v, void* d)";
- break;
- }
- }
-
- os << "{"
- << "using namespace mysql;"
- << endl
- << "typedef container_statements< " << name << " > statements;"
- << "statements& sts (*static_cast< statements* > (d));"
- << "data_image_type& di (sts.data_image ());";
-
- // Extract current element.
- //
- switch (ck)
- {
- case ck_ordered:
- {
- os << "init (" << (ordered ? "i, " : "") <<
- "v, di, sts.connection ().database ());"
- << endl;
- break;
- }
- case ck_map:
- case ck_multimap:
- {
- os << "init (k, v, di, sts.connection ().database ());"
- << endl;
- break;
- }
- case ck_set:
- case ck_multiset:
- {
- os << "init (v, di, sts.connection ().database ());"
- << endl;
- break;
- }
- }
-
- // If we are loading an eager pointer, then the call to init
- // above executes other statements which potentially could
- // change the image.
- //
- if (eager_ptr)
- {
- os << "id_image_type& ii (sts.id_image ());"
- << endl
- << "if (di.version != sts.data_image_version () ||" << endl
- << "ii.version != sts.data_id_image_version ())"
- << "{"
- << "binding& b (sts.data_image_binding ());"
- << "bind (b.bind, &ii, di);"
- << "sts.data_image_version (di.version);"
- << "sts.data_id_image_version (ii.version);"
- << "b.version++;"
- << "}";
- }
-
- // Fetch next.
- //
- os << "select_statement& st (sts.select_all_statement ());"
- << "select_statement::result r (st.fetch ());";
-
- if (grow)
- os << endl
- << "if (r == select_statement::truncated)"
- << "{"
- << "grow (di, sts.data_image_error ());"
- << endl
- << "if (di.version != sts.data_image_version ())"
- << "{"
- << "binding& b (sts.data_image_binding ());"
- << "bind (b.bind, 0, di);"
- << "sts.data_image_version (di.version);"
- << "b.version++;"
- << "st.refetch ();"
- << "}"
- << "}";
-
- os << "if (r == select_statement::no_data)"
- << "{"
- << "st.free_result ();"
- << "return false;"
- << "}"
- << "return true;"
- << "}";
-
- // delete_all
- //
- os << "void " << scope << "::" << endl
- << "delete_all (void*" << (inverse ? "" : " d") << ")"
- << "{";
-
- if (!inverse)
- os << "using namespace mysql;"
- << endl
- << "typedef container_statements< " << name << " > statements;"
- << "statements& sts (*static_cast< statements* > (d));"
- << "sts.delete_all_statement ().execute ();";
-
- os << "}";
-
- // persist
- //
- if (!inverse)
- {
- os << "void " << scope << "::" << endl
- << "persist (const container_type& c," << endl
- << "id_image_type& id," << endl
- << "statements_type& sts)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "binding& b (sts.data_image_binding ());"
- << "if (id.version != sts.data_id_image_version () || " <<
- "b.version == 0)"
- << "{"
- << "bind (b.bind, &id, sts.data_image ());"
- << "sts.data_id_image_version (id.version);"
- << "b.version++;"
- << "}"
- << "sts.id_image (id);"
- << "functions_type& fs (sts.functions ());";
-
- if (ck == ck_ordered)
- os << "fs.ordered (" << (ordered ? "true" : "false") << ");";
-
- os << "container_traits::persist (c, fs);"
- << "}";
- }
-
- // load
- //
- os << "void " << scope << "::" << endl
- << "load (container_type& c," << endl
- << "id_image_type& id," << endl
- << "statements_type& sts)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "binding& db (sts.data_image_binding ());"
- << "if (id.version != sts.data_id_image_version () || db.version == 0)"
- << "{"
- << "bind (db.bind, &id, sts.data_image ());"
- << "sts.data_id_image_version (id.version);"
- << "db.version++;"
- << "}"
- << "binding& cb (sts.cond_image_binding ());"
- << "if (id.version != sts.cond_id_image_version () || cb.version == 0)"
- << "{"
- << "bind (cb.bind, &id, sts.cond_image ());"
- << "sts.cond_id_image_version (id.version);"
- << "cb.version++;"
- << "}"
- << "select_statement& st (sts.select_all_statement ());"
- << "st.execute ();";
-
- // If we are loading eager object pointers, cache the result
- // since we will be loading other objects.
- //
- if (eager_ptr)
- os << "st.cache ();";
-
- os << "select_statement::result r (st.fetch ());";
-
- if (grow)
- os << endl
- << "if (r == select_statement::truncated)"
- << "{"
- << "data_image_type& di (sts.data_image ());"
- << "grow (di, sts.data_image_error ());"
- << endl
- << "if (di.version != sts.data_image_version ())"
- << "{"
- << "bind (db.bind, 0, sts.data_image ());"
- << "sts.data_image_version (di.version);"
- << "db.version++;"
- << "st.refetch ();"
- << "}"
- << "}";
-
- os << "bool more (r != select_statement::no_data);"
- << endl
- << "if (!more)" << endl
- << "st.free_result ();"
- << endl
- << "sts.id_image (id);"
- << "functions_type& fs (sts.functions ());";
-
- if (ck == ck_ordered)
- os << "fs.ordered (" << (ordered ? "true" : "false") << ");";
-
- os << "container_traits::load (c, more, fs);"
- << "}";
-
- // update
- //
- if (!inverse)
- {
- os << "void " << scope << "::" << endl
- << "update (const container_type& c," << endl
- << "id_image_type& id," << endl
- << "statements_type& sts)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "binding& db (sts.data_image_binding ());"
- << "if (id.version != sts.data_id_image_version () || " <<
- "db.version == 0)"
- << "{"
- << "bind (db.bind, &id, sts.data_image ());"
- << "sts.data_id_image_version (id.version);"
- << "db.version++;"
- << "}"
- //
- // We may need cond if the specialization calls delete_all.
- //
- << "binding& cb (sts.cond_image_binding ());"
- << "if (id.version != sts.cond_id_image_version () || " <<
- "cb.version == 0)"
- << "{"
- << "bind (cb.bind, &id, sts.cond_image ());"
- << "sts.cond_id_image_version (id.version);"
- << "cb.version++;"
- << "}"
- << "sts.id_image (id);"
- << "functions_type& fs (sts.functions ());";
-
- if (ck == ck_ordered)
- os << "fs.ordered (" << (ordered ? "true" : "false") << ");";
-
- os << "container_traits::update (c, fs);"
- << "}";
- }
-
- // erase
- //
- if (!inverse)
- {
- os << "void " << scope << "::" << endl
- << "erase (id_image_type& id, statements_type& sts)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "binding& b (sts.cond_image_binding ());"
- << "if (id.version != sts.cond_id_image_version () || b.version == 0)"
- << "{"
- << "bind (b.bind, &id, sts.cond_image ());"
- << "sts.cond_id_image_version (id.version);"
- << "b.version++;"
- << "}"
- << "sts.id_image (id);"
- << "functions_type& fs (sts.functions ());";
-
- if (ck == ck_ordered)
- os << "fs.ordered (" << (ordered ? "true" : "false") << ");";
-
- os << "container_traits::erase (fs);"
- << "}";
- }
- }
-
- private:
- string obj_scope_;
- semantics::class_& object_;
- semantics::data_member& id_member_;
- };
-
- // Container statement cache members.
- //
- struct container_cache_members: object_members_base, context
- {
- container_cache_members (context& c)
- : object_members_base (c, true, false), context (c)
- {
- }
-
- virtual void
- container (semantics::data_member& m)
- {
- string traits (prefix_ + public_name (m) + "_traits");
- os << "mysql::container_statements< " << traits << " > " <<
- prefix_ << m.name () << ";";
- }
- };
-
- struct container_cache_init_members: object_members_base, context
- {
- container_cache_init_members (context& c)
- : object_members_base (c, true, false), context (c), first_ (true)
- {
- }
-
- virtual void
- container (semantics::data_member& m)
- {
- if (first_)
- {
- os << endl
- << ": ";
- first_ = false;
- }
- else
- os << "," << endl
- << " ";
-
- os << prefix_ << m.name () << " (c)";
- }
-
- private:
- bool first_;
- };
-
- // Calls for container members.
- //
- struct container_calls: object_members_base, context
- {
- enum call_type
- {
- persist_call,
- load_call,
- update_call,
- erase_call
- };
-
- container_calls (context& c, call_type call)
- : object_members_base (c, true, false), context (c), call_ (call)
- {
- }
-
- virtual void
- composite (semantics::data_member& m, semantics::class_& c)
- {
- string old (obj_prefix_);
- obj_prefix_ += m.name ();
- obj_prefix_ += '.';
- object_members_base::composite (m, c);
- obj_prefix_ = old;
- }
-
- virtual void
- container (semantics::data_member& m)
- {
- using semantics::type;
-
- bool inverse (context::inverse (m, "value"));
-
- string const& name (m.name ());
- string obj_name (obj_prefix_ + name);
- string sts_name (prefix_ + name);
- string traits (prefix_ + public_name (m) + "_traits");
-
- switch (call_)
- {
- case persist_call:
- {
- if (!inverse)
- os << traits << "::persist (" << endl
- << "obj." << obj_name << "," << endl
- << "i," << endl
- << "sts.container_statment_cache ()." << sts_name << ");"
- << endl;
- break;
- }
- case load_call:
- {
- os << traits << "::load (" << endl
- << "obj." << obj_name << "," << endl
- << "i," << endl
- << "sts.container_statment_cache ()." << sts_name << ");"
- << endl;
- break;
- }
- case update_call:
- {
- if (!inverse)
- os << traits << "::update (" << endl
- << "obj." << obj_name << "," << endl
- << "i," << endl
- << "sts.container_statment_cache ()." << sts_name << ");"
- << endl;
- break;
- }
- case erase_call:
- {
- if (!inverse)
- os << traits << "::erase (" << endl
- << "i," << endl
- << "sts.container_statment_cache ()." << sts_name << ");"
- << endl;
- break;
- }
- }
- }
-
- private:
- call_type call_;
- string obj_prefix_;
- };
-
- //
- //
- struct class_: traversal::class_, context
- {
- class_ (context& c)
- : context (c),
- grow_base_ (c, index_),
- grow_member_ (c, index_),
- bind_base_ (c),
- bind_member_ (c),
- bind_id_member_ (c, "id_"),
- init_image_base_ (c),
- init_image_member_ (c),
- init_id_image_member_ (c, "id_", "id"),
- init_value_base_ (c),
- init_value_member_ (c),
- init_id_value_member_ (c, "id"),
-
- schema_emitter_ (c),
- schema_drop_ (c, schema_emitter_),
- schema_create_ (c, schema_emitter_)
- {
- grow_base_inherits_ >> grow_base_;
- grow_member_names_ >> grow_member_;
-
- bind_base_inherits_ >> bind_base_;
- bind_member_names_ >> bind_member_;
-
- init_image_base_inherits_ >> init_image_base_;
- init_image_member_names_ >> init_image_member_;
-
- init_value_base_inherits_ >> init_value_base_;
- init_value_member_names_ >> init_value_member_;
- }
-
- virtual void
- traverse (type& c)
- {
- if (c.file () != unit.file ())
- return;
-
- if (c.count ("object"))
- traverse_object (c);
- else if (comp_value (c))
- traverse_value (c);
- }
-
- virtual void
- traverse_object (type& c)
- {
- string const& type (c.fq_name ());
- string traits ("access::object_traits< " + type + " >");
-
- bool grow (context::grow (c));
- bool def_ctor (TYPE_HAS_DEFAULT_CONSTRUCTOR (c.tree_node ()));
-
- semantics::data_member& id (id_member (c));
- bool auto_id (id.count ("auto"));
- bool grow_id (context::grow (id));
-
- os << "// " << c.name () << endl
- << "//" << endl
- << endl;
-
- //
- // Containers.
- //
- bool straight_containers (has_a (c, test_straight_container));
- bool containers (straight_containers || has_a (c, test_container));
-
- // Statement cache (definition).
- //
- {
- os << "struct " << traits << "::container_statement_cache_type"
- << "{";
-
- container_cache_members cm (*this);
- cm.traverse (c);
-
- os << (containers ? "\n" : "")
- << "container_statement_cache_type (mysql::connection&" <<
- (containers ? " c" : "") << ")";
-
- container_cache_init_members im (*this);
- im.traverse (c);
-
- os << "{"
- << "}"
- << "};";
- }
-
- // Traits types.
- //
- if (containers)
- {
- container_traits t (*this, c);
- t.traverse (c);
- }
-
- // query columns
- //
- if (options.generate_query ())
- {
- query_columns t (*this, c);
- t.traverse (c);
- }
-
- string const& table (table_name (c));
-
- // persist_statement
- //
- os << "const char* const " << traits << "::persist_statement =" << endl
- << "\"INSERT INTO `" << table << "` (\"" << endl;
-
- {
- object_columns t (*this, table, false);
- t.traverse (c);
- }
-
- os << "\"" << endl
- << "\") VALUES (";
-
- for (size_t i (0), n (in_column_count (c)); i < n; ++i)
- os << (i != 0 ? "," : "") << '?';
-
- os << ")\";"
- << endl;
-
- // find_statement
- //
- os << "const char* const " << traits << "::find_statement =" << endl
- << "\"SELECT \"" << endl;
-
- {
- object_columns t (*this, table, true);
- t.traverse (c);
- }
-
- os << "\"" << endl
- << "\" FROM `" << table << "`\"" << endl;
-
- {
- object_joins t (*this, c, false);
- t.traverse (c);
- t.write ();
- }
-
- os << "\" WHERE `" << table << "`.`" << column_name (id) << "` = ?\";"
- << endl;
-
- // update_statement
- //
- os << "const char* const " << traits << "::update_statement =" << endl
- << "\"UPDATE `" << table << "` SET \"" << endl;
-
- {
- object_columns t (*this, table, false, " = ?");
- t.traverse (c);
- }
-
- os << "\"" << endl
- << "\" WHERE `" << table << "`.`" << column_name (id) << "` = ?\";"
- << endl;
-
- // erase_statement
- //
- os << "const char* const " << traits << "::erase_statement =" << endl
- << "\"DELETE FROM `" << table << "`\"" << endl
- << "\" WHERE `" << table << "`.`" << column_name (id) << "` = ?\";"
- << endl;
-
- // query_clause
- //
- if (options.generate_query ())
- {
- object_joins oj (*this, c, true);
- oj.traverse (c);
-
- // We only need DISTINCT if there are joins (object pointers)
- // and can optimize it out otherwise.
- //
- os << "const char* const " << traits << "::query_clause =" << endl
- << "\"SELECT " << (oj.count () ? "DISTINCT " : "") << "\"" << endl;
-
- {
- object_columns oc (*this, table, true);
- oc.traverse (c);
- }
-
- os << "\"" << endl
- << "\" FROM `" << table << "`\"" << endl;
-
- oj.write ();
-
- os << "\" \";"
- << endl;
- }
-
- // id
- //
- if (options.generate_query ())
- {
- os << traits << "::id_type" << endl
- << traits << "::" << endl
- << "id (const image_type& i)"
- << "{"
- << "id_type id;";
- init_id_value_member_.traverse (id);
- os << "return id;"
- << "}";
- }
-
- // grow ()
- //
- os << "void " << traits << "::" << endl
- << "grow (image_type& i, my_bool* e)"
- << "{"
- << "bool grew (false);"
- << endl;
-
- index_ = 0;
- inherits (c, grow_base_inherits_);
- names (c, grow_member_names_);
-
- os << "if (grew)" << endl
- << "i.version++;" << endl
- << "}";
-
- // bind (image_type)
- //
- os << "void " << traits << "::" << endl
- << "bind (MYSQL_BIND* b, image_type& i, bool out)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (out);"
- << endl
- << "std::size_t n (0);"
- << endl;
-
- inherits (c, bind_base_inherits_);
- names (c, bind_member_names_);
-
- os << "}";
-
- // bind (id_image_type)
- //
- os << "void " << traits << "::" << endl
- << "bind (MYSQL_BIND* b, id_image_type& i)"
- << "{"
- << "std::size_t n (0);";
- bind_id_member_.traverse (id);
- os << "}";
-
- // init (image, object)
- //
- os << "void " << traits << "::" << endl
- << "init (image_type& i, const object_type& o)"
- << "{"
- << "bool grew (false);"
- << endl;
-
- inherits (c, init_image_base_inherits_);
- names (c, init_image_member_names_);
-
- os << "if (grew)" << endl
- << "i.version++;" << endl
- << "}";
-
- // init (object, image)
- //
- os << "void " << traits << "::" << endl
- << "init (object_type& o, const image_type& i, database& db)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl;
-
- inherits (c, init_value_base_inherits_);
- names (c, init_value_member_names_);
-
- os << "}";
-
- // init (id_image, id)
- //
- os << "void " << traits << "::" << endl
- << "init (id_image_type& i, const id_type& id)"
- << "{";
-
- if (grow_id)
- os << "bool grew (false);";
-
- init_id_image_member_.traverse (id);
-
- if (grow_id)
- os << endl
- << "if (grew)" << endl
- << "i.version++;";
-
- os << "}";
-
- // persist ()
- //
- os << "void " << traits << "::" << endl
- << "persist (database&, " << (auto_id ? "" : "const ") <<
- "object_type& obj)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "connection& conn (mysql::transaction::current ().connection ());"
- << "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << "image_type& im (sts.image ());"
- << "binding& imb (sts.in_image_binding ());"
- << endl;
-
- if (auto_id)
- os << "obj." << id.name () << " = 0;";
-
- os << "init (im, obj);"
- << endl
- << "if (im.version != sts.in_image_version () || imb.version == 0)"
- << "{"
- << "bind (imb.bind, im, false);"
- << "sts.in_image_version (im.version);"
- << "imb.version++;"
- << "}"
- << "insert_statement& st (sts.persist_statement ());"
- << "if (!st.execute ())" << endl
- << "throw object_already_persistent ();"
- << endl;
-
- if (auto_id)
- os << "obj." << id.name () << " = static_cast<id_type> (st.id ());"
- << endl;
-
- if (straight_containers)
- {
- // Initialize id_image.
- //
- os << "id_image_type& i (sts.id_image ());"
- << "init (i, obj." << id.name () << ");"
- << endl;
-
- container_calls t (*this, container_calls::persist_call);
- t.traverse (c);
- }
-
- os << "}";
-
- // update ()
- //
- os << "void " << traits << "::" << endl
- << "update (database&, const object_type& obj)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "connection& conn (mysql::transaction::current ().connection ());"
- << "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << endl;
-
- // Initialize id image.
- //
- os << "id_image_type& i (sts.id_image ());"
- << "init (i, obj." << id.name () << ");"
- << endl;
-
- os << "binding& idb (sts.id_image_binding ());"
- << "if (i.version != sts.id_image_version () || idb.version == 0)"
- << "{"
- << "bind (idb.bind, i);"
- << "sts.id_image_version (i.version);"
- << "idb.version++;"
- << "}";
-
- // Initialize data image.
- //
- os << "image_type& im (sts.image ());"
- << "binding& imb (sts.in_image_binding ());"
- << "init (im, obj);"
- << endl
- << "if (im.version != sts.in_image_version () || imb.version == 0)"
- << "{"
- << "bind (imb.bind, im, false);"
- << "sts.in_image_version (im.version);"
- << "imb.version++;"
- << "}"
- << "sts.update_statement ().execute ();";
-
- if (straight_containers)
- {
- os << endl;
- container_calls t (*this, container_calls::update_call);
- t.traverse (c);
- }
-
- os << "}";
-
- // erase ()
- //
- os << "void " << traits << "::" << endl
- << "erase (database&, const id_type& id)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "connection& conn (mysql::transaction::current ().connection ());"
- << "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << endl;
-
- // Initialize id image.
- //
- os << "id_image_type& i (sts.id_image ());"
- << "init (i, id);"
- << endl;
-
- os << "binding& idb (sts.id_image_binding ());"
- << "if (i.version != sts.id_image_version () || idb.version == 0)"
- << "{"
- << "bind (idb.bind, i);"
- << "sts.id_image_version (i.version);"
- << "idb.version++;"
- << "}"
- << "if (sts.erase_statement ().execute () != 1)" << endl
- << "throw object_not_persistent ();";
-
- if (straight_containers)
- {
- os << endl;
- container_calls t (*this, container_calls::erase_call);
- t.traverse (c);
- }
-
- os << "}";
-
- // find ()
- //
- if (def_ctor)
- {
- os << traits << "::pointer_type" << endl
- << traits << "::" << endl
- << "find (database& db, const id_type& id)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "connection& conn (mysql::transaction::current ().connection ());"
- << "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << "object_statements< object_type >::auto_lock l (sts);"
- << endl
- << "if (l.locked ())"
- << "{"
- << "if (!find_ (sts, id))" << endl
- << "return pointer_type ();"
- << "}"
- << "pointer_type p (" << endl
- << "access::object_factory< object_type, pointer_type >::create ());"
- << "pointer_traits< pointer_type >::guard pg (p);"
- << "pointer_cache_traits< pointer_type >::insert_guard ig (" << endl
- << "pointer_cache_traits< pointer_type >::insert (db, id, p));"
- << "object_type& obj (pointer_traits< pointer_type >::get_ref (p));"
- << endl
- << "if (l.locked ())"
- << "{"
- << "init (obj, sts.image (), db);"
- << "load_ (sts, obj);"
- << "sts.load_delayed ();"
- << "l.unlock ();"
- << "}"
- << "else" << endl
- << "sts.delay_load (id, obj, ig.position ());"
- << endl;
-
- os << "ig.release ();"
- << "pg.release ();"
- << "return p;"
- << "}";
- }
-
- os << "bool " << traits << "::" << endl
- << "find (database& db, const id_type& id, object_type& obj)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "connection& conn (mysql::transaction::current ().connection ());"
- << "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << "object_statements< object_type >::auto_lock l (sts);"
- << endl
- << "if (l.locked ())"
- << "{"
- << "if (!find_ (sts, id))" << endl
- << "return false;"
- << "}"
- << "reference_cache_traits< object_type >::insert_guard ig (" << endl
- << "reference_cache_traits< object_type >::insert (db, id, obj));"
- << endl
- << "if (l.locked ())"
- << "{"
- << "init (obj, sts.image (), db);"
- << "load_ (sts, obj);"
- << "sts.load_delayed ();"
- << "l.unlock ();"
- << "}"
- << "else" << endl
- << "sts.delay_load (id, obj, ig.position ());"
- << endl;
-
- os << "ig.release ();"
- << "return true;"
- << "}";
-
- //
- //
- os << "bool " << traits << "::" << endl
- << "find_ (mysql::object_statements< object_type >& sts, " <<
- "const id_type& id)"
- << "{"
- << "using namespace mysql;"
- << endl;
-
- // Initialize id image.
- //
- os << "id_image_type& i (sts.id_image ());"
- << "init (i, id);"
- << endl;
-
- os << "binding& idb (sts.id_image_binding ());"
- << "if (i.version != sts.id_image_version () || idb.version == 0)"
- << "{"
- << "bind (idb.bind, i);"
- << "sts.id_image_version (i.version);"
- << "idb.version++;"
- << "}";
-
- // Rebind data image.
- //
- os << "image_type& im (sts.image ());"
- << "binding& imb (sts.out_image_binding ());"
- << endl
- << "if (im.version != sts.out_image_version () || imb.version == 0)"
- << "{"
- << "bind (imb.bind, im, true);"
- << "sts.out_image_version (im.version);"
- << "imb.version++;"
- << "}"
- << "select_statement& st (sts.find_statement ());"
- << "st.execute ();"
- << "select_statement::result r (st.fetch ());";
-
- if (grow)
- os << endl
- << "if (r == select_statement::truncated)"
- << "{"
- << "grow (im, sts.out_image_error ());"
- << endl
- << "if (im.version != sts.out_image_version ())"
- << "{"
- << "bind (imb.bind, im, true);"
- << "sts.out_image_version (im.version);"
- << "imb.version++;"
- << "st.refetch ();"
- << "}"
- << "}";
-
- os << "st.free_result ();"
- << "return r != select_statement::no_data;"
- << "}";
-
- // load_()
- //
- if (containers)
- {
- os << "void " << traits << "::" << endl
- << "load_ (mysql::object_statements< object_type >& sts, " <<
- "object_type& obj)"
- << "{"
- << "id_image_type& i (sts.id_image ());"
- << endl;
- container_calls t (*this, container_calls::load_call);
- t.traverse (c);
- os << "}";
- }
-
- // query ()
- //
- if (options.generate_query ())
- {
- os << "template<>" << endl
- << "result< " << traits << "::object_type >" << endl
- << traits << "::" << endl
- << "query< " << traits << "::object_type > (" << endl
- << "database& db," << endl
- << "const query_type& q)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "connection& conn (mysql::transaction::current ().connection ());"
- << endl
- << "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << "details::shared_ptr<select_statement> st;"
- << endl
- << "query_ (db, q, sts, st);"
- << endl
- << "details::shared_ptr<odb::result_impl<object_type> > r (" << endl
- << "new (details::shared) mysql::result_impl<object_type> (st, sts));"
- << "return result<object_type> (r);"
- << "}";
-
- os << "template<>" << endl
- << "result< const " << traits << "::object_type >" << endl
- << traits << "::" << endl
- << "query< const " << traits << "::object_type > (" << endl
- << "database& db," << endl
- << "const query_type& q)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "connection& conn (mysql::transaction::current ().connection ());"
- << endl
- << "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << "details::shared_ptr<select_statement> st;"
- << endl
- << "query_ (db, q, sts, st);"
- << endl
- << "details::shared_ptr<odb::result_impl<const object_type> > r (" << endl
- << "new (details::shared) mysql::result_impl<const object_type> (st, sts));"
- << "return result<const object_type> (r);"
- << "}";
-
- os << "void " << traits << "::" << endl
- << "query_ (database&," << endl
- << "const query_type& q," << endl
- << "mysql::object_statements< object_type >& sts,"
- << "details::shared_ptr<mysql::select_statement>& st)"
- << "{"
- << "using namespace mysql;"
- << endl
- << "image_type& im (sts.image ());"
- << "binding& imb (sts.out_image_binding ());"
- << endl
- << "if (im.version != sts.out_image_version () || imb.version == 0)"
- << "{"
- << "bind (imb.bind, im, true);"
- << "sts.out_image_version (im.version);"
- << "imb.version++;"
- << "}"
- << "st.reset (new (details::shared) select_statement (" << endl
- << "sts.connection ()," << endl
- << "query_clause + q.clause ()," << endl
- << "q.parameters ()," << endl
- << "imb));"
- << "st->execute ();"
- << "}";
- }
-
- // create_schema ()
- //
- if (embedded_schema)
- {
- os << "void " << traits << "::" << endl
- << "create_schema (database& db)"
- << "{";
-
- schema_drop_.traverse (c);
- schema_create_.traverse (c);
-
- os << "}";
-
- os << "static const schema_catalog_entry" << endl
- << "schema_catalog_entry_" << flat_name (type) << "_ (" << endl
- << strlit (options.default_schema ()) << "," << endl
- << "&" << traits << "::create_schema);"
- << endl;
- }
- }
-
- virtual void
- traverse_value (type& c)
- {
- string const& type (c.fq_name ());
- string traits ("access::composite_value_traits< " + type + " >");
-
- os << "// " << c.name () << endl
- << "//" << endl
- << endl;
-
- // grow ()
- //
- os << "bool " << traits << "::" << endl
- << "grow (image_type& i, my_bool* e)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (e);"
- << endl
- << "bool grew (false);"
- << endl;
-
- index_ = 0;
- inherits (c, grow_base_inherits_);
- names (c, grow_member_names_);
-
- os << "return grew;"
- << "}";
-
- // bind (image_type)
- //
- os << "void " << traits << "::" << endl
- << "bind (MYSQL_BIND* b, image_type& i)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (b);"
- << "ODB_POTENTIALLY_UNUSED (i);"
- << endl
- << "std::size_t n (0);"
- << "ODB_POTENTIALLY_UNUSED (n);"
- << endl;
-
- inherits (c, bind_base_inherits_);
- names (c, bind_member_names_);
-
- os << "}";
-
- // init (image, object)
- //
- os << "bool " << traits << "::" << endl
- << "init (image_type& i, const value_type& o)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (o);"
- << endl
- << "bool grew (false);"
- << endl;
-
- inherits (c, init_image_base_inherits_);
- names (c, init_image_member_names_);
-
- os << "return grew;"
- << "}";
-
- // init (object, image)
- //
- os << "void " << traits << "::" << endl
- << "init (value_type& o, const image_type& i, database& db)"
- << "{"
- << "ODB_POTENTIALLY_UNUSED (o);"
- << "ODB_POTENTIALLY_UNUSED (i);"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl;
-
- inherits (c, init_value_base_inherits_);
- names (c, init_value_member_names_);
-
- os << "}";
- }
-
- private:
- bool id_;
- size_t index_;
-
- grow_base grow_base_;
- traversal::inherits grow_base_inherits_;
- grow_member grow_member_;
- traversal::names grow_member_names_;
-
- bind_base bind_base_;
- traversal::inherits bind_base_inherits_;
- bind_member bind_member_;
- traversal::names bind_member_names_;
- bind_member bind_id_member_;
-
- init_image_base init_image_base_;
- traversal::inherits init_image_base_inherits_;
- init_image_member init_image_member_;
- traversal::names init_image_member_names_;
-
- init_image_member init_id_image_member_;
-
- init_value_base init_value_base_;
- traversal::inherits init_value_base_inherits_;
- init_value_member init_value_member_;
- traversal::names init_value_member_names_;
- init_value_member init_id_value_member_;
-
- schema_emitter schema_emitter_;
- class_drop schema_drop_;
- class_create schema_create_;
- };
- }
-
- void
- generate_source (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;
-
- //
- //
- ctx.os << "#include <odb/cache-traits.hxx>" << endl;
-
- if (ctx.embedded_schema)
- ctx.os << "#include <odb/schema-catalog-impl.hxx>" << endl;
-
- ctx.os << endl;
-
- //
- //
- ctx.os << "#include <odb/mysql/mysql.hxx>" << endl
- << "#include <odb/mysql/traits.hxx>" << endl
- << "#include <odb/mysql/database.hxx>" << endl
- << "#include <odb/mysql/transaction.hxx>" << endl
- << "#include <odb/mysql/connection.hxx>" << endl
- << "#include <odb/mysql/statement.hxx>" << endl
- << "#include <odb/mysql/statement-cache.hxx>" << endl
- << "#include <odb/mysql/object-statements.hxx>" << endl
- << "#include <odb/mysql/container-statements.hxx>" << endl
- << "#include <odb/mysql/exceptions.hxx>" << endl;
-
- if (ctx.options.generate_query ())
- ctx.os << "#include <odb/mysql/result.hxx>" << endl;
-
- ctx.os << endl;
-
- // Details includes.
- //
- ctx.os << "#include <odb/details/unused.hxx>" << endl;
-
- if (ctx.options.generate_query ())
- ctx.os << "#include <odb/details/shared-ptr.hxx>" << endl;
-
- ctx.os << endl;
-
- ctx.os << "namespace odb"
- << "{";
-
- unit.dispatch (ctx.unit);
-
- ctx.os << "}";
- }
-}
diff --git a/odb/mysql/source.hxx b/odb/mysql/source.hxx
deleted file mode 100644
index 43a051b..0000000
--- a/odb/mysql/source.hxx
+++ /dev/null
@@ -1,17 +0,0 @@
-// file : odb/mysql/source.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_MYSQL_SOURCE_HXX
-#define ODB_MYSQL_SOURCE_HXX
-
-#include <odb/mysql/context.hxx>
-
-namespace mysql
-{
- void
- generate_source (context&);
-}
-
-#endif // ODB_MYSQL_SOURCE_HXX
diff --git a/odb/mysql/sql-schema.cxx b/odb/mysql/sql-schema.cxx
deleted file mode 100644
index 7c71b24..0000000
--- a/odb/mysql/sql-schema.cxx
+++ /dev/null
@@ -1,98 +0,0 @@
-// file : odb/mysql/sql-schema.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 <odb/mysql/common.hxx>
-#include <odb/mysql/schema.hxx>
-#include <odb/mysql/sql-schema.hxx>
-
-using namespace std;
-
-namespace mysql
-{
- namespace
- {
- struct schema_emitter: emitter, context
- {
- schema_emitter (context& c): context (c) {}
-
- virtual void
- pre ()
- {
- first_ = true;
- }
-
- virtual void
- line (const std::string& l)
- {
- if (first_)
- first_ = false;
- else
- os << endl;
-
- os << l;
- }
-
- virtual void
- post ()
- {
- os << ';' << endl
- << endl;
- }
-
- private:
- bool first_;
- };
-
- static char const file_header[] =
- "/* This file was generated by ODB, object-relational mapping (ORM)\n"
- " * compiler for C++.\n"
- " */\n\n";
- }
-
- void
- generate_schema (context& ctx)
- {
- ctx.os << file_header;
- schema_emitter emitter (ctx);
-
- // Drop.
- //
- {
- traversal::unit unit;
- traversal::defines unit_defines;
- traversal::namespace_ ns;
- class_drop c (ctx, emitter);
-
- unit >> unit_defines >> ns;
- unit_defines >> c;
-
- traversal::defines ns_defines;
-
- ns >> ns_defines >> ns;
- ns_defines >> c;
- unit.dispatch (ctx.unit);
- }
-
- ctx.os << endl;
-
- // Create.
- //
- {
- traversal::unit unit;
- traversal::defines unit_defines;
- traversal::namespace_ ns;
- class_create c (ctx, emitter);
-
- 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/mysql/sql-schema.hxx b/odb/mysql/sql-schema.hxx
deleted file mode 100644
index fdbdf28..0000000
--- a/odb/mysql/sql-schema.hxx
+++ /dev/null
@@ -1,17 +0,0 @@
-// file : odb/mysql/sql-schema.hxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_MYSQL_SQL_SCHEMA_HXX
-#define ODB_MYSQL_SQL_SCHEMA_HXX
-
-#include <odb/mysql/context.hxx>
-
-namespace mysql
-{
- void
- generate_schema (context&);
-}
-
-#endif // ODB_MYSQL_SQL_SCHEMA_HXX