aboutsummaryrefslogtreecommitdiff
path: root/odb/mysql
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-11-17 18:05:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-11-17 18:05:06 +0200
commit2fe7a723c0b98d23531a76d9c1a451e3a57bf0c5 (patch)
tree8bd0323a9114a405902b3dfc116f97307278ae2b /odb/mysql
parent302b804ec633889f26dc54d937d9becc09246152 (diff)
Add support for unidirectional object relationships
New test: common/relationship.
Diffstat (limited to 'odb/mysql')
-rw-r--r--odb/mysql/common.cxx227
-rw-r--r--odb/mysql/common.hxx17
-rw-r--r--odb/mysql/context.cxx41
-rw-r--r--odb/mysql/context.hxx3
-rw-r--r--odb/mysql/header.cxx13
-rw-r--r--odb/mysql/schema.cxx24
-rw-r--r--odb/mysql/source.cxx315
7 files changed, 393 insertions, 247 deletions
diff --git a/odb/mysql/common.cxx b/odb/mysql/common.cxx
index 17cae9e..d7e6187 100644
--- a/odb/mysql/common.cxx
+++ b/odb/mysql/common.cxx
@@ -33,130 +33,149 @@ namespace mysql
semantics::type& t (type_override_ != 0 ? *type_override_ : m.type ());
- member_info mi (m, t, var, fq_type_override_);
-
if (comp_value (t))
{
+ member_info mi (m, t, var, fq_type_override_);
pre (mi);
traverse_composite (mi);
+ post (mi);
}
else if (container (t))
{
+ member_info mi (m, t, var, fq_type_override_);
pre (mi);
traverse_container (mi);
+ post (mi);
}
else
{
sql_type const& st (db_type (m, key_prefix_));
- mi.st = &st;
- pre (mi);
- switch (st.type)
+ if (semantics::class_* c = object_pointer (m, key_prefix_))
{
- // 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.
+ member_info mi (m, id_member (*c).type (), var, fq_type_override_);
+ mi.st = &st;
+ pre (mi);
+ traverse_object_pointer (mi);
+ post (mi);
+ }
+ else
+ {
+ member_info mi (m, t, var, fq_type_override_);
+ mi.st = &st;
+ 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.
//
- 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.
+ 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.
//
- 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);
- break;
- }
- case sql_type::VARBINARY:
- case sql_type::BLOB:
- case sql_type::MEDIUMBLOB:
- case sql_type::LONGBLOB:
- {
- if (st.range && 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;
- }
+ else
+ traverse_long_string (mi);
+
+ break;
}
- }
- post (mi);
+ // 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;
+ }
+ }
}
//
diff --git a/odb/mysql/common.hxx b/odb/mysql/common.hxx
index 31c6962..fb1f2a3 100644
--- a/odb/mysql/common.hxx
+++ b/odb/mysql/common.hxx
@@ -46,7 +46,13 @@ namespace mysql
string
fq_type () const
{
- return fq_type_.empty () ? t.fq_name (m.belongs ().hint ()) : fq_type_;
+ // 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_;
@@ -81,6 +87,15 @@ namespace mysql
}
virtual void
+ traverse_object_pointer (member_info& mi)
+ {
+ traverse_simple (mi);
+ }
+
+ virtual void
+ traverse_simple (member_info&);
+
+ virtual void
traverse_integer (member_info&)
{
}
diff --git a/odb/mysql/context.cxx b/odb/mysql/context.cxx
index 4803da2..de3eed0 100644
--- a/odb/mysql/context.cxx
+++ b/odb/mysql/context.cxx
@@ -26,28 +26,28 @@ namespace mysql
type_map_entry type_map[] =
{
- {"bool", "TINYINT(1) NOT NULL", 0},
+ {"bool", "TINYINT(1)", 0},
- {"char", "TINYINT NOT NULL", 0},
- {"signed char", "TINYINT NOT NULL", 0},
- {"unsigned char", "TINYINT UNSIGNED NOT NULL", 0},
+ {"char", "TINYINT", 0},
+ {"signed char", "TINYINT", 0},
+ {"unsigned char", "TINYINT UNSIGNED", 0},
- {"short int", "SMALLINT NOT NULL", 0},
- {"short unsigned int", "SMALLINT UNSIGNED NOT NULL", 0},
+ {"short int", "SMALLINT", 0},
+ {"short unsigned int", "SMALLINT UNSIGNED", 0},
- {"int", "INT NOT NULL", 0},
- {"unsigned int", "INT UNSIGNED NOT NULL", 0},
+ {"int", "INT", 0},
+ {"unsigned int", "INT UNSIGNED", 0},
- {"long int", "BIGINT NOT NULL", 0},
- {"long unsigned int", "BIGINT UNSIGNED NOT NULL", 0},
+ {"long int", "BIGINT", 0},
+ {"long unsigned int", "BIGINT UNSIGNED", 0},
- {"long long int", "BIGINT NOT NULL", 0},
- {"long long unsigned int", "BIGINT UNSIGNED NOT NULL", 0},
+ {"long long int", "BIGINT", 0},
+ {"long long unsigned int", "BIGINT UNSIGNED", 0},
- {"float", "FLOAT NOT NULL", 0},
- {"double", "DOUBLE NOT NULL", 0},
+ {"float", "FLOAT", 0},
+ {"double", "DOUBLE", 0},
- {"::std::string", "TEXT NOT NULL", "VARCHAR(255) NOT NULL"}
+ {"::std::string", "TEXT", "VARCHAR (255)"}
};
}
@@ -145,8 +145,10 @@ namespace mysql
virtual void
traverse_composite (member_info& mi)
{
+ // Reset any overrides.
+ //
if (!hg_.r_)
- hg_.r_ = hg_.dispatch (dynamic_cast<semantics::class_&> (mi.t));
+ hg_.r_ = context::grow (dynamic_cast<semantics::class_&> (mi.t));
}
virtual void
@@ -216,11 +218,12 @@ namespace mysql
string context::data::
column_type_impl (semantics::type& t,
string const& type,
- semantics::context* ctx) const
+ semantics::context& ctx,
+ column_type_flags f) const
{
- string r (::context::data::column_type_impl (t, type, ctx));
+ string r (::context::data::column_type_impl (t, type, ctx, f));
- if (!r.empty () && ctx != 0 && ctx->count ("auto"))
+ if (!r.empty () && ctx.count ("auto") && (f & ctf_object_id_ref) == 0)
r += " AUTO_INCREMENT";
return r;
diff --git a/odb/mysql/context.hxx b/odb/mysql/context.hxx
index 9a6beec..4ac36ca 100644
--- a/odb/mysql/context.hxx
+++ b/odb/mysql/context.hxx
@@ -105,7 +105,8 @@ namespace mysql
virtual string
column_type_impl (semantics::type&,
string const& type,
- semantics::context*) const;
+ semantics::context&,
+ column_type_flags) const;
};
private:
diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx
index 79b8d67..130a2ba 100644
--- a/odb/mysql/header.cxx
+++ b/odb/mysql/header.cxx
@@ -525,24 +525,25 @@ namespace mysql
{
case ck_ordered:
{
- os << "init (index_type&, value_type&, const data_image_type&);";
+ os << "init (index_type&, value_type&, ";
break;
}
case ck_map:
case ck_multimap:
{
- os << "init (key_type&, value_type&, const data_image_type&);";
+ os << "init (key_type&, value_type&, ";
break;
}
case ck_set:
case ck_multiset:
{
- os << "init (value_type&, const data_image_type&);";
+ os << "init (value_type&, ";
break;
}
}
- os << endl;
+ os << "const data_image_type&, database&);"
+ << endl;
// insert_one
//
@@ -801,7 +802,7 @@ namespace mysql
// init (object, image)
//
os << "static void" << endl
- << "init (object_type&, const image_type&);"
+ << "init (object_type&, const image_type&, database&);"
<< endl;
// persist ()
@@ -895,7 +896,7 @@ namespace mysql
// init (object, image)
//
os << "static void" << endl
- << "init (value_type&, const image_type&);"
+ << "init (value_type&, const image_type&, database&);"
<< endl;
os << "};";
diff --git a/odb/mysql/schema.cxx b/odb/mysql/schema.cxx
index 1dfeb1f..0c004ad 100644
--- a/odb/mysql/schema.cxx
+++ b/odb/mysql/schema.cxx
@@ -18,8 +18,8 @@ namespace mysql
struct object_columns: object_columns_base, context
{
- object_columns (context& c)
- : object_columns_base (c), context (c)
+ object_columns (context& c, string const& prefix = string ())
+ : object_columns_base (c), context (c), prefix_ (prefix)
{
}
@@ -29,11 +29,21 @@ namespace mysql
if (!first)
os << "," << endl;
- os << " `" << name << "` " << column_type (m);
+ os << " `" << name << "` " << column_type (m, prefix_);
if (m.count ("id"))
os << " PRIMARY KEY";
+
+ using semantics::class_;
+ if (class_* c = object_pointer (m, prefix_))
+ {
+ os << " REFERENCES `" << table_name (*c) << "` (`" <<
+ column_name (id_member (*c)) << "`)";
+ }
}
+
+ private:
+ string prefix_;
};
struct member_create: object_members_base, context
@@ -67,7 +77,7 @@ namespace mysql
// object_id (simple value)
//
string id_name (column_name (m, "id", "object_id"));
- os << " `" << id_name << "` " << column_type (id_member_);
+ os << " `" << id_name << "` " << column_type (id_member_, "ref");
// index (simple value)
//
@@ -95,8 +105,9 @@ namespace mysql
}
else
{
+ object_columns oc (*this, "key");
string const& name (column_name (m, "key", "key"));
- os << " `" << name << "` " << column_type (m, "key");
+ oc.column (m, name, true);
}
}
@@ -112,8 +123,9 @@ namespace mysql
}
else
{
+ object_columns oc (*this, "value");
string const& name (column_name (m, "value", "value"));
- os << " `" << name << "` " << column_type (m, "value");
+ oc.column (m, name, true);
}
}
diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx
index 2f65de6..8351ad5 100644
--- a/odb/mysql/source.cxx
+++ b/odb/mysql/source.cxx
@@ -516,19 +516,6 @@ namespace mysql
{
if (container (mi.t))
return;
- else if (comp_value (mi.t))
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- 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< "
- + type + ", "
- + image_type + ", "
- + db_type + " >";
- }
if (!member_override_.empty ())
member = member_override_;
@@ -540,6 +527,65 @@ namespace mysql
os << "// " << name << endl
<< "//" << endl;
}
+
+ if (comp_value (mi.t))
+ traits = "composite_value_traits< " + mi.fq_type () + " >";
+ else
+ {
+ if (semantics::class_* c = object_pointer (mi.m, key_prefix_))
+ {
+ 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
+ << "bool is_null (ptr_traits::null_ptr (" << member << "));"
+ << "if (!is_null)"
+ << "{"
+ << "const " << type << "& id (" << endl
+ << "obj_traits::id (ptr_traits::get_ref (" << member << ")));"
+ << 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 + " >";
+ }
+ }
+
+ virtual void
+ post (member_info& mi)
+ {
+ if (container (mi.t))
+ return;
+
+ if (!comp_value (mi.t))
+ {
+ if (object_pointer (mi.m, key_prefix_))
+ os << "}";
+
+ os << "i." << mi.var << "null = is_null;"
+ << "}";
+ }
}
virtual void
@@ -555,23 +601,15 @@ namespace mysql
virtual void
traverse_integer (member_info& mi)
{
- os << "{"
- << "bool is_null;"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "null = is_null;"
- << "}";
+ os << traits << "::set_image (" << endl
+ << "i." << mi.var << "value, is_null, " << member << ");";
}
virtual void
traverse_float (member_info& mi)
{
- os << "{"
- << "bool is_null;"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "null = is_null;"
- << "}";
+ os << traits << "::set_image (" << endl
+ << "i." << mi.var << "value, is_null, " << member << ");";
}
virtual void
@@ -579,9 +617,7 @@ namespace mysql
{
// @@ Optimization: can remove growth check if buffer is fixed.
//
- os << "{"
- << "bool is_null;"
- << "std::size_t size;"
+ os << "std::size_t size;"
<< "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
<< "i." << mi.var << "value," << endl
@@ -589,20 +625,14 @@ namespace mysql
<< "is_null," << endl
<< member << ");"
<< "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "i." << mi.var << "null = is_null;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
- << "}";
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
virtual void
traverse_date_time (member_info& mi)
{
- os << "{"
- << "bool is_null;"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "null = is_null;"
- << "}";
+ os << traits << "::set_image (" << endl
+ << "i." << mi.var << "value, is_null, " << member << ");";
}
virtual void
@@ -610,9 +640,7 @@ namespace mysql
{
// @@ Optimization: can remove growth check if buffer is fixed.
//
- os << "{"
- << "bool is_null;"
- << "std::size_t size;"
+ os << "std::size_t size;"
<< "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
<< "i." << mi.var << "value," << endl
@@ -620,17 +648,13 @@ namespace mysql
<< "is_null," << endl
<< member << ");"
<< "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "i." << mi.var << "null = is_null;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
- << "}";
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
virtual void
traverse_long_string (member_info& mi)
{
- os << "{"
- << "bool is_null;"
- << "std::size_t size;"
+ os << "std::size_t size;"
<< "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
<< "i." << mi.var << "value," << endl
@@ -638,9 +662,7 @@ namespace mysql
<< "is_null," << endl
<< member << ");"
<< "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "i." << mi.var << "null = is_null;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
- << "}";
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
virtual void
@@ -648,18 +670,14 @@ namespace mysql
{
// Represented as a BLOB.
//
- os << "{"
- << "bool is_null;"
- << "std::size_t size;"
+ os << "std::size_t size;"
<< 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);"
- << "i." << mi.var << "null = is_null;"
- << "}";
+ << "i." << mi.var << "size = static_cast<unsigned long> (size);";
}
virtual void
@@ -667,9 +685,7 @@ namespace mysql
{
// Represented as a string.
//
- os << "{"
- << "bool is_null;"
- << "std::size_t size;"
+ os << "std::size_t size;"
<< "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
<< "i." << mi.var << "value," << endl
@@ -677,9 +693,7 @@ namespace mysql
<< "is_null," << endl
<< member << ");"
<< "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "i." << mi.var << "null = is_null;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
- << "}";
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
virtual void
@@ -687,9 +701,7 @@ namespace mysql
{
// Represented as a string.
//
- os << "{"
- << "bool is_null;"
- << "std::size_t size;"
+ os << "std::size_t size;"
<< "std::size_t cap (i." << mi.var << "value.capacity ());"
<< traits << "::set_image (" << endl
<< "i." << mi.var << "value," << endl
@@ -697,9 +709,7 @@ namespace mysql
<< "is_null," << endl
<< member << ");"
<< "i." << mi.var << "size = static_cast<unsigned long> (size);"
- << "i." << mi.var << "null = is_null;"
- << "grew = grew || (cap != i." << mi.var << "value.capacity ());"
- << "}";
+ << "grew = grew || (cap != i." << mi.var << "value.capacity ());";
}
private:
@@ -766,19 +776,6 @@ namespace mysql
{
if (container (mi.t))
return;
- else if (comp_value (mi.t))
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- 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< "
- + type + ", "
- + image_type + ", "
- + db_type + " >";
- }
if (!member_override_.empty ())
member = member_override_;
@@ -790,13 +787,75 @@ namespace mysql
os << "// " << name << endl
<< "//" << endl;
}
+
+ if (comp_value (mi.t))
+ traits = "composite_value_traits< " + mi.fq_type () + " >";
+ else
+ {
+ if (semantics::class_* c = object_pointer (mi.m, key_prefix_))
+ {
+ 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
+ << member << " = ptr_traits::pointer_type ();"
+ << "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 + " >";
+ }
+ }
+
+ virtual void
+ post (member_info& mi)
+ {
+ if (container (mi.t))
+ return;
+
+ if (!comp_value (mi.t) && object_pointer (mi.m, key_prefix_))
+ {
+ member = member_override_.empty ()
+ ? "o." + mi.m.name ()
+ : member_override_;
+
+ 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< obj_traits::object_type > (id));"
+ << "}"
+ << "}";
+ }
}
virtual void
traverse_composite (member_info& mi)
{
os << traits << "::init (" << member << ", i." <<
- mi.var << "value);"
+ mi.var << "value, db);"
<< endl;
}
@@ -924,7 +983,8 @@ namespace mysql
{
os << "// " << c.name () << " base" << endl
<< "//" << endl
- << "composite_value_traits< " << c.fq_name () << " >::init (o, i);"
+ << "composite_value_traits< " << c.fq_name () <<
+ " >::init (o, i, db);"
<< endl;
}
};
@@ -1232,8 +1292,10 @@ namespace mysql
size_t index (0);
os << "bool " << scope << "::" << endl
- << "grow (data_image_type&" << (grow ? " i" : "") << ", my_bool* e)"
+ << "grow (data_image_type& i, my_bool* e)"
<< "{"
+ << "ODB_POTENTIALLY_UNUSED (i);"
+ << endl
<< "bool r (false);"
<< endl;
@@ -1339,8 +1401,11 @@ namespace mysql
{
case ck_ordered:
{
- os << "init (index_type& j, value_type& v, const data_image_type& i)"
+ os << "init (index_type& j, value_type& v, " <<
+ "const data_image_type& i, database& db)"
<< "{"
+ << "ODB_POTENTIALLY_UNUSED (db);"
+ << endl
<< "// index" << endl
<< "//" << endl;
@@ -1353,8 +1418,11 @@ namespace mysql
case ck_map:
case ck_multimap:
{
- os << "init (key_type& k, value_type& v, const data_image_type& i)"
+ os << "init (key_type& k, value_type& v, " <<
+ "const data_image_type& i, database& db)"
<< "{"
+ << "ODB_POTENTIALLY_UNUSED (db);"
+ << endl
<< "// key" << endl
<< "//" << endl;
@@ -1366,8 +1434,11 @@ namespace mysql
case ck_set:
case ck_multiset:
{
- os << "init (value_type& v, const data_image_type& i)"
- << "{";
+ os << "init (value_type& v, const data_image_type& i, " <<
+ "database& db)"
+ << "{"
+ << "ODB_POTENTIALLY_UNUSED (db);"
+ << endl;
break;
}
}
@@ -1375,6 +1446,9 @@ namespace mysql
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);
@@ -1485,19 +1559,19 @@ namespace mysql
{
case ck_ordered:
{
- os << "init (i, v, di);";
+ os << "init (i, v, di, sts.connection ().database ());";
break;
}
case ck_map:
case ck_multimap:
{
- os << "init (k, v, di);";
+ os << "init (k, v, di, sts.connection ().database ());";
break;
}
case ck_set:
case ck_multiset:
{
- os << "init (v, di);";
+ os << "init (v, di, sts.connection ().database ());";
break;
}
}
@@ -1514,9 +1588,9 @@ namespace mysql
<< "{"
<< "if (grow (di, sts.data_image_error ()))"
<< "{"
- << "binding& db (sts.data_image_binding ());"
- << "bind (db.bind, 0, di);"
- << "db.version++;"
+ << "binding& b (sts.data_image_binding ());"
+ << "bind (b.bind, 0, di);"
+ << "b.version++;"
<< "st.refetch ();"
<< "}"
<< "}";
@@ -1589,8 +1663,15 @@ namespace mysql
<< "cb.version++;"
<< "}"
<< "select_statement& st (sts.select_all_statement ());"
- << "st.execute ();"
- << "select_statement::result r (st.fetch ());";
+ << "st.execute ();";
+
+ // If we are loading eager object pointers, cache the result
+ // since we will be loading other objects.
+ //
+ if (is_a (m, eager_pointer, vt, "value") || has_a (vt, eager_pointer))
+ os << "st.cache ();";
+
+ os << "select_statement::result r (st.fetch ());";
if (grow)
os << endl
@@ -1971,8 +2052,10 @@ namespace mysql
// grow ()
//
os << "bool " << traits << "::" << endl
- << "grow (image_type&" << (grow ? " i" : "") << ", my_bool* e)"
+ << "grow (image_type& i, my_bool* e)"
<< "{"
+ << "ODB_POTENTIALLY_UNUSED (i);"
+ << endl
<< "bool r (false);"
<< endl;
@@ -2023,8 +2106,10 @@ namespace mysql
// init (object, image)
//
os << "void " << traits << "::" << endl
- << "init (object_type& o, const image_type& i)"
- << "{";
+ << "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_);
@@ -2163,7 +2248,7 @@ namespace mysql
{
os << traits << "::pointer_type" << endl
<< traits << "::" << endl
- << "find (database&, const id_type& id)"
+ << "find (database& db, const id_type& id)"
<< "{"
<< "using namespace mysql;"
<< endl
@@ -2178,7 +2263,7 @@ namespace mysql
"pointer_type >::create ());"
<< "pointer_traits< pointer_type >::guard_type g (p);"
<< "object_type& obj (pointer_traits< pointer_type >::get_ref (p));"
- << "init (obj, sts.image ());";
+ << "init (obj, sts.image (), db);";
if (containers)
{
@@ -2197,7 +2282,7 @@ namespace mysql
}
os << "bool " << traits << "::" << endl
- << "find (database&, const id_type& id, object_type& obj)"
+ << "find (database& db, const id_type& id, object_type& obj)"
<< "{"
<< "using namespace mysql;"
<< endl
@@ -2208,7 +2293,7 @@ namespace mysql
<< "bool grew (false);"
<< "if (find (sts, id, grew))"
<< "{"
- << "init (obj, sts.image ());";
+ << "init (obj, sts.image (), db);";
if (containers)
{
@@ -2303,7 +2388,6 @@ namespace mysql
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 + " >");
@@ -2315,9 +2399,10 @@ namespace mysql
// grow ()
//
os << "bool " << traits << "::" << endl
- << "grow (image_type&" << (grow ? " i" : "") << ", " <<
- "my_bool*" << (columns ? " e" : "") << ")"
+ << "grow (image_type& i, my_bool*" << (columns ? " e" : "") << ")"
<< "{"
+ << "ODB_POTENTIALLY_UNUSED (i);"
+ << endl
<< "bool r (false);"
<< endl;
@@ -2360,8 +2445,11 @@ namespace mysql
//
os << "void " << traits << "::" << endl
<< "init (value_type&" << (columns ? " o" : "") << ", " <<
- "const image_type&" << (columns ? " i" : "") << ")"
- << "{";
+ "const image_type&" << (columns ? " i" : "") << ", " <<
+ "database& db)"
+ << "{"
+ << "ODB_POTENTIALLY_UNUSED (db);"
+ << endl;
inherits (c, init_value_base_inherits_);
names (c, init_value_member_names_);
@@ -2426,9 +2514,16 @@ namespace mysql
<< "#include <odb/mysql/exceptions.hxx>" << endl;
if (ctx.options.generate_query ())
- ctx.os << "#include <odb/mysql/result.hxx>" << endl
- << endl
- << "#include <odb/details/shared-ptr.hxx>" << endl;
+ 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;