summaryrefslogtreecommitdiff
path: root/odb/relational/source.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-04-25 15:02:43 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-04-25 15:02:43 +0200
commit1a6a0652a6ef5b319cfc8ad05a0acee6910f7560 (patch)
tree40605db91ed90c342a9074308bd7406008b4f10b /odb/relational/source.hxx
parent9c5b2f928699a6752d7c3d1a062bac7efc247c64 (diff)
Add support for abstract object types
Diffstat (limited to 'odb/relational/source.hxx')
-rw-r--r--odb/relational/source.hxx283
1 files changed, 150 insertions, 133 deletions
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index 5b2ec8d..9a23ca4 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -111,7 +111,7 @@ namespace relational
}
else
{
- semantics::data_member& id (id_member (*c));
+ semantics::data_member& id (*id_member (*c));
column (id, "",
table_name_.empty () ? table_name_ : table_qname (*c),
column_qname (id));
@@ -172,7 +172,7 @@ namespace relational
object_joins (semantics::class_& scope, bool query)
: query_ (query),
table_ (table_qname (scope)),
- id_ (id_member (scope))
+ id_ (*id_member (scope))
{
}
@@ -240,7 +240,7 @@ namespace relational
dt = ct;
string const& id (column_qname (*im, "id", "object_id"));
- dcond << dt << '.' << column_qname (id_member (*c)) << " = " <<
+ dcond << dt << '.' << column_qname (*id_member (*c)) << " = " <<
t << '.' << id;
}
}
@@ -259,7 +259,7 @@ namespace relational
//
t = table_qname (*c);
- cond << t << '.' << column_qname (id_member (*c)) << " = _." <<
+ cond << t << '.' << column_qname (*id_member (*c)) << " = _." <<
quote_id (col_name);
}
@@ -703,7 +703,7 @@ namespace relational
// many(i)-to-one
//
inv_table = table_qname (*c);
- inv_id = column_qname (id_member (*c));
+ inv_id = column_qname (*id_member (*c));
inv_fid = column_qname (*im);
}
@@ -873,8 +873,6 @@ namespace relational
// bind()
//
{
- instance<bind_member> bind_id ("id_", "id");
-
// bind (cond_image_type)
//
os << "void " << scope << "::" << endl
@@ -1795,160 +1793,57 @@ namespace relational
virtual void
traverse_object (type& c)
{
+ bool abst (abstract (c));
string const& type (c.fq_name ());
string traits ("access::object_traits< " + type + " >");
bool grow (context::grow (c));
- semantics::data_member& id (id_member (c));
- bool auto_id (id.count ("auto"));
- bool grow_id (context::grow (id));
- bool base_id (&id.scope () != &c); // Id comes from a base class.
+ semantics::data_member* id (id_member (c));
+ bool auto_id (id ? id->count ("auto") : false);
+ bool grow_id (id ? context::grow (*id) : false);
+ bool base_id (id ? &id->scope () != &c : false); // Comes from base.
os << "// " << c.name () << endl
<< "//" << endl
<< endl;
//
- // Containers.
- //
- bool straight_containers (has_a (c, test_straight_container));
- bool containers (straight_containers || has_a (c, test_container));
-
- // Statement cache (definition).
+ // Query.
//
- {
- os << "struct " << traits << "::container_statement_cache_type"
- << "{";
-
- instance<container_cache_members> cm;
- cm->traverse (c);
-
- os << (containers ? "\n" : "")
- << "container_statement_cache_type (" << db << "::connection&" <<
- (containers ? " c" : "") << ")";
-
- instance<container_cache_init_members> im;
- im->traverse (c);
-
- os << "{"
- << "}"
- << "};";
- }
-
- // Traits types.
- //
- if (containers)
- {
- instance<container_traits> t (c);
- t->traverse (c);
- }
- // query columns
- //
if (options.generate_query ())
{
instance<query_columns> t (c);
t->traverse (c);
}
- string const& table (table_qname (c));
- string const& id_col (column_qname (id));
-
- // persist_statement
//
- os << "const char* const " << traits << "::persist_statement =" << endl
- << strlit ("INSERT INTO " + table + " (") << endl;
-
- {
- instance<object_columns> t (false);
- t->traverse (c);
- }
-
- string values;
- for (size_t i (0), n (in_column_count (c)); i < n; ++i)
- values += i != 0 ? ",?" : "?";
-
- os << strlit (") VALUES (" + values + ")") << ";"
- << endl;
-
- // find_statement
- //
- os << "const char* const " << traits << "::find_statement =" << endl
- << strlit ("SELECT ") << endl;
-
- {
- instance<object_columns> t (table, true);
- t->traverse (c);
- }
-
- os << strlit (" FROM " + table + " AS _") << endl;
-
- {
- bool f (false);
- instance<object_joins> t (c, f); // @@ (im)perfect forwarding
- t->traverse (c);
- t->write ();
- }
-
- os << strlit (" WHERE _." + id_col + " = ?") << ";"
- << endl;
-
- // update_statement
+ // Containers (abstract and concrete).
//
- os << "const char* const " << traits << "::update_statement =" << endl
- << strlit ("UPDATE " + table + " SET ") << endl;
+ bool straight_containers (has_a (c, test_straight_container));
+ bool containers (straight_containers || has_a (c, test_container));
+ if (containers)
{
- instance<object_columns> t (false, true, " = ?");
+ instance<container_traits> t (c);
t->traverse (c);
}
- os << strlit (" WHERE " + id_col + " = ?") << ";"
- << endl;
-
- // erase_statement
//
- os << "const char* const " << traits << "::erase_statement =" << endl
- << strlit ("DELETE FROM " + table) << endl
- << strlit (" WHERE " + id_col + " = ?") << ";"
- << endl;
-
- // query_clause
+ // Functions (abstract and concrete).
//
- if (options.generate_query ())
- {
- bool t (true);
- instance<object_joins> oj (c, t); //@@ (im)perfect forwarding
- oj->traverse (c);
-
- // We only need DISTINCT if there are joins (object pointers)
- // and can optimize it out otherwise.
- //
- os << "const char* const " << traits << "::query_clause =" << endl
- << strlit (oj->count () ? "SELECT DISTINCT " : "SELECT ") << endl;
-
- {
- instance<object_columns> oc (table, true);
- oc->traverse (c);
- }
-
- os << strlit (" FROM " + table + " AS _") << endl;
- oj->write ();
- os << strlit (" ") << ";"
- << endl;
- }
// id (image_type)
//
- if (options.generate_query () && !base_id)
+ if (id != 0 && options.generate_query () && !base_id)
{
os << traits << "::id_type" << endl
<< traits << "::" << endl
<< "id (const image_type& i)"
<< "{"
<< "id_type id;";
- init_id_value_member_->traverse (id);
+ init_id_value_member_->traverse (*id);
os << "return id;"
<< "}";
}
@@ -1988,13 +1883,13 @@ namespace relational
// bind (id_image_type)
//
- if (!base_id)
+ if (id != 0 && !base_id)
{
os << "void " << traits << "::" << endl
<< "bind (" << bind_vector << " b, id_image_type& i)"
<< "{"
<< "std::size_t n (0);";
- bind_id_member_->traverse (id);
+ bind_id_member_->traverse (*id);
os << "}";
}
@@ -2032,7 +1927,7 @@ namespace relational
// init (id_image, id)
//
- if (!base_id)
+ if (id != 0 && !base_id)
{
os << "void " << traits << "::" << endl
<< "init (id_image_type& i, const id_type& id)"
@@ -2041,7 +1936,7 @@ namespace relational
if (grow_id)
os << "bool grew (false);";
- init_id_image_member_->traverse (id);
+ init_id_image_member_->traverse (*id);
if (grow_id)
os << endl
@@ -2051,6 +1946,128 @@ namespace relational
os << "}";
}
+ //
+ // The rest only applies to concrete objects.
+ //
+ if (abst)
+ return;
+
+ //
+ // Containers (concrete).
+ //
+
+ // Statement cache (definition).
+ //
+ {
+ os << "struct " << traits << "::container_statement_cache_type"
+ << "{";
+
+ instance<container_cache_members> cm;
+ cm->traverse (c);
+
+ os << (containers ? "\n" : "")
+ << "container_statement_cache_type (" << db << "::connection&" <<
+ (containers ? " c" : "") << ")";
+
+ instance<container_cache_init_members> im;
+ im->traverse (c);
+
+ os << "{"
+ << "}"
+ << "};";
+ }
+
+ //
+ // Statements.
+ //
+
+ string const& table (table_qname (c));
+ string const& id_col (column_qname (*id));
+
+ // persist_statement
+ //
+ os << "const char* const " << traits << "::persist_statement =" << endl
+ << strlit ("INSERT INTO " + table + " (") << endl;
+
+ {
+ instance<object_columns> t (false);
+ t->traverse (c);
+ }
+
+ string values;
+ for (size_t i (0), n (in_column_count (c)); i < n; ++i)
+ values += i != 0 ? ",?" : "?";
+
+ os << strlit (") VALUES (" + values + ")") << ";"
+ << endl;
+
+ // find_statement
+ //
+ os << "const char* const " << traits << "::find_statement =" << endl
+ << strlit ("SELECT ") << endl;
+
+ {
+ instance<object_columns> t (table, true);
+ t->traverse (c);
+ }
+
+ os << strlit (" FROM " + table + " AS _") << endl;
+
+ {
+ bool f (false);
+ instance<object_joins> t (c, f); // @@ (im)perfect forwarding
+ t->traverse (c);
+ t->write ();
+ }
+
+ os << strlit (" WHERE _." + id_col + " = ?") << ";"
+ << endl;
+
+ // update_statement
+ //
+ os << "const char* const " << traits << "::update_statement =" << endl
+ << strlit ("UPDATE " + table + " SET ") << endl;
+
+ {
+ instance<object_columns> t (false, true, " = ?");
+ t->traverse (c);
+ }
+
+ os << strlit (" WHERE " + id_col + " = ?") << ";"
+ << endl;
+
+ // erase_statement
+ //
+ os << "const char* const " << traits << "::erase_statement =" << endl
+ << strlit ("DELETE FROM " + table) << endl
+ << strlit (" WHERE " + id_col + " = ?") << ";"
+ << endl;
+
+ // query_clause
+ //
+ if (options.generate_query ())
+ {
+ bool t (true);
+ instance<object_joins> oj (c, t); //@@ (im)perfect forwarding
+ oj->traverse (c);
+
+ // We only need DISTINCT if there are joins (object pointers)
+ // and can optimize it out otherwise.
+ //
+ os << "const char* const " << traits << "::query_clause =" << endl
+ << strlit (oj->count () ? "SELECT DISTINCT " : "SELECT ") << endl;
+
+ {
+ instance<object_columns> oc (table, true);
+ oc->traverse (c);
+ }
+
+ os << strlit (" FROM " + table + " AS _") << endl;
+ oj->write ();
+ os << strlit (" ") << ";"
+ << endl;
+ }
+
// persist ()
//
os << "void " << traits << "::" << endl
@@ -2072,9 +2089,9 @@ namespace relational
if (auto_id)
{
- string const& n (id.name ());
+ string const& n (id->name ());
string var ("im." + n + (n[n.size () - 1] == '_' ? "" : "_"));
- init_auto_id (id, var);
+ init_auto_id (*id, var);
os << endl;
}
@@ -2090,7 +2107,7 @@ namespace relational
<< 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 (straight_containers)
@@ -2098,7 +2115,7 @@ namespace relational
// Initialize id_image and binding.
//
os << "id_image_type& i (sts.id_image ());"
- << "init (i, obj." << id.name () << ");"
+ << "init (i, obj." << id->name () << ");"
<< endl
<< "binding& idb (sts.id_image_binding ());"
<< "if (i.version != sts.id_image_version () || idb.version == 0)"
@@ -2130,7 +2147,7 @@ namespace relational
// Initialize id image.
//
os << "id_image_type& i (sts.id_image ());"
- << "init (i, obj." << id.name () << ");"
+ << "init (i, obj." << id->name () << ");"
<< endl;
os << "binding& idb (sts.id_image_binding ());"