aboutsummaryrefslogtreecommitdiff
path: root/odb/mysql
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-11-06 18:05:19 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-11-06 18:05:19 +0200
commitce696c26d2c9dd5a5813fd865082ab19ac49bcfa (patch)
treec44331b2a6e6fa1d9d518ddff63e711ce5d308c4 /odb/mysql
parent727a83dc82fa094aa91630d165d230a9a2dabe60 (diff)
Add support for container persistence
Diffstat (limited to 'odb/mysql')
-rw-r--r--odb/mysql/common.cxx158
-rw-r--r--odb/mysql/common.hxx138
-rw-r--r--odb/mysql/context.cxx146
-rw-r--r--odb/mysql/context.hxx13
-rw-r--r--odb/mysql/header.cxx573
-rw-r--r--odb/mysql/inline.cxx5
-rw-r--r--odb/mysql/schema.cxx165
-rw-r--r--odb/mysql/source.cxx1558
8 files changed, 2275 insertions, 481 deletions
diff --git a/odb/mysql/common.cxx b/odb/mysql/common.cxx
index 372d08e..17cae9e 100644
--- a/odb/mysql/common.cxx
+++ b/odb/mysql/common.cxx
@@ -11,29 +11,47 @@ using namespace std;
namespace mysql
{
+ //
+ // member_base
+ //
+
void member_base::
- traverse (type& m)
+ traverse (semantics::data_member& m)
{
- if (m.count ("transient") || (id_ && !m.count ("id")))
+ if (m.count ("transient"))
return;
- if (id_)
- var = "id_";
+ string var;
+
+ if (!var_override_.empty ())
+ var = var_override_;
else
{
string const& name (m.name ());
var = name + (name[name.size () - 1] == '_' ? "" : "_");
}
- pre (m);
+ semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
+
+ member_info mi (m, t, var, fq_type_override_);
- if (comp_value (m.type ()))
- traverse_composite (m);
+ if (comp_value (t))
+ {
+ pre (mi);
+ traverse_composite (mi);
+ }
+ else if (container (t))
+ {
+ pre (mi);
+ traverse_container (mi);
+ }
else
{
- sql_type const& t (db_type (m));
+ sql_type const& st (db_type (m, key_prefix_));
+ mi.st = &st;
+ pre (mi);
- switch (t.type)
+ switch (st.type)
{
// Integral types.
//
@@ -43,7 +61,7 @@ namespace mysql
case sql_type::INT:
case sql_type::BIGINT:
{
- traverse_integer (m, t);
+ traverse_integer (mi);
break;
}
@@ -52,12 +70,12 @@ namespace mysql
case sql_type::FLOAT:
case sql_type::DOUBLE:
{
- traverse_float (m, t);
+ traverse_float (mi);
break;
}
case sql_type::DECIMAL:
{
- traverse_decimal (m, t);
+ traverse_decimal (mi);
break;
}
@@ -69,7 +87,7 @@ namespace mysql
case sql_type::TIMESTAMP:
case sql_type::YEAR:
{
- traverse_date_time (m, t);
+ traverse_date_time (mi);
break;
}
@@ -88,7 +106,7 @@ namespace mysql
// To support this we will need the character encoding
// in sql_type.
//
- traverse_long_string (m, t);
+ traverse_long_string (mi);
break;
}
case sql_type::BINARY:
@@ -97,7 +115,7 @@ namespace mysql
// BINARY's range is always 255 or less from MySQL 5.0.3.
// TINYBLOB can only store up to 255 bytes.
//
- traverse_short_string (m, t);
+ traverse_short_string (mi);
break;
}
case sql_type::VARBINARY:
@@ -105,10 +123,10 @@ namespace mysql
case sql_type::MEDIUMBLOB:
case sql_type::LONGBLOB:
{
- if (t.range && t.range_value <= 255)
- traverse_short_string (m, t);
+ if (st.range && st.range_value <= 255)
+ traverse_short_string (mi);
else
- traverse_long_string (m, t);
+ traverse_long_string (mi);
break;
}
@@ -117,17 +135,17 @@ namespace mysql
//
case sql_type::BIT:
{
- traverse_bit (m, t);
+ traverse_bit (mi);
break;
}
case sql_type::ENUM:
{
- traverse_enum (m, t);
+ traverse_enum (mi);
break;
}
case sql_type::SET:
{
- traverse_set (m, t);
+ traverse_set (mi);
break;
}
case sql_type::invalid:
@@ -138,7 +156,7 @@ namespace mysql
}
}
- post (m);
+ post (mi);
}
//
@@ -164,13 +182,22 @@ namespace mysql
}
member_image_type::
- member_image_type (context& c, bool id)
- : member_base (c, id)
+ 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 (type& m)
+ image_type (semantics::data_member& m)
{
type_.clear ();
member_base::traverse (m);
@@ -178,58 +205,57 @@ namespace mysql
}
void member_image_type::
- traverse_composite (type& m)
+ traverse_composite (member_info& mi)
{
- type_ = "composite_value_traits< " + m.type ().fq_name () +
- " >::image_type";
+ type_ = "composite_value_traits< " + mi.fq_type () + " >::image_type";
}
void member_image_type::
- traverse_integer (type&, sql_type const& t)
+ traverse_integer (member_info& mi)
{
- if (t.unsign)
+ if (mi.st->unsign)
type_ = "unsigned ";
- else if (t.type == sql_type::TINYINT)
+ else if (mi.st->type == sql_type::TINYINT)
type_ = "signed ";
- type_ += integer_types[t.type - sql_type::TINYINT];
+ type_ += integer_types[mi.st->type - sql_type::TINYINT];
}
void member_image_type::
- traverse_float (type&, sql_type const& t)
+ traverse_float (member_info& mi)
{
- type_ = float_types[t.type - sql_type::FLOAT];
+ type_ = float_types[mi.st->type - sql_type::FLOAT];
}
void member_image_type::
- traverse_decimal (type&, sql_type const&)
+ traverse_decimal (member_info&)
{
type_ = "details::buffer";
}
void member_image_type::
- traverse_date_time (type&, sql_type const& t)
+ traverse_date_time (member_info& mi)
{
- if (t.type == sql_type::YEAR)
+ if (mi.st->type == sql_type::YEAR)
type_ = "short";
else
type_ = "MYSQL_TIME";
}
void member_image_type::
- traverse_string (type&, sql_type const&)
+ traverse_string (member_info&)
{
type_ = "details::buffer";
}
void member_image_type::
- traverse_bit (type&, sql_type const&)
+ traverse_bit (member_info&)
{
type_ = "unsigned char*";
}
void member_image_type::
- traverse_enum (type&, sql_type const&)
+ traverse_enum (member_info&)
{
// Represented as string.
//
@@ -237,7 +263,7 @@ namespace mysql
}
void member_image_type::
- traverse_set (type&, sql_type const&)
+ traverse_set (member_info&)
{
// Represented as string.
//
@@ -298,7 +324,16 @@ namespace mysql
member_database_type::
member_database_type (context& c)
- : member_base (c, false)
+ : 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)
{
}
@@ -311,56 +346,59 @@ namespace mysql
}
void member_database_type::
- traverse_composite (type&)
+ traverse_composite (member_info&)
{
assert (false);
}
void member_database_type::
- traverse_integer (type&, sql_type const& t)
+ traverse_integer (member_info& mi)
{
- size_t i ((t.type - sql_type::TINYINT) * 2 + (t.unsign ? 1 : 0));
+ 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 (type&, sql_type const& t)
+ traverse_float (member_info& mi)
{
- type_ = string ("mysql::") + float_database_id[t.type - sql_type::FLOAT];
+ type_ = string ("mysql::") +
+ float_database_id[mi.st->type - sql_type::FLOAT];
}
void member_database_type::
- traverse_decimal (type&, sql_type const&)
+ traverse_decimal (member_info&)
{
type_ = "mysql::id_decimal";
}
void member_database_type::
- traverse_date_time (type&, sql_type const& t)
+ traverse_date_time (member_info& mi)
{
- type_ = string ("mysql::") + date_time_database_id[t.type - sql_type::DATE];
+ type_ = string ("mysql::") +
+ date_time_database_id[mi.st->type - sql_type::DATE];
}
void member_database_type::
- traverse_string (type&, sql_type const& t)
+ traverse_string (member_info& mi)
{
- type_ = string ("mysql::") + char_bin_database_id[t.type - sql_type::CHAR];
+ type_ = string ("mysql::") +
+ char_bin_database_id[mi.st->type - sql_type::CHAR];
}
void member_database_type::
- traverse_bit (type&, sql_type const&)
+ traverse_bit (member_info&)
{
type_ = "mysql::id_bit";
}
void member_database_type::
- traverse_enum (type&, sql_type const&)
+ traverse_enum (member_info&)
{
type_ = "mysql::id_enum";
}
void member_database_type::
- traverse_set (type&, sql_type const&)
+ traverse_set (member_info&)
{
type_ = "mysql::id_set";
}
@@ -374,7 +412,7 @@ namespace mysql
: object_columns_base (c),
context (c),
decl_ (true),
- member_image_type_ (c, false),
+ member_image_type_ (c),
member_database_type_ (c)
{
}
@@ -384,7 +422,7 @@ namespace mysql
: object_columns_base (c),
context (c),
decl_ (false),
- member_image_type_ (c, false),
+ member_image_type_ (c),
member_database_type_ (c)
{
scope_ = "access::object_traits< " + cl.fq_name () + " >::query_type";
@@ -392,7 +430,7 @@ namespace mysql
}
void query_columns::
- composite (semantics::data_member& m)
+ composite (semantics::data_member& m, semantics::type& t)
{
string name (public_name (m));
@@ -403,7 +441,7 @@ namespace mysql
<< "struct " << name
<< "{";
- object_columns_base::composite (m);
+ object_columns_base::composite (m, t);
os << "};";
}
@@ -412,7 +450,7 @@ namespace mysql
string old_scope (scope_);
scope_ += "::" + name;
- object_columns_base::composite (m);
+ object_columns_base::composite (m, t);
scope_ = old_scope;
}
diff --git a/odb/mysql/common.hxx b/odb/mysql/common.hxx
index 83fa998..31c6962 100644
--- a/odb/mysql/common.hxx
+++ b/odb/mysql/common.hxx
@@ -13,119 +13,170 @@ namespace mysql
{
struct member_base: traversal::data_member, context
{
- member_base (context& c, bool id)
- : context (c), id_ (id)
+ 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 (type& m);
+ 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
+ {
+ return fq_type_.empty () ? t.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)
+ {
+ }
+ };
+
+ virtual void
+ pre (member_info&)
+ {
+ }
virtual void
- pre (type&)
+ post (member_info&)
{
}
virtual void
- post (type&)
+ traverse_composite (member_info&)
{
}
virtual void
- traverse_composite (type&)
+ traverse_container (member_info&)
{
}
virtual void
- traverse_integer (type&, sql_type const&)
+ traverse_integer (member_info&)
{
}
virtual void
- traverse_float (type&, sql_type const&)
+ traverse_float (member_info&)
{
}
virtual void
- traverse_decimal (type&, sql_type const&)
+ traverse_decimal (member_info&)
{
}
virtual void
- traverse_date_time (type&, sql_type const&)
+ traverse_date_time (member_info&)
{
}
virtual void
- traverse_string (type&, sql_type const&)
+ traverse_string (member_info&)
{
}
virtual void
- traverse_short_string (type& t, sql_type const& st)
+ traverse_short_string (member_info& mi)
{
- traverse_string (t, st);
+ traverse_string (mi);
}
virtual void
- traverse_long_string (type& t, sql_type const& st)
+ traverse_long_string (member_info& mi)
{
- traverse_string (t, st);
+ traverse_string (mi);
}
virtual void
- traverse_bit (type&, sql_type const&)
+ traverse_bit (member_info&)
{
}
virtual void
- traverse_enum (type&, sql_type const&)
+ traverse_enum (member_info&)
{
}
virtual void
- traverse_set (type&, sql_type const&)
+ traverse_set (member_info&)
{
}
protected:
- bool id_;
- string var;
+ string var_override_;
+ semantics::type* type_override_;
+ string fq_type_override_;
+ string key_prefix_;
};
struct member_image_type: member_base
{
- member_image_type (context&, bool id);
+ member_image_type (context&);
+
+ member_image_type (context& c,
+ semantics::type& type,
+ string const& fq_type,
+ string const& key_prefix);
string
- image_type (type&);
+ image_type (semantics::data_member&);
virtual void
- traverse_composite (type&);
+ traverse_composite (member_info&);
virtual void
- traverse_integer (type&, sql_type const&);
+ traverse_integer (member_info&);
virtual void
- traverse_float (type&, sql_type const&);
+ traverse_float (member_info&);
virtual void
- traverse_decimal (type&, sql_type const&);
+ traverse_decimal (member_info&);
virtual void
- traverse_date_time (type&, sql_type const&);
+ traverse_date_time (member_info&);
virtual void
- traverse_string (type&, sql_type const&);
+ traverse_string (member_info&);
virtual void
- traverse_bit (type&, sql_type const&);
+ traverse_bit (member_info&);
virtual void
- traverse_enum (type&, sql_type const&);
+ traverse_enum (member_info&);
virtual void
- traverse_set (type&, sql_type const&);
+ traverse_set (member_info&);
private:
string type_;
@@ -135,35 +186,40 @@ namespace mysql
{
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 (type&);
+ traverse_composite (member_info&);
virtual void
- traverse_integer (type&, sql_type const&);
+ traverse_integer (member_info&);
virtual void
- traverse_float (type&, sql_type const&);
+ traverse_float (member_info&);
virtual void
- traverse_decimal (type&, sql_type const&);
+ traverse_decimal (member_info&);
virtual void
- traverse_date_time (type&, sql_type const&);
+ traverse_date_time (member_info&);
virtual void
- traverse_string (type&, sql_type const&);
+ traverse_string (member_info&);
virtual void
- traverse_bit (type&, sql_type const&);
+ traverse_bit (member_info&);
virtual void
- traverse_enum (type&, sql_type const&);
+ traverse_enum (member_info&);
virtual void
- traverse_set (type&, sql_type const&);
+ traverse_set (member_info&);
private:
string type_;
@@ -175,7 +231,7 @@ namespace mysql
query_columns (context&, semantics::class_&);
virtual void
- composite (semantics::data_member&);
+ composite (semantics::data_member&, semantics::type&);
virtual void
column (semantics::data_member&, string const&, bool);
diff --git a/odb/mysql/context.cxx b/odb/mysql/context.cxx
index e896f68..4803da2 100644
--- a/odb/mysql/context.cxx
+++ b/odb/mysql/context.cxx
@@ -81,18 +81,16 @@ namespace mysql
{
struct has_grow: traversal::class_
{
- has_grow (context& c)
- : member_ (c, *this)
+ has_grow ()
{
- *this >> member_names_ >> member_;
*this >> inherits_ >> *this;
}
bool
- dispatch (semantics::type& t)
+ dispatch (type& c)
{
r_ = false;
- traversal::class_::dispatch (t);
+ traverse (c);
return r_;
}
@@ -115,57 +113,74 @@ namespace mysql
}
private:
- struct member: member_base
- {
- member (context& c, has_grow& hg) : member_base (c, false), hg_ (hg) {}
+ friend class has_grow_member;
- virtual void
- traverse_composite (type& m)
- {
- if (!hg_.r_)
- hg_.r_ = hg_.dispatch (m.type ());
- }
+ bool r_;
+ traversal::inherits inherits_;
+ };
- virtual void
- traverse_decimal (type&, sql_type const&)
- {
- hg_.r_ = true;
- }
+ struct has_grow_member: member_base
+ {
+ has_grow_member (context& c, has_grow& hg)
+ : member_base (c), hg_ (hg)
+ {
+ }
- virtual void
- traverse_long_string (type&, sql_type const&)
- {
- hg_.r_ = true;
- }
+ has_grow_member (context& c,
+ has_grow& hg,
+ semantics::type& type,
+ string const& key_prefix)
+ : member_base (c, "", type, "", key_prefix), hg_ (hg)
+ {
+ }
- virtual void
- traverse_short_string (type&, sql_type const&)
- {
- hg_.r_ = true; // @@ Short string optimization disabled.
- }
+ bool
+ dispatch (semantics::data_member& m)
+ {
+ hg_.r_ = false;
+ member_base::traverse (m);
+ return hg_.r_;
+ }
- virtual void
- traverse_enum (type&, sql_type const&)
- {
- hg_.r_ = true;
- }
+ virtual void
+ traverse_composite (member_info& mi)
+ {
+ if (!hg_.r_)
+ hg_.r_ = hg_.dispatch (dynamic_cast<semantics::class_&> (mi.t));
+ }
- virtual void
- traverse_set (type&, sql_type const&)
- {
- hg_.r_ = true;
- }
+ virtual void
+ traverse_decimal (member_info&)
+ {
+ hg_.r_ = true;
+ }
- private:
- has_grow& hg_;
- };
+ virtual void
+ traverse_long_string (member_info&)
+ {
+ hg_.r_ = true;
+ }
- bool r_;
+ virtual void
+ traverse_short_string (member_info&)
+ {
+ hg_.r_ = true; // @@ Short string optimization disabled.
+ }
- member member_;
- traversal::names member_names_;
+ virtual void
+ traverse_enum (member_info&)
+ {
+ hg_.r_ = true;
+ }
- traversal::inherits inherits_;
+ virtual void
+ traverse_set (member_info&)
+ {
+ hg_.r_ = true;
+ }
+
+ private:
+ has_grow& hg_;
};
}
@@ -175,20 +190,37 @@ namespace mysql
if (c.count ("mysql::grow"))
return c.get<bool> ("mysql::grow");
- has_grow t (*this);
- return t.dispatch (c);
+ has_grow ct;
+ has_grow_member mt (*this, ct);
+ traversal::names names;
+ ct >> names >> mt;
+
+ return ct.dispatch (c);
+ }
+
+ bool context::
+ grow (semantics::data_member& m, semantics::type& t, string const& kp)
+ {
+ has_grow ct;
+ has_grow_member mt (*this, ct, t, kp);
+ traversal::names names;
+ ct >> names >> mt;
+
+ return mt.dispatch (m);
}
//
// SQL type parsing.
//
- string context::
- column_type_impl (semantics::data_member& m) const
+ string context::data::
+ column_type_impl (semantics::type& t,
+ string const& type,
+ semantics::context* ctx) const
{
- string r (::context::column_type_impl (m));
+ string r (::context::data::column_type_impl (t, type, ctx));
- if (m.count ("auto"))
+ if (!r.empty () && ctx != 0 && ctx->count ("auto"))
r += " AUTO_INCREMENT";
return r;
@@ -198,12 +230,14 @@ namespace mysql
parse_sql_type (semantics::data_member& m, std::string const& sql);
sql_type const& context::
- db_type (semantics::data_member& m)
+ db_type (semantics::data_member& m, string const& kp)
{
- if (!m.count ("db-type"))
- m.set ("db-type", parse_sql_type (m, column_type (m)));
+ 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> ("db-type");
+ return m.get<sql_type> (key);
}
static sql_type
diff --git a/odb/mysql/context.hxx b/odb/mysql/context.hxx
index 40facae..9a6beec 100644
--- a/odb/mysql/context.hxx
+++ b/odb/mysql/context.hxx
@@ -86,25 +86,32 @@ namespace mysql
bool
grow (semantics::class_&);
+ // The same for a member's value type.
+ //
+ bool
+ grow (semantics::data_member&, semantics::type&, string const& key_prefix);
+
//
//
public:
sql_type const&
- db_type (semantics::data_member&);
+ 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*) const;
};
private:
data* data_;
public:
- virtual string
- column_type_impl (semantics::data_member&) const;
public:
context (std::ostream&, semantics::unit&, options_type const&);
diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx
index 2544ff3..b4781f9 100644
--- a/odb/mysql/header.cxx
+++ b/odb/mysql/header.cxx
@@ -14,46 +14,59 @@ namespace mysql
{
struct image_member: member_base
{
- image_member (context& c, bool id)
- : member_base (c, id), member_image_type_ (c, id)
+ 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 void
- pre (type& m)
+ pre (member_info& mi)
{
- image_type = member_image_type_.image_type (m);
+ if (container (mi.t))
+ return;
- if (!id_)
- os << "// " << m.name () << endl
+ image_type = member_image_type_.image_type (mi.m);
+
+ if (var_override_.empty ())
+ os << "// " << mi.m.name () << endl
<< "//" << endl;
}
virtual void
- traverse_composite (type&)
+ traverse_composite (member_info& mi)
{
- os << image_type << " " << var << "value;"
+ os << image_type << " " << mi.var << "value;"
<< endl;
}
virtual void
- traverse_integer (type&, sql_type const&)
+ traverse_integer (member_info& mi)
{
- os << image_type << " " << var << "value;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_float (type&, sql_type const&)
+ traverse_float (member_info& mi)
{
- os << image_type << " " << var << "value;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_decimal (type&, sql_type const&)
+ 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.
@@ -61,83 +74,83 @@ namespace mysql
/*
@@ Disabled.
- os << "char " << var << "value[" <<
+ os << "char " << mi.var << "value[" <<
(t.range ? t.range_value : 10) + 3 << "];"
*/
- os << image_type << " " << var << "value;"
- << "unsigned long " << var << "size;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "unsigned long " << mi.var << "size;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_date_time (type&, sql_type const&)
+ traverse_date_time (member_info& mi)
{
- os << image_type << " " << var << "value;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_short_string (type&, sql_type const&)
+ traverse_short_string (member_info& mi)
{
// If range is not specified, the default buffer size is 255.
//
/*
@@ Disabled.
- os << "char " << var << "value[" <<
+ os << "char " << mi.var << "value[" <<
(t.range ? t.range_value : 255) + 1 << "];"
*/
- os << image_type << " " << var << "value;"
- << "unsigned long " << var << "size;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "unsigned long " << mi.var << "size;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_long_string (type&, sql_type const&)
+ traverse_long_string (member_info& mi)
{
- os << image_type << " " << var << "value;"
- << "unsigned long " << var << "size;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "unsigned long " << mi.var << "size;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_bit (type&, sql_type const& t)
+ traverse_bit (member_info& mi)
{
// Valid range is 1 to 64.
//
- unsigned int n (t.range / 8 + (t.range % 8 ? 1 : 0));
+ unsigned int n (mi.st->range / 8 + (mi.st->range % 8 ? 1 : 0));
- os << "unsigned char " << var << "value[" << n << "];"
- << "unsigned long " << var << "size;"
- << "my_bool " << var << "null;"
+ os << "unsigned char " << mi.var << "value[" << n << "];"
+ << "unsigned long " << mi.var << "size;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_enum (type&, sql_type const&)
+ traverse_enum (member_info& mi)
{
// Represented as string.
//
- os << image_type << " " << var << "value;"
- << "unsigned long " << var << "size;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "unsigned long " << mi.var << "size;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
virtual void
- traverse_set (type&, sql_type const&)
+ traverse_set (member_info& mi)
{
// Represented as string.
//
- os << image_type << " " << var << "value;"
- << "unsigned long " << var << "size;"
- << "my_bool " << var << "null;"
+ os << image_type << " " << mi.var << "value;"
+ << "unsigned long " << mi.var << "size;"
+ << "my_bool " << mi.var << "null;"
<< endl;
}
@@ -175,7 +188,7 @@ namespace mysql
struct image_type: traversal::class_, context
{
image_type (context& c)
- : context (c), member_ (c, false)
+ : context (c), member_ (c)
{
*this >> names_member_ >> member_;
}
@@ -203,36 +216,437 @@ namespace mysql
traversal::names names_member_;
};
- struct id_image_type: traversal::class_, context
+ // Member-specific traits types for container members.
+ //
+ struct container_traits: object_members_base, context
{
- id_image_type (context& c)
- : context (c), image_member_ (c, true)
+ container_traits (context& c)
+ : object_members_base (c, true, false), context (c)
{
- *this >> names_image_member_ >> image_member_;
}
virtual void
- traverse (type& c)
+ container (semantics::data_member& m)
{
- os << "struct id_image_type"
+ 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);
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ it = &container_it (t);
+ 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.
+ //
+ 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 = 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 += column_count (*vc);
+ else
+ cond_columns++;
+
+ break;
+ }
+ }
+
+ if (class_* vc = comp_value (vt))
+ data_columns += 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
<< "{";
- names (c);
+ // container_type
+ // index_type
+ // key_type
+ // value_type
+ //
+
+ os << "typedef " << t.fq_name (m.belongs ().hint ()) <<
+ " container_type;";
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "typedef " << container_fq_it (m) << " index_type;";
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ os << "typedef " << container_fq_kt (m) << " key_type;";
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ break;
+ }
+ }
+
+ os << "typedef " << container_fq_vt (m) << " value_type;"
+ << endl;
+
+ os << "typedef odb::access::container_traits< container_type > " <<
+ "container_traits;";
+
+ // 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;
+
+ // cond_image_type (object id is taken from the object image)
+ //
+ os << "struct cond_image_type"
+ << "{";
+
+ switch (ck)
+ {
+ case ck_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 << "};";
- }
- private:
- image_member image_member_;
- traversal::names names_image_member_;
+ // data_image_type (object id is taken from the object image)
+ //
+ os << "struct data_image_type"
+ << "{";
+
+ switch (ck)
+ {
+ case ck_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 << "};";
+
+ // 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 bool" << endl
+ << "grow (data_image_type&, my_bool*);"
+ << endl;
+
+ // init (data_image)
+ //
+ os << "static bool" << endl;
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "init (data_image_type&, index_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:
+ {
+ os << "init (index_type&, value_type&, const data_image_type&);";
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ os << "init (key_type&, value_type&, const data_image_type&);";
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ os << "init (value_type&, const data_image_type&);";
+ break;
+ }
+ }
+
+ os << 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
+ //
+ os << "static void" << endl
+ << "persist (const container_type&," << endl
+ << "id_image_type&," << endl
+ << "bool," << endl
+ << "statements_type&);"
+ << endl;
+
+ // load
+ //
+ os << "static void" << endl
+ << "load (container_type&," << endl
+ << "id_image_type&," << endl
+ << "bool," << endl
+ << "statements_type&);"
+ << endl;
+
+ // update
+ //
+ os << "static void" << endl
+ << "update (const container_type&," << endl
+ << "id_image_type&," << endl
+ << "bool," << endl
+ << "statements_type&);"
+ << endl;
+
+ // erase
+ //
+ os << "static void" << endl
+ << "erase (id_image_type&, bool, statements_type&);"
+ << endl;
+
+ os << "};";
+ }
};
+ //
+ //
struct class_: traversal::class_, context
{
class_ (context& c)
- : context (c),
- image_type_ (c),
- id_image_type_ (c)
+ : context (c), image_type_ (c), id_image_member_ (c, "id_")
{
}
@@ -254,8 +668,7 @@ namespace mysql
string const& type (c.fq_name ());
bool def_ctor (TYPE_HAS_DEFAULT_CONSTRUCTOR (c.tree_node ()));
- id_member_.traverse (c);
- semantics::data_member& id (*id_member_.member ());
+ semantics::data_member& id (id_member (c));
bool auto_id (id.count ("auto"));
os << "// " << c.name () << endl
@@ -284,7 +697,12 @@ namespace mysql
// id_image_type
//
- id_image_type_.traverse (c);
+ os << "struct id_image_type"
+ << "{";
+
+ id_image_member_.traverse (id);
+
+ os << "};";
// query_type & query_base_type
//
@@ -317,7 +735,7 @@ namespace mysql
column_count (c) << "UL;"
<< endl;
- // Queries.
+ // Statements.
//
os << "static const char* const persist_statement;"
<< "static const char* const find_statement;"
@@ -329,6 +747,28 @@ namespace mysql
os << endl;
+ //
+ // Containers.
+ //
+
+ // Traits types.
+ //
+ {
+ // @@ Make it class members?
+ //
+ container_traits t (*this);
+ t.traverse (c);
+ }
+
+ // Statement cache (forward declaration).
+ //
+ os << "struct container_statement_cache_type;"
+ << endl;
+
+ //
+ // Functions.
+ //
+
// id ()
//
os << "static id_type" << endl
@@ -406,7 +846,9 @@ namespace mysql
//
os << "private:" << endl
<< "static bool" << endl
- << "find (mysql::object_statements<object_type>&, const id_type&);";
+ << "find (mysql::object_statements<object_type>&," << endl
+ << "const id_type&," << endl
+ << "bool&);";
os << "};";
}
@@ -461,9 +903,8 @@ namespace mysql
}
private:
- id_member id_member_;
image_type image_type_;
- id_image_type id_image_type_;
+ image_member id_image_member_;
};
}
diff --git a/odb/mysql/inline.cxx b/odb/mysql/inline.cxx
index 47766e2..948caac 100644
--- a/odb/mysql/inline.cxx
+++ b/odb/mysql/inline.cxx
@@ -34,10 +34,7 @@ namespace mysql
{
string const& type (c.fq_name ());
string traits ("access::object_traits< " + type + " >");
-
- id_member t;
- t.traverse (c);
- semantics::data_member& id (*t.member ());
+ semantics::data_member& id (id_member (c));
os << "// " << c.name () << endl
<< "//" << endl
diff --git a/odb/mysql/schema.cxx b/odb/mysql/schema.cxx
index 3ef412b..1dfeb1f 100644
--- a/odb/mysql/schema.cxx
+++ b/odb/mysql/schema.cxx
@@ -8,10 +8,14 @@
#include <odb/mysql/common.hxx>
#include <odb/mysql/schema.hxx>
+using namespace std;
+
namespace mysql
{
namespace
{
+ typedef set<string> tables;
+
struct object_columns: object_columns_base, context
{
object_columns (context& c)
@@ -32,6 +36,118 @@ namespace mysql
}
};
+ struct member_create: object_members_base, context
+ {
+ member_create (context& c, semantics::class_& object, tables& t)
+ : object_members_base (c, false, true),
+ context (c),
+ object_ (object),
+ id_member_ (id_member (object)),
+ tables_ (t)
+ {
+ }
+
+ virtual void
+ container (semantics::data_member& m)
+ {
+ using semantics::type;
+ using semantics::data_member;
+
+ 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;
+
+ 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_);
+
+ // index (simple value)
+ //
+ string index_name;
+ if (ck == ck_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 (comp_value (kt))
+ {
+ object_columns oc (*this);
+ oc.traverse_composite (m, kt, "key", "key");
+ }
+ else
+ {
+ string const& name (column_name (m, "key", "key"));
+ os << " `" << name << "` " << column_type (m, "key");
+ }
+ }
+
+ // value (simple or composite value)
+ //
+ {
+ os << "," << endl;
+
+ if (comp_value (vt))
+ {
+ object_columns oc (*this);
+ oc.traverse_composite (m, vt, "value", "value");
+ }
+ else
+ {
+ string const& name (column_name (m, "value", "value"));
+ os << " `" << name << "` " << column_type (m, "value");
+ }
+ }
+
+ // object_id index
+ //
+ os << "," << endl
+ << " INDEX (`" << id_name << "`)";
+
+ // index index
+ //
+ if (ck == ck_ordered)
+ os << "," << endl
+ << " INDEX (`" << index_name << "`)";
+
+ os << ")";
+
+ string const& engine (options.mysql_engine ());
+
+ if (engine != "default")
+ os << endl
+ << " ENGINE=" << engine;
+
+ os << ";" << endl
+ << endl;
+
+ tables_.insert (name);
+ }
+
+ private:
+ semantics::class_& object_;
+ semantics::data_member& id_member_;
+ tables& tables_;
+ };
+
struct class_create: traversal::class_, context
{
class_create (context& c)
@@ -59,8 +175,8 @@ namespace mysql
os << "CREATE TABLE `" << name << "` (" << endl;
{
- object_columns t (*this);
- t.traverse (c);
+ object_columns oc (*this);
+ oc.traverse (c);
}
os << ")";
@@ -74,11 +190,45 @@ namespace mysql
os << ";" << endl
<< endl;
+ // Create tables for members.
+ //
+ {
+ member_create mc (*this, c, tables_);
+ mc.traverse (c);
+ }
+
tables_.insert (name);
}
private:
- std::set<string> tables_;
+ tables tables_;
+ };
+
+ struct member_drop: object_members_base, context
+ {
+ member_drop (context& c, semantics::class_& object, tables& t)
+ : object_members_base (c, false, true),
+ context (c),
+ object_ (object),
+ tables_ (t)
+ {
+ }
+
+ virtual void
+ container (semantics::data_member& m)
+ {
+ string const& name (table_name (m, table_prefix_));
+
+ if (tables_.count (name))
+ return;
+
+ os << "DROP TABLE IF EXISTS `" << name << "`;" << endl;
+ tables_.insert (name);
+ }
+
+ private:
+ semantics::class_& object_;
+ tables& tables_;
};
struct class_drop: traversal::class_, context
@@ -104,11 +254,18 @@ namespace mysql
os << "DROP TABLE IF EXISTS `" << name << "`;" << endl;
+ // Drop tables for members.
+ //
+ {
+ member_drop mc (*this, c, tables_);
+ mc.traverse (c);
+ }
+
tables_.insert (name);
}
private:
- std::set<string> tables_;
+ tables tables_;
};
static char const file_header[] =
diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx
index d572560..29495df 100644
--- a/odb/mysql/source.cxx
+++ b/odb/mysql/source.cxx
@@ -18,21 +18,33 @@ namespace mysql
{
struct object_columns: object_columns_base, context
{
- object_columns (context& c, string const& suffix = "")
- : object_columns_base (c), context (c), suffix_ (suffix)
+ object_columns (context& c, char const* suffix = "")
+ : object_columns_base (c),
+ context (c),
+ first_ (true),
+ suffix_ (suffix)
+ {
+ }
+
+ object_columns (context& c, bool first, char const* suffix = "")
+ : object_columns_base (c),
+ context (c),
+ first_ (first),
+ suffix_ (suffix)
{
}
virtual void
column (semantics::data_member&, string const& name, bool first)
{
- if (!first)
+ if (!first || !first_)
os << ",\"" << endl;
os << "\"`" << name << "`" << suffix_;
}
private:
+ bool first_;
string suffix_;
};
@@ -82,43 +94,66 @@ namespace mysql
struct bind_member: member_base
{
- bind_member (context& c, size_t& index, bool id)
- : member_base (c, id), index_ (index)
+ bind_member (context& c,
+ size_t& index,
+ string const& var = string (),
+ string const& arg = string ())
+ : member_base (c, var), index_ (index), arg_override_ (arg)
+ {
+ }
+
+ bind_member (context& c,
+ size_t& index,
+ 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),
+ index_ (index),
+ arg_override_ (arg)
{
}
virtual void
- pre (type& m)
+ pre (member_info& mi)
{
+ if (container (mi.t))
+ return;
+
ostringstream ostr;
ostr << "b[" << index_ << "UL]";
b = ostr.str ();
- if (!id_)
- os << "// " << m.name () << endl
+ arg = arg_override_.empty () ? string ("i") : arg_override_;
+
+ if (var_override_.empty ())
+ os << "// " << mi.m.name () << endl
<< "//" << endl;
}
virtual void
- post (type& m)
+ post (member_info& mi)
{
- if (semantics::class_* c = comp_value (m.type ()))
+ if (container (mi.t))
+ return;
+ else if (semantics::class_* c = comp_value (mi.t))
index_ += column_count (*c);
else
index_++;
}
virtual void
- traverse_composite (type& m)
+ traverse_composite (member_info& mi)
{
- os << "composite_value_traits< " << m.type ().fq_name () <<
+ os << "composite_value_traits< " << mi.fq_type () <<
" >::bind (" << endl
- << "b + " << index_ << "UL, i." << var << "value);"
+ << "b + " << index_ << "UL, " << arg << "." << mi.var << "value);"
<< endl;
}
virtual void
- traverse_integer (type&, sql_type const& t)
+ traverse_integer (member_info& mi)
{
// While the is_unsigned should indicate whether the
// buffer variable is unsigned, rather than whether the
@@ -126,51 +161,51 @@ namespace mysql
// this is the same.
//
os << b << ".buffer_type = " <<
- integer_buffer_types[t.type - sql_type::TINYINT] << ";"
- << b << ".is_unsigned = " << (t.unsign ? "1" : "0") << ";"
- << b << ".buffer = &i." << var << "value;"
- << b << ".is_null = &i." << var << "null;"
+ 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;"
<< endl;
}
virtual void
- traverse_float (type&, sql_type const& t)
+ traverse_float (member_info& mi)
{
os << b << ".buffer_type = " <<
- float_buffer_types[t.type - sql_type::FLOAT] << ";"
- << b << ".buffer = &i." << var << "value;"
- << b << ".is_null = &i." << var << "null;"
+ float_buffer_types[mi.st->type - sql_type::FLOAT] << ";"
+ << b << ".buffer = &" << arg << "." << mi.var << "value;"
+ << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
virtual void
- traverse_decimal (type&, sql_type const&)
+ traverse_decimal (member_info& mi)
{
os << b << ".buffer_type = MYSQL_TYPE_NEWDECIMAL;"
- << b << ".buffer = i." << var << "value.data ();"
+ << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
<< b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "i." << var << "value.capacity ());"
- << b << ".length = &i." << var << "size;"
- << b << ".is_null = &i." << var << "null;"
+ << "" << arg << "." << mi.var << "value.capacity ());"
+ << b << ".length = &" << arg << "." << mi.var << "size;"
+ << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
virtual void
- traverse_date_time (type&, sql_type const& t)
+ traverse_date_time (member_info& mi)
{
os << b << ".buffer_type = " <<
- date_time_buffer_types[t.type - sql_type::DATE] << ";"
- << b << ".buffer = &i." << var << "value;";
+ date_time_buffer_types[mi.st->type - sql_type::DATE] << ";"
+ << b << ".buffer = &" << arg << "." << mi.var << "value;";
- if (t.type == sql_type::YEAR)
+ if (mi.st->type == sql_type::YEAR)
os << b << ".is_unsigned = 0;";
- os << b << ".is_null = &i." << var << "null;"
+ os << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
virtual void
- traverse_short_string (type&, sql_type const& t)
+ 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.
@@ -178,73 +213,76 @@ namespace mysql
// only if length is NULL.
//
os << b << ".buffer_type = " <<
- char_bin_buffer_types[t.type - sql_type::CHAR] << ";"
- << b << ".buffer = i." << var << "value.data ();"
+ 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
- << "i." << var << "value.capacity ());"
- << b << ".length = &i." << var << "size;"
- << b << ".is_null = &i." << var << "null;"
+ << "" << arg << "." << mi.var << "value.capacity ());"
+ << b << ".length = &" << arg << "." << mi.var << "size;"
+ << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
virtual void
- traverse_long_string (type&, sql_type const& t)
+ traverse_long_string (member_info& mi)
{
os << b << ".buffer_type = " <<
- char_bin_buffer_types[t.type - sql_type::CHAR] << ";"
- << b << ".buffer = i." << var << "value.data ();"
+ 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
- << "i." << var << "value.capacity ());"
- << b << ".length = &i." << var << "size;"
- << b << ".is_null = &i." << var << "null;"
+ << "" << arg << "." << mi.var << "value.capacity ());"
+ << b << ".length = &" << arg << "." << mi.var << "size;"
+ << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
virtual void
- traverse_bit (type&, sql_type const&)
+ traverse_bit (member_info& mi)
{
// Treated as a BLOB.
//
os << b << ".buffer_type = MYSQL_TYPE_BLOB;"
- << b << ".buffer = i." << var << "value;"
+ << b << ".buffer = " << arg << "." << mi.var << "value;"
<< b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "sizeof (i." << var << "value));"
- << b << ".length = &i." << var << "size;"
- << b << ".is_null = &i." << var << "null;"
+ << "sizeof (" << arg << "." << mi.var << "value));"
+ << b << ".length = &" << arg << "." << mi.var << "size;"
+ << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
virtual void
- traverse_enum (type&, sql_type const&)
+ traverse_enum (member_info& mi)
{
// Represented as a string.
//
os << b << ".buffer_type = MYSQL_TYPE_STRING;"
- << b << ".buffer = i." << var << "value.data ();"
+ << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
<< b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "i." << var << "value.capacity ());"
- << b << ".length = &i." << var << "size;"
- << b << ".is_null = &i." << var << "null;"
+ << "" << arg << "." << mi.var << "value.capacity ());"
+ << b << ".length = &" << arg << "." << mi.var << "size;"
+ << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
virtual void
- traverse_set (type&, sql_type const&)
+ traverse_set (member_info& mi)
{
// Represented as a string.
//
os << b << ".buffer_type = MYSQL_TYPE_STRING;"
- << b << ".buffer = i." << var << "value.data ();"
+ << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
<< b << ".buffer_length = static_cast<unsigned long> (" << endl
- << "i." << var << "value.capacity ());"
- << b << ".length = &i." << var << "size;"
- << b << ".is_null = &i." << var << "null;"
+ << "" << arg << "." << mi.var << "value.capacity ());"
+ << b << ".length = &" << arg << "." << mi.var << "size;"
+ << b << ".is_null = &" << arg << "." << mi.var << "null;"
<< endl;
}
private:
- string b;
size_t& index_;
+
+ string b;
+ string arg;
+ string arg_override_;
};
struct bind_base: traversal::class_, context
@@ -277,123 +315,139 @@ namespace mysql
struct grow_member: member_base
{
grow_member (context& c, size_t& index)
- : member_base (c, false), index_ (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 void
- pre (type& m)
+ pre (member_info& mi)
{
+ if (container (mi.t))
+ return;
+
ostringstream ostr;
ostr << "e[" << index_ << "UL]";
e = ostr.str ();
- os << "// " << m.name () << endl
- << "//" << endl;
+ if (var_override_.empty ())
+ os << "// " << mi.m.name () << endl
+ << "//" << endl;
}
virtual void
- post (type& m)
+ post (member_info& mi)
{
- if (semantics::class_* c = comp_value (m.type ()))
+ if (container (mi.t))
+ return;
+ else if (semantics::class_* c = comp_value (mi.t))
index_ += column_count (*c);
else
index_++;
}
virtual void
- traverse_composite (type& m)
+ traverse_composite (member_info& mi)
{
- os << "if (composite_value_traits< " << m.type ().fq_name () <<
+ os << "if (composite_value_traits< " << mi.fq_type () <<
" >::grow (" << endl
- << "i." << var << "value, e + " << index_ << "UL))"
+ << "i." << mi.var << "value, e + " << index_ << "UL))"
<< "{"
<< "r = true;"
<< "}";
}
virtual void
- traverse_integer (type&, sql_type const&)
+ traverse_integer (member_info&)
{
os << e << " = 0;"
<< endl;
}
virtual void
- traverse_float (type&, sql_type const&)
+ traverse_float (member_info&)
{
os << e << " = 0;"
<< endl;
}
virtual void
- traverse_decimal (type&, sql_type const&)
+ traverse_decimal (member_info& mi)
{
// @@ Optimization disabled.
//
os << "if (" << e << ")" << endl
<< "{"
- << "i." << var << "value.capacity (i." << var << "size);"
+ << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
<< "r = true;"
<< "}";
}
virtual void
- traverse_date_time (type&, sql_type const&)
+ traverse_date_time (member_info&)
{
os << e << " = 0;"
<< endl;
}
virtual void
- traverse_short_string (type&, sql_type const&)
+ traverse_short_string (member_info& mi)
{
// @@ Optimization disabled.
//
os << "if (" << e << ")" << endl
<< "{"
- << "i." << var << "value.capacity (i." << var << "size);"
+ << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
<< "r = true;"
<< "}";
}
virtual void
- traverse_long_string (type&, sql_type const&)
+ traverse_long_string (member_info& mi)
{
os << "if (" << e << ")" << endl
<< "{"
- << "i." << var << "value.capacity (i." << var << "size);"
+ << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
<< "r = true;"
<< "}";
}
virtual void
- traverse_bit (type&, sql_type const&)
+ traverse_bit (member_info&)
{
os << e << " = 0;"
<< endl;
}
virtual void
- traverse_enum (type&, sql_type const&)
+ traverse_enum (member_info& mi)
{
// Represented as a string.
//
os << "if (" << e << ")" << endl
<< "{"
- << "i." << var << "value.capacity (i." << var << "size);"
+ << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
<< "r = true;"
<< "}";
}
virtual void
- traverse_set (type&, sql_type const&)
+ traverse_set (member_info& mi)
{
// Represented as a string.
//
os << "if (" << e << ")" << endl
<< "{"
- << "i." << var << "value.capacity (i." << var << "size);"
+ << "i." << mi.var << "value.capacity (i." << mi.var << "size);"
<< "r = true;"
<< "}";
}
@@ -434,25 +488,41 @@ namespace mysql
struct init_image_member: member_base
{
- init_image_member (context& c, bool id)
- : member_base (c, id),
- member_image_type_ (c, id),
- member_database_type_ (c)
+ 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)
{
}
- virtual void
- pre (type& m)
+ 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)
{
- semantics::type& t (m.type ());
+ }
- if (comp_value (t))
- traits = "composite_value_traits< " + t.fq_name () + " >";
+ virtual void
+ pre (member_info& mi)
+ {
+ if (container (mi.t))
+ return;
+ else if (comp_value (mi.t))
+ traits = "composite_value_traits< " + mi.fq_type () + " >";
else
{
- type = t.fq_name (m.belongs ().hint ());
- image_type = member_image_type_.image_type (m);
- db_type = member_database_type_.database_type (m);
+ 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< "
+ type + ", "
@@ -460,11 +530,11 @@ namespace mysql
+ db_type + " >";
}
- if (id_)
- member = "id";
+ if (!member_override_.empty ())
+ member = member_override_;
else
{
- string const& name (m.name ());
+ string const& name (mi.m.name ());
member = "o." + name;
os << "// " << name << endl
@@ -473,9 +543,9 @@ namespace mysql
}
virtual void
- traverse_composite (type&)
+ traverse_composite (member_info& mi)
{
- os << "if (" << traits << "::init (i." << var << "value, " <<
+ os << "if (" << traits << "::init (i." << mi.var << "value, " <<
member << "))"
<< "{"
<< "grew = true;"
@@ -483,98 +553,98 @@ namespace mysql
}
virtual void
- traverse_integer (type&, sql_type const&)
+ traverse_integer (member_info& mi)
{
os << "{"
<< "bool is_null;"
<< traits << "::set_image (" << endl
- << "i." << var << "value, is_null, " << member << ");"
- << "i." << var << "null = is_null;"
+ << "i." << mi.var << "value, is_null, " << member << ");"
+ << "i." << mi.var << "null = is_null;"
<< "}";
}
virtual void
- traverse_float (type&, sql_type const&)
+ traverse_float (member_info& mi)
{
os << "{"
<< "bool is_null;"
<< traits << "::set_image (" << endl
- << "i." << var << "value, is_null, " << member << ");"
- << "i." << var << "null = is_null;"
+ << "i." << mi.var << "value, is_null, " << member << ");"
+ << "i." << mi.var << "null = is_null;"
<< "}";
}
virtual void
- traverse_decimal (type&, sql_type const&)
+ traverse_decimal (member_info& mi)
{
// @@ Optimization: can remove growth check if buffer is fixed.
//
os << "{"
<< "bool is_null;"
<< "std::size_t size;"
- << "std::size_t cap (i." << var << "value.capacity ());"
+ << "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
- << "i." << var << "value," << endl
+ << "i." << mi.var << "value," << endl
<< "size," << endl
<< "is_null," << endl
<< member << ");"
- << "i." << var << "size = static_cast<unsigned long> (size);"
- << "i." << var << "null = is_null;"
- << "grew = grew || (cap != i." << var << "value.capacity ());"
+ << "i." << mi.var << "size = static_cast<unsigned long> (size);"
+ << "i." << mi.var << "null = is_null;"
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
<< "}";
}
virtual void
- traverse_date_time (type&, sql_type const&)
+ traverse_date_time (member_info& mi)
{
os << "{"
<< "bool is_null;"
<< traits << "::set_image (" << endl
- << "i." << var << "value, is_null, " << member << ");"
- << "i." << var << "null = is_null;"
+ << "i." << mi.var << "value, is_null, " << member << ");"
+ << "i." << mi.var << "null = is_null;"
<< "}";
}
virtual void
- traverse_short_string (type&, sql_type const&)
+ traverse_short_string (member_info& mi)
{
// @@ Optimization: can remove growth check if buffer is fixed.
//
os << "{"
<< "bool is_null;"
<< "std::size_t size;"
- << "std::size_t cap (i." << var << "value.capacity ());"
+ << "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
- << "i." << var << "value," << endl
+ << "i." << mi.var << "value," << endl
<< "size," << endl
<< "is_null," << endl
<< member << ");"
- << "i." << var << "size = static_cast<unsigned long> (size);"
- << "i." << var << "null = is_null;"
- << "grew = grew || (cap != i." << var << "value.capacity ());"
+ << "i." << mi.var << "size = static_cast<unsigned long> (size);"
+ << "i." << mi.var << "null = is_null;"
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
<< "}";
}
virtual void
- traverse_long_string (type&, sql_type const&)
+ traverse_long_string (member_info& mi)
{
os << "{"
<< "bool is_null;"
<< "std::size_t size;"
- << "std::size_t cap (i." << var << "value.capacity ());"
+ << "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
- << "i." << var << "value," << endl
+ << "i." << mi.var << "value," << endl
<< "size," << endl
<< "is_null," << endl
<< member << ");"
- << "i." << var << "size = static_cast<unsigned long> (size);"
- << "i." << var << "null = is_null;"
- << "grew = grew || (cap != i." << var << "value.capacity ());"
+ << "i." << mi.var << "size = static_cast<unsigned long> (size);"
+ << "i." << mi.var << "null = is_null;"
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
<< "}";
}
virtual void
- traverse_bit (type&, sql_type const&)
+ traverse_bit (member_info& mi)
{
// Represented as a BLOB.
//
@@ -582,53 +652,53 @@ namespace mysql
<< "bool is_null;"
<< "std::size_t size;"
<< traits << "::set_image (" << endl
- << "i." << var << "value," << endl
- << "sizeof (i." << var << "value)," << endl
+ << "i." << mi.var << "value," << endl
+ << "sizeof (i." << mi.var << "value)," << endl
<< "size," << endl
<< "is_null," << endl
<< member << ");"
- << "i." << var << "size = static_cast<unsigned long> (size);"
- << "i." << var << "null = is_null;"
+ << "i." << mi.var << "size = static_cast<unsigned long> (size);"
+ << "i." << mi.var << "null = is_null;"
<< "}";
}
virtual void
- traverse_enum (type&, sql_type const&)
+ traverse_enum (member_info& mi)
{
// Represented as a string.
//
os << "{"
<< "bool is_null;"
<< "std::size_t size;"
- << "std::size_t cap (i." << var << "value.capacity ());"
+ << "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
- << "i." << var << "value," << endl
+ << "i." << mi.var << "value," << endl
<< "size," << endl
<< "is_null," << endl
<< member << ");"
- << "i." << var << "size = static_cast<unsigned long> (size);"
- << "i." << var << "null = is_null;"
- << "grew = grew || (cap != i." << var << "value.capacity ());"
+ << "i." << mi.var << "size = static_cast<unsigned long> (size);"
+ << "i." << mi.var << "null = is_null;"
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
<< "}";
}
virtual void
- traverse_set (type&, sql_type const&)
+ traverse_set (member_info& mi)
{
// Represented as a string.
//
os << "{"
<< "bool is_null;"
<< "std::size_t size;"
- << "std::size_t cap (i." << var << "value.capacity ());"
+ << "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
- << "i." << var << "value," << endl
+ << "i." << mi.var << "value," << endl
<< "size," << endl
<< "is_null," << endl
<< member << ");"
- << "i." << var << "size = static_cast<unsigned long> (size);"
- << "i." << var << "null = is_null;"
- << "grew = grew || (cap != i." << var << "value.capacity ());"
+ << "i." << mi.var << "size = static_cast<unsigned long> (size);"
+ << "i." << mi.var << "null = is_null;"
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
<< "}";
}
@@ -641,6 +711,8 @@ namespace mysql
member_image_type member_image_type_;
member_database_type member_database_type_;
+
+ string member_override_;
};
struct init_image_base: traversal::class_, context
@@ -670,24 +742,37 @@ namespace mysql
struct init_value_member: member_base
{
init_value_member (context& c)
- : member_base (c, false),
- member_image_type_ (c, false),
+ : member_base (c),
+ member_image_type_ (c),
member_database_type_ (c)
{
}
- virtual void
- pre (type& m)
+ 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)
{
- semantics::type& t (m.type ());
+ }
- if (comp_value (t))
- traits = "composite_value_traits< " + t.fq_name () + " >";
+ virtual void
+ pre (member_info& mi)
+ {
+ if (container (mi.t))
+ return;
+ else if (comp_value (mi.t))
+ traits = "composite_value_traits< " + mi.fq_type () + " >";
else
{
- type = m.type ().fq_name (m.belongs ().hint ());
- image_type = member_image_type_.image_type (m);
- db_type = member_database_type_.database_type (m);
+ 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< "
+ type + ", "
@@ -695,113 +780,122 @@ namespace mysql
+ db_type + " >";
}
- os << "// " << m.name () << endl
- << "//" << endl;
+ if (!member_override_.empty ())
+ member = member_override_;
+ else
+ {
+ string const& name (mi.m.name ());
+ member = "o." + name;
+
+ os << "// " << name << endl
+ << "//" << endl;
+ }
}
virtual void
- traverse_composite (type& m)
+ traverse_composite (member_info& mi)
{
- os << traits << "::init (o." << m.name () << ", i." << var << "value);"
+ os << traits << "::init (" << member << ", i." <<
+ mi.var << "value);"
<< endl;
}
virtual void
- traverse_integer (type& m, sql_type const&)
+ traverse_integer (member_info& mi)
{
os << traits << "::set_value (" << endl
- << "o." << m.name () << ", i." << var << "value, " <<
- "i." << var << "null);"
+ << member << ", i." << mi.var << "value, " <<
+ "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_float (type& m, sql_type const&)
+ traverse_float (member_info& mi)
{
os << traits << "::set_value (" << endl
- << "o." << m.name () << ", i." << var << "value, " <<
- "i." << var << "null);"
+ << member << ", i." << mi.var << "value, " <<
+ "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_decimal (type& m, sql_type const&)
+ traverse_decimal (member_info& mi)
{
os << traits << "::set_value (" << endl
- << "o." << m.name () << "," << endl
- << "i." << var << "value," << endl
- << "i." << var << "size," << endl
- << "i." << var << "null);"
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "i." << mi.var << "size," << endl
+ << "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_date_time (type& m, sql_type const&)
+ traverse_date_time (member_info& mi)
{
os << traits << "::set_value (" << endl
- << "o." << m.name () << ", i." << var << "value, " <<
- "i." << var << "null);"
+ << member << ", i." << mi.var << "value, " <<
+ "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_short_string (type& m, sql_type const&)
+ traverse_short_string (member_info& mi)
{
os << traits << "::set_value (" << endl
- << "o." << m.name () << "," << endl
- << "i." << var << "value," << endl
- << "i." << var << "size," << endl
- << "i." << var << "null);"
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "i." << mi.var << "size," << endl
+ << "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_long_string (type& m, sql_type const&)
+ traverse_long_string (member_info& mi)
{
os << traits << "::set_value (" << endl
- << "o." << m.name () << "," << endl
- << "i." << var << "value," << endl
- << "i." << var << "size," << endl
- << "i." << var << "null);"
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "i." << mi.var << "size," << endl
+ << "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_bit (type& m, sql_type const&)
+ traverse_bit (member_info& mi)
{
// Represented as a BLOB.
//
os << traits << "::set_value (" << endl
- << "o." << m.name () << "," << endl
- << "i." << var << "value," << endl
- << "i." << var << "size," << endl
- << "i." << var << "null);"
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "i." << mi.var << "size," << endl
+ << "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_enum (type& m, sql_type const&)
+ traverse_enum (member_info& mi)
{
// Represented as a string.
//
os << traits << "::set_value (" << endl
- << "o." << m.name () << "," << endl
- << "i." << var << "value," << endl
- << "i." << var << "size," << endl
- << "i." << var << "null);"
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "i." << mi.var << "size," << endl
+ << "i." << mi.var << "null);"
<< endl;
}
virtual void
- traverse_set (type& m, sql_type const&)
+ traverse_set (member_info& mi)
{
// Represented as a string.
//
os << traits << "::set_value (" << endl
- << "o." << m.name () << "," << endl
- << "i." << var << "value," << endl
- << "i." << var << "size," << endl
- << "i." << var << "null);"
+ << member << "," << endl
+ << "i." << mi.var << "value," << endl
+ << "i." << mi.var << "size," << endl
+ << "i." << mi.var << "null);"
<< endl;
}
@@ -810,9 +904,12 @@ namespace mysql
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
@@ -832,6 +929,872 @@ namespace mysql
}
};
+ // 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);
+
+ bool grow (false);
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ it = &container_it (t);
+ 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");
+
+ 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_));
+
+ // insert_one_statement
+ //
+ os << "const char* const " << scope << "::insert_one_statement =" << endl
+ << "\"INSERT INTO `" << table << "` (\"" << endl
+ << "\"`" << column_name (m, "id", "object_id") << "`";
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << ",\"" << endl
+ << "\"`" << column_name (m, "index", "index") << "`";
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ if (comp_value (*kt))
+ {
+ object_columns t (*this, false);
+ t.traverse_composite (m, *kt, "key", "key");
+ }
+ else
+ {
+ os << ",\"" << endl
+ << "\"`" << column_name (m, "key", "key") << "`";
+ }
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ break;
+ }
+ }
+
+ if (comp_value (vt))
+ {
+ object_columns t (*this, false);
+ t.traverse_composite (m, vt, "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;
+
+ // select_all_statement
+ //
+ os << "const char* const " << scope << "::select_all_statement =" << endl
+ << "\"SELECT \"" << endl
+ << "\"`" << column_name (m, "id", "object_id") << "`";
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << ",\"" << endl
+ << "\"`" << column_name (m, "index", "index") << "`";
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ if (comp_value (*kt))
+ {
+ object_columns t (*this, false);
+ t.traverse_composite (m, *kt, "key", "key");
+ }
+ else
+ {
+ os << ",\"" << endl
+ << "\"`" << column_name (m, "key", "key") << "`";
+ }
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ break;
+ }
+ }
+
+ if (comp_value (vt))
+ {
+ object_columns t (*this, false);
+ t.traverse_composite (m, vt, "value", "value");
+ }
+ else
+ {
+ os << ",\"" << endl
+ << "\"`" << column_name (m, "value", "value") << "`";
+ }
+
+ os << "\"" << endl
+ << "\" FROM `" << table << "` WHERE `" <<
+ column_name (m, "id", "object_id") << "` = ?\"" << endl;
+
+ if (ck == ck_ordered)
+ os << "\" ORDER BY `" << column_name (m, "index", "index") << "`\"";
+
+ os << ";"
+ << endl;
+
+ // delete_all_statement
+ //
+ os << "const char* const " << scope << "::delete_all_statement =" << endl
+ << "\"DELETE FROM `" << table << "`\"" << endl
+ << "\" WHERE `" << column_name (m, "id", "object_id") << "` = ?\";"
+ << endl;
+
+ //
+ // Functions.
+ //
+
+ // bind()
+ //
+ {
+ size_t index;
+ bind_member bind_id (*this, index, "id_", "id");
+
+ // bind (cond_image_type)
+ //
+ os << "void " << scope << "::" << endl
+ << "bind (MYSQL_BIND* b, id_image_type* p, cond_image_type& c)"
+ << "{";
+
+ index = 0;
+
+ os << "// object_id" << endl
+ << "//" << endl
+ << "if (p != 0)"
+ << "{"
+ << "id_image_type& id (*p);";
+ bind_id.traverse (id_member_);
+ os << "}";
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "// index" << endl
+ << "//" << endl;
+ bind_member bm (
+ *this, index, "index_", "c", *it, "index_type", "index");
+ bm.traverse (m);
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ os << "// key" << endl
+ << "//" << endl;
+ bind_member bm (
+ *this, index, "key_", "c", *kt, "key_type", "key");
+ bm.traverse (m);
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ os << "// value" << endl
+ << "//" << endl;
+ bind_member bm (
+ *this, index, "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)"
+ << "{";
+
+ index = 0;
+
+ os << "// object_id" << endl
+ << "//" << endl
+ << "if (p != 0)"
+ << "{"
+ << "id_image_type& id (*p);";
+ bind_id.traverse (id_member_);
+ os << "}";
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "// index" << endl
+ << "//" << endl;
+ bind_member bm (
+ *this, index, "index_", "d", *it, "index_type", "index");
+ bm.traverse (m);
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ os << "// key" << endl
+ << "//" << endl;
+ bind_member bm (
+ *this, index, "key_", "d", *kt, "key_type", "key");
+ bm.traverse (m);
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ break;
+ }
+ }
+
+ os << "// value" << endl
+ << "//" << endl;
+ bind_member bm (
+ *this, index, "value_", "d", vt, "value_type", "value");
+ bm.traverse (m);
+
+ os << "}";
+ }
+
+ // grow ()
+ //
+ {
+ size_t index (0);
+
+ os << "bool " << scope << "::" << endl
+ << "grow (data_image_type&" << (grow ? " i" : "") << ", my_bool* e)"
+ << "{"
+ << "bool r (false);"
+ << endl;
+
+ switch (ck)
+ {
+ case ck_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 << "return r;"
+ << "}";
+ }
+
+ // init (data_image)
+ //
+ os << "bool " << scope << "::" << endl;
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "init (data_image_type& i, index_type j, const value_type& v)"
+ << "{"
+ << "bool grew (false);"
+ << endl
+ << "// 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 << "return grew;"
+ << "}";
+
+ // init (data)
+ //
+ os << "void " << scope << "::" << endl;
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "init (index_type& j, value_type& v, const data_image_type& i)"
+ << "{"
+ << "// 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)"
+ << "{"
+ << "// 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)"
+ << "{";
+ break;
+ }
+ }
+
+ os << "// value" << endl
+ << "//" << endl;
+ {
+ init_value_member im (
+ *this, "value_", "v", vt, "value_type", "value");
+ im.traverse (m);
+ }
+ os << "}";
+
+ // insert_one
+ //
+ os << "void " << scope << "::" << endl;
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "insert_one (index_type i, const value_type& v, void* d)";
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ os << "insert_one (const key_type& k, const value_type& v, void* d)";
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ os << "insert_one (const value_type& v, void* d)";
+ break;
+ }
+ }
+
+ 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
+ << "if (";
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "init (di, 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 << " || b.version == 0)"
+ << "{"
+ << "bind (b.bind, 0, di);"
+ << "b.version++;"
+ << "}"
+ << "if (!sts.insert_one_statement ().execute ())" << endl
+ << "throw object_already_persistent ();"
+ << "}";
+
+
+ // load_all
+ //
+ os << "bool " << scope << "::" << endl;
+
+ switch (ck)
+ {
+ case ck_ordered:
+ {
+ os << "load_all (index_type& 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 (i, v, di);";
+ break;
+ }
+ case ck_map:
+ case ck_multimap:
+ {
+ os << "init (k, v, di);";
+ break;
+ }
+ case ck_set:
+ case ck_multiset:
+ {
+ os << "init (v, di);";
+ break;
+ }
+ }
+
+ // Fetch next.
+ //
+ os << endl
+ << "select_statement& st (sts.select_all_statement ());"
+ << "select_statement::result r (st.fetch ());";
+
+ if (grow)
+ os << endl
+ << "if (r == select_statement::truncated)"
+ << "{"
+ << "if (grow (di, sts.data_image_error ()))"
+ << "{"
+ << "binding& db (sts.data_image_binding ());"
+ << "bind (db.bind, 0, di);"
+ << "db.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* d)"
+ << "{"
+ << "using namespace mysql;"
+ << endl
+ << "typedef container_statements< " << name << " > statements;"
+ << "statements& sts (*static_cast< statements* > (d));"
+ << "sts.delete_all_statement ().execute ();"
+ << "}";
+
+ // persist
+ //
+ os << "void " << scope << "::" << endl
+ << "persist (const container_type& c," << endl
+ << "id_image_type& id," << endl
+ << "bool rebind," << endl
+ << "statements_type& sts)"
+ << "{"
+ << "using namespace mysql;"
+ << endl
+ << "binding& b (sts.data_image_binding ());"
+ << "if (rebind || b.version == 0)"
+ << "{"
+ << "bind (b.bind, &id, sts.data_image ());"
+ << "b.version++;"
+ << "}"
+ << "if (rebind)" // We don't need it, just don't miss the event.
+ << "{"
+ << "binding& cb (sts.cond_image_binding ());"
+ << "bind (cb.bind, &id, sts.cond_image ());"
+ << "cb.version++;"
+ << "}"
+ << "container_traits::persist (c, sts.functions ());"
+ << "}";
+
+ // load
+ //
+ os << "void " << scope << "::" << endl
+ << "load (container_type& c," << endl
+ << "id_image_type& id," << endl
+ << "bool rebind," << endl
+ << "statements_type& sts)"
+ << "{"
+ << "using namespace mysql;"
+ << endl
+ << "binding& db (sts.data_image_binding ());"
+ << "if (rebind || db.version == 0)"
+ << "{"
+ << "bind (db.bind, &id, sts.data_image ());"
+ << "db.version++;"
+ << "}"
+ << "binding& cb (sts.cond_image_binding ());"
+ << "if (rebind || cb.version == 0)"
+ << "{"
+ << "bind (cb.bind, &id, sts.cond_image ());"
+ << "cb.version++;"
+ << "}"
+ << "select_statement& st (sts.select_all_statement ());"
+ << "st.execute ();"
+ << "select_statement::result r (st.fetch ());";
+
+ if (grow)
+ os << endl
+ << "if (r == select_statement::truncated)"
+ << "{"
+ << "if (grow (sts.data_image (), sts.data_image_error ()))"
+ << "{"
+ << "bind (db.bind, 0, sts.data_image ());"
+ << "db.version++;"
+ << "st.refetch ();"
+ << "}"
+ << "}";
+
+ os << "bool more (r != select_statement::no_data);"
+ << endl
+ << "if (!more)" << endl
+ << "st.free_result ();"
+ << endl
+ << "container_traits::load (c, more, sts.functions ());"
+ << "}";
+
+ // update
+ //
+ os << "void " << scope << "::" << endl
+ << "update (const container_type& c," << endl
+ << "id_image_type& id," << endl
+ << "bool rebind," << endl
+ << "statements_type& sts)"
+ << "{"
+ << "using namespace mysql;"
+ << endl
+ << "binding& db (sts.data_image_binding ());"
+ << "if (rebind || db.version == 0)"
+ << "{"
+ << "bind (db.bind, &id, sts.data_image ());"
+ << "db.version++;"
+ << "}"
+ << "binding& cb (sts.cond_image_binding ());"
+ << "if (rebind || cb.version == 0)" // We may need it (delete_all).
+ << "{"
+ << "bind (cb.bind, &id, sts.cond_image ());"
+ << "cb.version++;"
+ << "}"
+ << "container_traits::update (c, sts.functions ());"
+ << "}";
+
+ // erase
+ //
+ os << "void " << scope << "::" << endl
+ << "erase (id_image_type& id, bool rebind, statements_type& sts)"
+ << "{"
+ << "using namespace mysql;"
+ << endl
+ << "binding& b (sts.cond_image_binding ());"
+ << "if (rebind || b.version == 0)"
+ << "{"
+ << "bind (b.bind, &id, sts.cond_image ());"
+ << "b.version++;"
+ << "}"
+ << "if (rebind)"
+ << "{"
+ << "binding& db (sts.data_image_binding ());"
+ << "bind (db.bind, &id, sts.data_image ());"
+ << "db.version++;"
+ << "}"
+ << "container_traits::erase (sts.functions ());"
+ << "}";
+ }
+
+ 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),
+ containers_ (false)
+ {
+ }
+
+ bool
+ containers () const
+ {
+ return containers_;
+ }
+
+ virtual void
+ container (semantics::data_member& m)
+ {
+ string traits (prefix_ + public_name (m) + "_traits");
+ os << "mysql::container_statements< " << traits << " > " <<
+ prefix_ << m.name () << ";";
+
+ containers_ = true;
+ }
+
+ private:
+ bool containers_;
+ };
+
+ 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::type& t)
+ {
+ string old (obj_prefix_);
+ obj_prefix_ += m.name ();
+ obj_prefix_ += '.';
+ object_members_base::composite (m, t);
+ obj_prefix_ = old;
+ }
+
+ virtual void
+ container (semantics::data_member& m)
+ {
+ using semantics::type;
+
+ 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:
+ {
+ os << traits << "::persist (obj." << obj_name << ", i, grew, " <<
+ "sts.container_statment_cache ()." << sts_name << ");";
+ break;
+ }
+ case load_call:
+ {
+ os << traits << "::load (obj." << obj_name << ", i, grew, " <<
+ "sts.container_statment_cache ()." << sts_name << ");";
+ break;
+ }
+ case update_call:
+ {
+ os << traits << "::update (obj." << obj_name << ", i, grew, " <<
+ "sts.container_statment_cache ()." << sts_name << ");";
+ break;
+ }
+ case erase_call:
+ {
+ os << traits << "::erase (i, grew, " <<
+ "sts.container_statment_cache ()." << sts_name << ");";
+ break;
+ }
+ }
+ }
+
+ private:
+ call_type call_;
+ string obj_prefix_;
+ };
+
//
//
struct class_: traversal::class_, context
@@ -841,11 +1804,11 @@ namespace mysql
grow_base_ (c, index_),
grow_member_ (c, index_),
bind_base_ (c, index_),
- bind_member_ (c, index_, false),
- bind_id_member_ (c, index_, true),
+ bind_member_ (c, index_),
+ bind_id_member_ (c, index_, "id_"),
init_image_base_ (c),
- init_image_member_ (c, false),
- init_id_image_member_ (c, true),
+ init_image_member_ (c),
+ init_id_image_member_ (c, "id_", "id"),
init_value_base_ (c),
init_value_member_ (c)
{
@@ -854,13 +1817,10 @@ namespace mysql
bind_base_inherits_ >> bind_base_;
bind_member_names_ >> bind_member_;
- bind_id_member_names_ >> bind_id_member_;
init_image_base_inherits_ >> init_image_base_;
init_image_member_names_ >> init_image_member_;
- init_id_image_member_names_ >> init_id_image_member_;
-
init_value_base_inherits_ >> init_value_base_;
init_value_member_names_ >> init_value_member_;
}
@@ -886,14 +1846,48 @@ namespace mysql
bool grow (context::grow (c));
bool def_ctor (TYPE_HAS_DEFAULT_CONSTRUCTOR (c.tree_node ()));
- id_member_.traverse (c);
- semantics::data_member& id (*id_member_.member ());
+ semantics::data_member& id (id_member (c));
bool auto_id (id.count ("auto"));
os << "// " << c.name () << endl
<< "//" << endl
<< endl;
+ //
+ // Containers.
+ //
+
+ // Statement cache (definition).
+ //
+ bool containers;
+ {
+ os << "struct " << traits << "::container_statement_cache_type"
+ << "{";
+
+ container_cache_members cm (*this);
+ cm.traverse (c);
+ containers = cm.containers ();
+
+ 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 ())
@@ -1008,7 +2002,7 @@ namespace mysql
<< "{";
index_ = 0;
- names (c, bind_id_member_names_);
+ bind_id_member_.traverse (id);
os << "}";
@@ -1060,11 +2054,36 @@ namespace mysql
<< "bind (b.bind, sts.image ());"
<< "b.version++;"
<< "}"
- << "mysql::persist_statement& st (sts.persist_statement ());"
- << "st.execute ();";
+ << "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 ());";
+ os << "obj." << id.name () << " = static_cast<id_type> (st.id ());"
+ << endl;
+
+ if (containers)
+ {
+ // Initialize id_image.
+ //
+ os << "{"
+ << "bool grew (false);"
+ << "const id_type& id (obj." << id.name () << ");"
+ << "id_image_type& i (sts.id_image ());";
+ init_id_image_member_.traverse (id);
+ os << "binding& idb (sts.id_image_binding ());"
+ << "if (grew && idb.version != 0)"
+ << "{"
+ << "bind (idb.bind, i);"
+ << "idb.version++;"
+ << "}";
+
+ container_calls t (*this, container_calls::persist_call);
+ t.traverse (c);
+
+ os << "}";
+ }
os << "}";
@@ -1082,7 +2101,7 @@ namespace mysql
<< "bool grew (false);"
<< "const id_type& id (object_traits::id (obj));"
<< "id_image_type& i (sts.id_image ());";
- names (c, init_id_image_member_names_);
+ init_id_image_member_.traverse (id);
os << "binding& idb (sts.id_image_binding ());"
<< "if (grew || idb.version == 0)"
<< "{"
@@ -1095,8 +2114,16 @@ namespace mysql
<< "bind (imb.bind, sts.image ());"
<< "imb.version++;"
<< "}"
- << "sts.update_statement ().execute ();"
- << "}";
+ << "sts.update_statement ().execute ();";
+
+ if (containers)
+ {
+ os << endl;
+ container_calls t (*this, container_calls::update_call);
+ t.traverse (c);
+ }
+
+ os << "}";
// erase ()
//
@@ -1111,19 +2138,29 @@ namespace mysql
<< endl
<< "bool grew (false);"
<< "id_image_type& i (sts.id_image ());";
- names (c, init_id_image_member_names_);
+ init_id_image_member_.traverse (id);
os << "binding& idb (sts.id_image_binding ());"
<< "if (grew || idb.version == 0)"
<< "{"
<< "bind (idb.bind, i);"
<< "idb.version++;"
<< "}"
- << "sts.erase_statement ().execute ();"
- << "}";
+ << "if (sts.erase_statement ().execute () != 1)" << endl
+ << "throw object_not_persistent ();";
+
+ if (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&, const id_type& id)"
@@ -1134,18 +2171,30 @@ namespace mysql
<< "object_statements<object_type>& sts (" << endl
<< "conn.statement_cache ().find<object_type> ());"
<< endl
- << "if (find (sts, id))"
+ << "bool grew (false);"
+ << "if (find (sts, id, grew))"
<< "{"
<< "pointer_type p (access::object_factory< " << type <<
" >::create ());"
<< "pointer_traits< pointer_type >::guard g (p);"
- << "init (pointer_traits< pointer_type >::get_ref (p), " <<
- "sts.image ());"
- << "g.release ();"
+ << "object_type& obj (pointer_traits< pointer_type >::get_ref (p));"
+ << "init (obj, sts.image ());";
+
+ if (containers)
+ {
+ os << endl
+ << "id_image_type& i (sts.id_image ());";
+ container_calls t (*this, container_calls::load_call);
+ t.traverse (c);
+ os << endl;
+ }
+
+ os << "g.release ();"
<< "return p;"
<< "}"
<< "return pointer_type ();"
<< "}";
+ }
os << "bool " << traits << "::" << endl
<< "find (database&, const id_type& id, object_type& obj)"
@@ -1156,23 +2205,34 @@ namespace mysql
<< "object_statements<object_type>& sts (" << endl
<< "conn.statement_cache ().find<object_type> ());"
<< endl
- << "if (find (sts, id))"
+ << "bool grew (false);"
+ << "if (find (sts, id, grew))"
<< "{"
- << "init (obj, sts.image ());"
- << "return true;"
+ << "init (obj, sts.image ());";
+
+ if (containers)
+ {
+ os << endl
+ << "id_image_type& i (sts.id_image ());";
+ container_calls t (*this, container_calls::load_call);
+ t.traverse (c);
+ os << endl;
+ }
+
+ os << "return true;"
<< "}"
<< "return false;"
<< "}";
os << "bool " << traits << "::" << endl
- << "find (mysql::object_statements<object_type>& sts, " <<
- "const id_type& id)"
+ << "find (mysql::object_statements<object_type>& sts," << endl
+ << "const id_type& id," << endl
+ << "bool& grew)"
<< "{"
<< "using namespace mysql;"
<< endl
- << "bool grew (false);"
<< "id_image_type& i (sts.id_image ());";
- names (c, init_id_image_member_names_);
+ init_id_image_member_.traverse (id);
os << "binding& idb (sts.id_image_binding ());"
<< "if (grew || idb.version == 0)"
<< "{"
@@ -1185,15 +2245,13 @@ namespace mysql
<< "bind (imb.bind, sts.image ());"
<< "imb.version++;"
<< "}"
- << "mysql::find_statement& st (sts.find_statement ());"
- << "mysql::find_statement::result r (st.execute ());"
- << endl
- << "if (r == mysql::find_statement::no_data)" << endl
- << "return false;"
- << endl;
+ << "select_statement& st (sts.find_statement ());"
+ << "st.execute ();"
+ << "select_statement::result r (st.fetch ());";
if (grow)
- os << "if (r == mysql::find_statement::truncated)"
+ os << endl
+ << "if (r == select_statement::truncated)"
<< "{"
<< "if (grow (sts.image (), sts.image_error ()))"
<< "{"
@@ -1204,7 +2262,7 @@ namespace mysql
<< "}";
os << "st.free_result ();"
- << "return true;"
+ << "return r != select_statement::no_data;"
<< "}";
// query ()
@@ -1227,11 +2285,11 @@ namespace mysql
<< "bind (imb.bind, sts.image ());"
<< "imb.version++;"
<< "}"
- << "details::shared_ptr<query_statement> st (" << endl
- << "new (details::shared) query_statement (conn," << endl
+ << "details::shared_ptr<select_statement> st (" << endl
+ << "new (details::shared) select_statement (conn," << endl
<< "query_clause + q.clause ()," << endl
- << "imb," << endl
- << "q.parameters ()));"
+ << "q.parameters ()," << endl
+ << "imb));"
<< "st->execute ();"
<< endl
<< "details::shared_ptr<odb::result_impl<object_type> > r (" << endl
@@ -1244,6 +2302,9 @@ namespace mysql
virtual void
traverse_value (type& c)
{
+ bool columns (column_count (c) != 0);
+ bool grow (columns && context::grow (c));
+
string const& type (c.fq_name ());
string traits ("access::composite_value_traits< " + type + " >");
@@ -1254,7 +2315,8 @@ namespace mysql
// grow ()
//
os << "bool " << traits << "::" << endl
- << "grow (image_type&" << (grow (c) ? " i" : "") << ", my_bool* e)"
+ << "grow (image_type&" << (grow ? " i" : "") << ", " <<
+ "my_bool*" << (columns ? " e" : "") << ")"
<< "{"
<< "bool r (false);"
<< endl;
@@ -1269,7 +2331,8 @@ namespace mysql
// bind (image_type)
//
os << "void " << traits << "::" << endl
- << "bind (MYSQL_BIND* b, image_type& i)"
+ << "bind (MYSQL_BIND*" << (columns ? " b" : "") << ", " <<
+ "image_type&" << (columns ? " i" : "") << ")"
<< "{";
index_ = 0;
@@ -1281,7 +2344,8 @@ namespace mysql
// init (image, object)
//
os << "bool " << traits << "::" << endl
- << "init (image_type& i, const value_type& o)"
+ << "init (image_type&" << (columns ? " i" : "") << ", " <<
+ "const value_type&" << (columns ? " o" : "") << ")"
<< "{"
<< "bool grew (false);"
<< endl;
@@ -1295,7 +2359,8 @@ namespace mysql
// init (object, image)
//
os << "void " << traits << "::" << endl
- << "init (value_type& o, const image_type& i)"
+ << "init (value_type&" << (columns ? " o" : "") << ", " <<
+ "const image_type&" << (columns ? " i" : "") << ")"
<< "{";
inherits (c, init_value_base_inherits_);
@@ -1305,8 +2370,6 @@ namespace mysql
}
private:
- id_member id_member_;
-
bool id_;
size_t index_;
@@ -1320,7 +2383,6 @@ namespace mysql
bind_member bind_member_;
traversal::names bind_member_names_;
bind_member bind_id_member_;
- traversal::names bind_id_member_names_;
init_image_base init_image_base_;
traversal::inherits init_image_base_inherits_;
@@ -1328,7 +2390,6 @@ namespace mysql
traversal::names init_image_member_names_;
init_image_member init_id_image_member_;
- traversal::names init_id_image_member_names_;
init_value_base init_value_base_;
traversal::inherits init_value_base_inherits_;
@@ -1359,6 +2420,9 @@ namespace mysql
<< "#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 ())