summaryrefslogtreecommitdiff
path: root/odb/relational
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational')
-rw-r--r--odb/relational/header.hxx145
-rw-r--r--odb/relational/inline.hxx55
-rw-r--r--odb/relational/mysql/context.cxx7
-rw-r--r--odb/relational/pgsql/source.cxx4
-rw-r--r--odb/relational/source.hxx257
-rw-r--r--odb/relational/type-processor.cxx8
6 files changed, 404 insertions, 72 deletions
diff --git a/odb/relational/header.hxx b/odb/relational/header.hxx
index 69f7977..f7e1058 100644
--- a/odb/relational/header.hxx
+++ b/odb/relational/header.hxx
@@ -46,7 +46,7 @@ namespace relational
{
bool obj (object (c));
- // Ignore transient bases.
+ // Ignore transient bases. Not used for views.
//
if (!(obj || composite (c)))
return;
@@ -92,6 +92,7 @@ namespace relational
{
os << "struct image_type";
+ if (!view (c))
{
instance<image_base> b;
traversal::inherits i (*b);
@@ -126,7 +127,7 @@ namespace relational
virtual void
traverse (type& c)
{
- // Ignore transient bases.
+ // Ignore transient bases. Not used for views.
//
if (!object (c))
return;
@@ -224,7 +225,7 @@ namespace relational
if (object (c_))
{
- base = cur_object != &c_ ||
+ base = cur_object != &c_ ||
!object (dynamic_cast<type&> (m.scope ()));
abst = abstract (c_);
}
@@ -754,6 +755,8 @@ namespace relational
if (object (c))
traverse_object (c);
+ else if (view (c))
+ traverse_view (c);
else if (composite (c))
traverse_composite (c);
}
@@ -782,6 +785,12 @@ namespace relational
<< "//" << endl;
os << "template <>" << endl
+ << "struct class_traits< " << type << " >"
+ << "{"
+ << "static const class_kind kind = class_object;"
+ << "};";
+
+ os << "template <>" << endl
<< "class access::object_traits< " << type << " >"
<< "{"
<< "public:" << endl;
@@ -1073,6 +1082,124 @@ namespace relational
}
virtual void
+ view_public_extra_pre (type&)
+ {
+ }
+
+ virtual void
+ view_public_extra_post (type&)
+ {
+ }
+
+ virtual void
+ traverse_view (type& c)
+ {
+ string const& type (c.fq_name ());
+
+ os << "// " << c.name () << endl
+ << "//" << endl;
+
+ os << "template <>" << endl
+ << "struct class_traits< " << type << " >"
+ << "{"
+ << "static const class_kind kind = class_view;"
+ << "};";
+
+ os << "template <>" << endl
+ << "class access::view_traits< " << type << " >"
+ << "{"
+ << "public:" << endl;
+
+ view_public_extra_pre (c);
+
+ // view_type & pointer_type
+ //
+ os << "typedef " << type << " view_type;"
+ << "typedef " << c.get<string> ("object-pointer") << " pointer_type;"
+ << endl;
+
+ // image_type
+ //
+ image_type_->traverse (c);
+
+ //
+ // Query.
+ //
+
+ // query_base_type
+ //
+ os << "typedef " << db << "::query query_base_type;"
+ << endl;
+
+ // query_type
+ //
+ os << "typedef query_base_type query_type;"
+ << endl;
+
+ /*
+ os << "struct query_type: query_base_type, query_columns"
+ << "{"
+ << "query_type ();"
+ << "query_type (const std::string&);"
+ << "query_type (const query_base_type&);"
+ << "};";
+ */
+
+ //
+ // Functions.
+ //
+
+ // grow ()
+ //
+ os << "static bool" << endl
+ << "grow (image_type&, " << truncated_vector << ");"
+ << endl;
+
+ // bind (image_type)
+ //
+ os << "static void" << endl
+ << "bind (" << bind_vector << ", image_type&);"
+ << endl;
+
+ // init (view, image)
+ //
+ os << "static void" << endl
+ << "init (view_type&, const image_type&);"
+ << endl;
+
+ // column_count
+ //
+ os << "static const std::size_t column_count = " <<
+ out_column_count (c) << "UL;"
+ << endl;
+
+ // Statements.
+ //
+ os << "static const char* const query_statement;"
+ << endl;
+
+ //
+ // Functions.
+ //
+
+ // callback ()
+ //
+ os << "static void" << endl
+ << "callback (database&, view_type&, callback_event);"
+ << endl;
+
+ // query ()
+ //
+ os << "static result<view_type>" << endl
+ << "query (database&, const query_type&);"
+ << endl;
+
+ view_public_extra_post (c);
+
+ os << "};";
+ }
+
+ virtual void
traverse_composite (type& c)
{
string const& type (c.fq_name ());
@@ -1081,11 +1208,17 @@ namespace relational
<< "//" << endl;
os << "template <>" << endl
+ << "struct class_traits< " << type << " >"
+ << "{"
+ << "static const class_kind kind = class_composite;"
+ << "};";
+
+ os << "template <>" << endl
<< "class access::composite_value_traits< " << type << " >"
<< "{"
<< "public:" << endl;
- // object_type
+ // value_type
//
os << "typedef " << type << " value_type;"
<< endl;
@@ -1113,13 +1246,13 @@ namespace relational
<< "bind (" << bind_vector << ", image_type&);"
<< endl;
- // init (image, object)
+ // init (image, value)
//
os << "static bool" << endl
<< "init (image_type&, const value_type&);"
<< endl;
- // init (object, image)
+ // init (value, image)
//
os << "static void" << endl
<< "init (value_type&, const image_type&, database&);"
diff --git a/odb/relational/inline.hxx b/odb/relational/inline.hxx
index 311640e..1134df6 100644
--- a/odb/relational/inline.hxx
+++ b/odb/relational/inline.hxx
@@ -41,29 +41,31 @@ namespace relational
virtual void
traverse (type& c)
{
+ bool obj (object (c));
+
// Ignore transient bases.
//
- if (!object (c))
+ if (!(obj || view (c)))
return;
if (c.count ("callback"))
{
string name (c.get<string> ("callback"));
- // In case of the const object, we only generate the call if
+ // In case of the const instance, we only generate the call if
// there is a const callback.
//
if (const_)
{
if (c.count ("callback-const"))
- os << "static_cast< const " << c.fq_name () << "& > (obj)." <<
+ os << "static_cast< const " << c.fq_name () << "& > (x)." <<
name << " (e, db);";
}
else
- os << "static_cast< " << c.fq_name () << "& > (obj)." <<
+ os << "static_cast< " << c.fq_name () << "& > (x)." <<
name << " (e, db);";
}
- else
+ else if (obj)
inherits (c);
}
@@ -86,6 +88,8 @@ namespace relational
if (object (c))
traverse_object (c);
+ if (view (c))
+ traverse_view (c);
else if (composite (c))
traverse_composite (c);
}
@@ -178,11 +182,11 @@ namespace relational
//
os << "inline" << endl
<< "void " << traits << "::" << endl
- << "callback (database& db, object_type& obj, callback_event e)"
+ << "callback (database& db, object_type& x, callback_event e)"
<< endl
<< "{"
<< "ODB_POTENTIALLY_UNUSED (db);"
- << "ODB_POTENTIALLY_UNUSED (obj);"
+ << "ODB_POTENTIALLY_UNUSED (x);"
<< "ODB_POTENTIALLY_UNUSED (e);"
<< endl;
callback_calls_->traverse (c, false);
@@ -190,11 +194,10 @@ namespace relational
os << "inline" << endl
<< "void " << traits << "::" << endl
- << "callback (database& db, const object_type& obj, " <<
- "callback_event e)"
+ << "callback (database& db, const object_type& x, callback_event e)"
<< "{"
<< "ODB_POTENTIALLY_UNUSED (db);"
- << "ODB_POTENTIALLY_UNUSED (obj);"
+ << "ODB_POTENTIALLY_UNUSED (x);"
<< "ODB_POTENTIALLY_UNUSED (e);"
<< endl;
callback_calls_->traverse (c, true);
@@ -239,6 +242,38 @@ namespace relational
}
virtual void
+ view_extra (type&)
+ {
+ }
+
+ virtual void
+ traverse_view (type& c)
+ {
+ string const& type (c.fq_name ());
+ string traits ("access::view_traits< " + type + " >");
+
+ os << "// " << c.name () << endl
+ << "//" << endl
+ << endl;
+
+ view_extra (c);
+
+ // callback ()
+ //
+ os << "inline" << endl
+ << "void " << traits << "::" << endl
+ << "callback (database& db, view_type& x, callback_event e)"
+ << endl
+ << "{"
+ << "ODB_POTENTIALLY_UNUSED (db);"
+ << "ODB_POTENTIALLY_UNUSED (x);"
+ << "ODB_POTENTIALLY_UNUSED (e);"
+ << endl;
+ callback_calls_->traverse (c, false);
+ os << "}";
+ }
+
+ virtual void
traverse_composite (type&)
{
/*
diff --git a/odb/relational/mysql/context.cxx b/odb/relational/mysql/context.cxx
index ccd1861..59b93ba 100644
--- a/odb/relational/mysql/context.cxx
+++ b/odb/relational/mysql/context.cxx
@@ -122,9 +122,11 @@ namespace relational
virtual void
traverse (type& c)
{
+ bool view (context::view (c));
+
// Ignore transient bases.
//
- if (!(context::object (c) || context::composite (c)))
+ if (!(context::object (c) || view || context::composite (c)))
return;
if (c.count ("mysql-grow"))
@@ -133,7 +135,8 @@ namespace relational
{
// r_ should be false.
//
- inherits (c);
+ if (!view)
+ inherits (c);
if (!r_)
names (c);
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index b869520..da9d0d7 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -969,7 +969,7 @@ namespace relational
}
virtual void
- query_statement_ctor_args (type&)
+ object_query_statement_ctor_args (type&)
{
os << "sts.connection ()," << endl
<< "query_statement_name," << endl
@@ -981,7 +981,7 @@ namespace relational
}
virtual void
- erase_query_statement_ctor_args (type&)
+ object_erase_query_statement_ctor_args (type&)
{
os << "conn," << endl
<< "erase_query_statement_name," << endl
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index d9cf66f..a3ef5de 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -404,7 +404,7 @@ namespace relational
{
bool obj (object (c));
- // Ignore transient bases.
+ // Ignore transient bases. Not used for views.
//
if (!(obj || composite (c)))
return;
@@ -461,7 +461,7 @@ namespace relational
{
bool obj (object (c));
- // Ignore transient bases.
+ // Ignore transient bases. Not used for views.
//
if (!(obj || composite (c)))
return;
@@ -519,7 +519,7 @@ namespace relational
{
bool obj (object (c));
- // Ignore transient bases.
+ // Ignore transient bases. Not used for views.
//
if (!(obj || composite (c)))
return;
@@ -570,7 +570,7 @@ namespace relational
{
bool obj (object (c));
- // Ignore transient bases.
+ // Ignore transient bases. Not used for views.
//
if (!(obj || composite (c)))
return;
@@ -689,8 +689,13 @@ namespace relational
grow = grow || context::grow (m, vt, "value");
- bool eager_ptr (is_a (m, test_eager_pointer, vt, "value") ||
- has_a (vt, test_eager_pointer));
+ bool eager_ptr (is_a (m, test_eager_pointer, vt, "value"));
+
+ if (!eager_ptr)
+ {
+ if (semantics::class_* cvt = composite_wrapper (vt))
+ eager_ptr = has_a (*cvt, test_eager_pointer);
+ }
string name (prefix_ + public_name (m) + "_traits");
string scope (scope_ + "::" + name);
@@ -1902,17 +1907,32 @@ namespace relational
if (object (c))
traverse_object (c);
+ else if (view (c))
+ traverse_view (c);
else if (composite (c))
traverse_composite (c);
}
+ //
+ // common
+ //
+
+ virtual void
+ post_query_ (type&)
+ {
+ }
+
+ //
+ // object
+ //
+
virtual void
object_extra (type&)
{
}
virtual void
- query_statement_ctor_args (type&)
+ object_query_statement_ctor_args (type&)
{
os << "sts.connection ()," << endl
<< "query_clause + q.clause (table_name)," << endl
@@ -1921,7 +1941,7 @@ namespace relational
}
virtual void
- erase_query_statement_ctor_args (type&)
+ object_erase_query_statement_ctor_args (type&)
{
os << "conn," << endl
<< "erase_query_clause + q.clause (table_name)," << endl
@@ -1929,11 +1949,6 @@ namespace relational
}
virtual void
- post_query_ (type&)
- {
- }
-
- virtual void
traverse_object (type& c)
{
bool abst (abstract (c));
@@ -2249,10 +2264,10 @@ namespace relational
<< "{"
<< "using namespace " << db << ";"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
+ << "conn.statement_cache ().find_object<object_type> ());"
<< "image_type& im (sts.image ());"
<< "binding& imb (sts.in_image_binding ());"
<< endl
@@ -2311,10 +2326,10 @@ namespace relational
<< "{"
<< "using namespace " << db << ";"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
+ << "conn.statement_cache ().find_object<object_type> ());"
<< endl;
// Initialize id image.
@@ -2363,10 +2378,10 @@ namespace relational
<< "{"
<< "using namespace " << db << ";"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
+ << "conn.statement_cache ().find_object<object_type> ());"
<< endl;
// Initialize id image.
@@ -2410,10 +2425,10 @@ namespace relational
<< "{"
<< "using namespace " << db << ";"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
+ << "conn.statement_cache ().find_object<object_type> ());"
<< "object_statements< object_type >::auto_lock l (sts);"
<< endl
<< "if (l.locked ())"
@@ -2452,10 +2467,10 @@ namespace relational
<< "{"
<< "using namespace " << db << ";"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
+ << "conn.statement_cache ().find_object<object_type> ());"
<< "object_statements< object_type >::auto_lock l (sts);"
<< endl
<< "if (l.locked ())"
@@ -2568,19 +2583,24 @@ namespace relational
<< "const query_type& q)"
<< "{"
<< "using namespace " << db << ";"
+ << "using odb::details::shared;"
+ << "using odb::details::shared_ptr;"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< endl
<< "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << "odb::details::shared_ptr<select_statement> st;"
+ << "conn.statement_cache ().find_object<object_type> ());"
+ << "shared_ptr<select_statement> st;"
<< endl
<< "query_ (db, q, sts, st);"
<< endl
- << "odb::details::shared_ptr<odb::result_impl<object_type> > r (" << endl
- << "new (odb::details::shared) " << db <<
- "::result_impl<object_type> (q, st, sts));"
+ << "shared_ptr<odb::result_impl<object_type, " <<
+ "class_object> > r (" << endl
+ << "new (shared) " << db <<
+ "::result_impl<object_type, class_object> (" << endl
+ << "q, st, sts));"
+ << endl
<< "return result<object_type> (r);"
<< "}";
@@ -2592,19 +2612,24 @@ namespace relational
<< "const query_type& q)"
<< "{"
<< "using namespace " << db << ";"
+ << "using odb::details::shared;"
+ << "using odb::details::shared_ptr;"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< endl
<< "object_statements< object_type >& sts (" << endl
- << "conn.statement_cache ().find<object_type> ());"
- << "odb::details::shared_ptr<select_statement> st;"
+ << "conn.statement_cache ().find_object<object_type> ());"
+ << "shared_ptr<select_statement> st;"
<< endl
<< "query_ (db, q, sts, st);"
<< endl
- << "odb::details::shared_ptr<odb::result_impl<const object_type> > r (" << endl
- << "new (odb::details::shared) " << db <<
- "::result_impl<const object_type> (q, st, sts));"
+ << "shared_ptr<odb::result_impl<" <<
+ "const object_type, class_object> > r (" << endl
+ << "new (shared) " << db <<
+ "::result_impl<const object_type, class_object> (" << endl
+ << "q, st, sts));"
+ << endl
<< "return result<const object_type> (r);"
<< "}";
@@ -2628,7 +2653,7 @@ namespace relational
<< "st.reset (new (odb::details::shared) select_statement ("
<< endl;
- query_statement_ctor_args (c);
+ object_query_statement_ctor_args (c);
os << "));" << endl
<< "st->execute ();";
@@ -2644,12 +2669,12 @@ namespace relational
<< "{"
<< "using namespace " << db << ";"
<< endl
- << db << "::connection& conn (" << db <<
- "::transaction::current ().connection ());"
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
<< endl
<< "delete_statement st (" << endl;
- erase_query_statement_ctor_args (c);
+ object_erase_query_statement_ctor_args (c);
os << ");"
<< endl
@@ -2811,6 +2836,142 @@ namespace relational
<< endl;
}
+ //
+ // view
+ //
+
+ virtual void
+ view_extra (type&)
+ {
+ }
+
+ virtual void
+ view_query_statement_ctor_args (type&)
+ {
+ os << "sts.connection ()," << endl
+ << "query_statement + q.clause (\"\")," << endl
+ << "q.parameters_binding ()," << endl
+ << "imb";
+ }
+
+ virtual void
+ traverse_view (type& c)
+ {
+ string const& type (c.fq_name ());
+ string traits ("access::view_traits< " + type + " >");
+
+ os << "// " << c.name () << endl
+ << "//" << endl
+ << endl;
+
+ view_extra (c);
+
+ //
+ // Functions.
+ //
+
+ // grow ()
+ //
+ os << "bool " << traits << "::" << endl
+ << "grow (image_type& i, " << truncated_vector << " t)"
+ << "{"
+ << "ODB_POTENTIALLY_UNUSED (i);"
+ << "ODB_POTENTIALLY_UNUSED (t);"
+ << endl
+ << "bool grew (false);"
+ << endl;
+
+ index_ = 0;
+ names (c, grow_member_names_);
+
+ os << "return grew;"
+ << "}";
+
+ // bind (image_type)
+ //
+ os << "void " << traits << "::" << endl
+ << "bind (" << bind_vector << " b, image_type& i)"
+ << "{"
+ << "bool out (true);" //@@ Try to get rid of this.
+ << "ODB_POTENTIALLY_UNUSED (out);"
+ << endl
+ << "std::size_t n (0);"
+ << endl;
+
+ names (c, bind_member_names_);
+
+ os << "}";
+
+ // init (view, image)
+ //
+ os << "void " << traits << "::" << endl
+ << "init (view_type& o, const image_type& i)"
+ << "{"
+ << "ODB_POTENTIALLY_UNUSED (o);"
+ << "ODB_POTENTIALLY_UNUSED (i);"
+ << endl;
+
+ names (c, init_value_member_names_);
+
+ os << "}";
+
+ // query_statement
+ //
+ os << "const char* const " << traits << "::query_statement =" << endl
+ << strlit (c.get<string> ("query")) << endl
+ << strlit (" ") << ";" << endl
+ << endl;
+
+ // query ()
+ //
+ os << "result< " << traits << "::view_type >" << endl
+ << traits << "::" << endl
+ << "query (database&, const query_type& q)"
+ << "{"
+ << "using namespace " << db << ";"
+ << "using odb::details::shared;"
+ << "using odb::details::shared_ptr;"
+ << endl
+ << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
+ << endl
+ << "view_statements< view_type >& sts (" << endl
+ << "conn.statement_cache ().find_view<view_type> ());"
+ << endl
+ << "image_type& im (sts.image ());"
+ << "binding& imb (sts.image_binding ());"
+ << endl
+ << "if (im.version != sts.image_version () || imb.version == 0)"
+ << "{"
+ << "bind (imb.bind, im);"
+ << "sts.image_version (im.version);"
+ << "imb.version++;"
+ << "}"
+ << "shared_ptr<select_statement> st (" << endl
+ << "new (shared) select_statement (" << endl;
+
+ view_query_statement_ctor_args (c);
+
+ os << "));" << endl
+ << "st->execute ();";
+
+ post_query_ (c);
+
+ os << endl
+ << "shared_ptr<odb::result_impl<view_type, " <<
+ "class_view> > r (" << endl
+ << "new (shared) " << db <<
+ "::result_impl<view_type, class_view> (" << endl
+ << "q, st, sts));"
+ << endl
+ << "return result<view_type> (r);"
+ << "}";
+ }
+
+ //
+ // composite
+ //
+
virtual void
traverse_composite (type& c)
{
@@ -2863,7 +3024,7 @@ namespace relational
os << "}";
- // init (image, object)
+ // init (image, value)
//
os << "bool " << traits << "::" << endl
<< "init (image_type& i, const value_type& o)"
@@ -2880,7 +3041,7 @@ namespace relational
os << "return grew;"
<< "}";
- // init (object, image)
+ // init (value, image)
//
os << "void " << traits << "::" << endl
<< "init (value_type& o, const image_type& i, database& db)"
diff --git a/odb/relational/type-processor.cxx b/odb/relational/type-processor.cxx
index 12d2b52..362fab3 100644
--- a/odb/relational/type-processor.cxx
+++ b/odb/relational/type-processor.cxx
@@ -1087,16 +1087,16 @@ namespace relational
virtual void
traverse (type& c)
{
- bool obj (object (c));
+ bool ov (object (c) || view (c));
- if (!(obj || composite (c)))
+ if (!(ov || composite (c)))
return;
names (c);
- // Assign object pointer.
+ // Assign pointer.
//
- if (obj)
+ if (ov)
assign_pointer (c);
}