aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-06-21 10:33:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-06-21 11:25:15 +0200
commit8c31ee59d95356cb111bab1853eac3b35b451f01 (patch)
tree00d62089c7ea3e39f7e9d4968517a51562483036
parent0efbd383bf4b9d6c1a884ff0249412567b329fce (diff)
Various bug fixes for dynamic multi-database support2.2.22.2
-rw-r--r--odb/common-query.cxx103
-rw-r--r--odb/common-query.hxx10
-rw-r--r--odb/generate.hxx2
-rw-r--r--odb/generator.cxx26
-rw-r--r--odb/include.cxx10
5 files changed, 102 insertions, 49 deletions
diff --git a/odb/common-query.cxx b/odb/common-query.cxx
index 68fcb21..9697486 100644
--- a/odb/common-query.cxx
+++ b/odb/common-query.cxx
@@ -336,23 +336,23 @@ generate_inst (semantics::data_member& m, semantics::class_& c)
string name (public_name (m));
string const& fq_name (class_fq_name (c));
- // If the pointed-to class has no pointers of its own then
- // pointer_query_columns just derives from query_columns and
- // that's what we need to instantiate.
- //
- bool has_ptr (has_a (c, test_pointer | include_base));
string alias (scope_ + "::" + name + "_alias_");
// Instantiate base [pointer_]query_columns.
//
{
- instance<query_columns_base_insts> b (has_ptr, inst_, alias);
+ instance<query_columns_base_insts> b (true, inst_, alias, true);
traversal::inherits i (*b);
inherits (c, i);
}
+ // If the pointed-to class has no pointers of its own then
+ // pointer_query_columns just derives from query_columns and
+ // that's what we need to instantiate.
+ //
inst_header (inst_);
- os << (has_ptr ? "pointer_" : "") << "query_columns<" << endl
+ os << (has_a (c, test_pointer | include_base) ? "pointer_" : "") <<
+ "query_columns<" << endl
<< " " << fq_name << "," << endl
<< " id_" << db << "," << endl
<< " " << alias << " >;"
@@ -486,9 +486,14 @@ bool query_columns::
traverse_column (semantics::data_member& m, string const& column, bool)
{
semantics::names* hint;
- semantics::type& t (utype (m, hint));
+ semantics::type* t (&utype (m, hint));
- column_common (m, t.fq_name (hint), column);
+ // Unwrap it if it is a wrapper.
+ //
+ if (semantics::type* wt = wrapper (*t, hint))
+ t = &utype (*wt, hint);
+
+ column_common (m, t->fq_name (hint), column);
if (decl_)
{
@@ -685,8 +690,11 @@ traverse (type& c)
//
query_columns_base_insts::
-query_columns_base_insts (bool ptr, bool decl, string const& alias)
- : ptr_ (ptr), decl_ (decl), alias_ (alias)
+query_columns_base_insts (bool test_ptr,
+ bool decl,
+ string const& alias,
+ bool poly)
+ : test_ptr_ (test_ptr), decl_ (decl), alias_ (alias), poly_ (poly)
{
*this >> inherits_ >> *this;
}
@@ -694,7 +702,10 @@ query_columns_base_insts (bool ptr, bool decl, string const& alias)
query_columns_base_insts::
query_columns_base_insts (query_columns_base_insts const& x)
: context (), // @@ -Wextra
- ptr_ (x.ptr_), decl_ (x.decl_), alias_ (x.alias_)
+ test_ptr_ (x.test_ptr_),
+ decl_ (x.decl_),
+ alias_ (x.alias_),
+ poly_ (x.poly_)
{
*this >> inherits_ >> *this;
}
@@ -702,21 +713,46 @@ query_columns_base_insts (query_columns_base_insts const& x)
void query_columns_base_insts::
traverse (type& c)
{
- // We are only interested in reuse inheritance.
- //
- if (!object (c) || polymorphic (c))
+ if (!object (c))
+ return;
+
+ bool poly (polymorphic (c));
+ if (poly && (poly != poly_))
return;
+ bool ptr (has_a (c, test_pointer | include_base));
+
+ string old_alias;
+ if (poly)
+ {
+ old_alias = alias_;
+ alias_ += "::base_traits";
+ }
+
// Instantiate bases recursively.
//
inherits (c, inherits_);
inst_header (decl_);
- os << (ptr_ ? "pointer_query_columns" : "query_columns") << "<" << endl
+ os << (test_ptr_ && ptr ? "pointer_query_columns" : "query_columns") <<
+ "<" << endl
<< " " << class_fq_name (c) << "," << endl
<< " id_" << db << "," << endl
<< " " << alias_ << " >;"
<< endl;
+
+ if (!test_ptr_ && ptr)
+ {
+ inst_header (decl_);
+ os << "pointer_query_columns<" << endl
+ << " " << class_fq_name (c) << "," << endl
+ << " id_" << db << "," << endl
+ << " " << alias_ << " >;"
+ << endl;
+ }
+
+ if (poly)
+ alias_ = old_alias;
}
// query_columns_type
@@ -940,13 +976,16 @@ generate_inst (type& c)
//
// 3. The query_columns class for the table itself.
//
+ // We also need to repeat these steps for pointer_query_columns
+ // since it is used by views.
+ //
string alias ("access::object_traits_impl< " + type + ", id_" +
db.string () + " >");
// 1
//
{
- instance<query_columns_base_insts> b (false, inst_, alias);
+ instance<query_columns_base_insts> b (false, inst_, alias, false);
traversal::inherits i (*b);
inherits (c, i);
}
@@ -963,6 +1002,16 @@ generate_inst (type& c)
<< " id_" << db << "," << endl
<< " " << alias << " >;"
<< endl;
+
+ if (has_a (c, test_pointer | exclude_base))
+ {
+ inst_header (inst_);
+ os << "pointer_query_columns<" << endl
+ << " " << type << "," << endl
+ << " id_" << db << "," << endl
+ << " " << alias << " >;"
+ << endl;
+ }
}
// view_query_columns_type
@@ -1172,7 +1221,7 @@ generate_inst (type& c)
continue; // Skip tables.
if (i->alias.empty ())
- continue;
+ continue; // Instantiated by object.
semantics::class_& o (*i->obj);
qname const& t (table_name (o));
@@ -1183,32 +1232,26 @@ generate_inst (type& c)
//
if (polymorphic (o) || t.qualified () || i->alias != t.uname ())
{
-
string const& otype (class_fq_name (o));
-
- // If the pointed-to class has no pointers of its own then
- // pointer_query_columns just derives from query_columns and
- // that's what we need to instantiate.
- //
- bool has_ptr (has_a (o, test_pointer | include_base));
-
string alias ("odb::alias_traits<\n"
" " + otype + ",\n"
" id_" + db.string () + ",\n"
" " + traits + "::" + i->alias + "_tag>");
-
-
// Instantiate base [pointer_]query_columns.
//
{
- instance<query_columns_base_insts> b (has_ptr, decl_, alias);
+ instance<query_columns_base_insts> b (true, decl_, alias, true);
traversal::inherits i (*b);
inherits (o, i);
}
+ // If the pointed-to class has no pointers of its own then
+ // pointer_query_columns just derives from query_columns and
+ // that's what we need to instantiate.
+ //
inst_header (decl_);
- os << (has_ptr ? "pointer_" : "") <<
+ os << (has_a (o, test_pointer | include_base) ? "pointer_" : "") <<
"query_columns<" << endl
<< " " << otype << "," << endl
<< " id_" << db << "," << endl
diff --git a/odb/common-query.hxx b/odb/common-query.hxx
index 5a07c86..b340b9f 100644
--- a/odb/common-query.hxx
+++ b/odb/common-query.hxx
@@ -177,22 +177,26 @@ private:
bool ptr_;
};
-// Generate explicit instantiations of base classes (reuse inheritance).
+// Generate explicit instantiations of base classes.
//
struct query_columns_base_insts: traversal::class_, virtual context
{
typedef query_columns_base_insts base;
- query_columns_base_insts (bool ptr, bool decl, string const& alias);
+ query_columns_base_insts (bool test_ptr,
+ bool decl,
+ string const& alias,
+ bool poly); // Traverse polymorphic bases.
query_columns_base_insts (query_columns_base_insts const&);
virtual void
traverse (type&);
private:
- bool ptr_;
+ bool test_ptr_;
bool decl_;
string alias_;
+ bool poly_;
traversal::inherits inherits_;
};
diff --git a/odb/generate.hxx b/odb/generate.hxx
index f846bf4..92c6336 100644
--- a/odb/generate.hxx
+++ b/odb/generate.hxx
@@ -7,7 +7,7 @@
namespace include
{
- void
+ bool
generate (bool header);
}
diff --git a/odb/generator.cxx b/odb/generator.cxx
index 4af66c4..ed37964 100644
--- a/odb/generator.cxx
+++ b/odb/generator.cxx
@@ -321,19 +321,21 @@ generate (options const& ops,
for (paths::const_iterator i (inputs.begin ()); i != inputs.end (); ++i)
hxx << "#include " <<
ctx->process_include_path (i->leaf ().string ()) << endl;
+
hxx << endl;
+ // There are no -odb.hxx includes if we are generating code for
+ // everything.
+ //
+ if (!ops.at_once ())
+ if (include::generate (true))
+ hxx << endl;
+
{
// We don't want to indent prologues/epilogues.
//
ind_filter ind (ctx->os);
- // There are no -odb.hxx includes if we are generating code for
- // everything.
- //
- if (!ops.at_once ())
- include::generate (true);
-
switch (db)
{
case database::common:
@@ -526,6 +528,12 @@ generate (options const& ops,
cxx << "#include " << ctx->process_include_path (hxx_name) << endl;
+ // There are no -odb.hxx includes if we are generating code for
+ // everything.
+ //
+ if (!ops.at_once ())
+ include::generate (false);
+
if (!impl_guard.empty ())
cxx << "#undef " << impl_guard << endl;
@@ -536,12 +544,6 @@ generate (options const& ops,
//
ind_filter ind (ctx->os);
- // There are no -odb.hxx includes if we are generating code for
- // everything.
- //
- if (!ops.at_once ())
- include::generate (false);
-
switch (db)
{
case database::common:
diff --git a/odb/include.cxx b/odb/include.cxx
index 152cee8..a6e8c53 100644
--- a/odb/include.cxx
+++ b/odb/include.cxx
@@ -486,9 +486,11 @@ namespace
namespace include
{
- void
+ bool
generate (bool header)
{
+ bool r (false);
+
// We do the same include directive collection and processing
// twice, once for the header file and once for the source file.
// If that proves to be too slow, we will need to do it only once
@@ -695,8 +697,10 @@ namespace include
char o (inc->type_ == include_directive::quote ? '"' : '<');
ctx.os << "#include " << ctx.process_include_path (
- f.string (), false, o) << endl
- << endl;
+ f.string (), false, o) << endl;
+ r = true;
}
+
+ return r;
}
}