aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--doc/manual.xhtml88
-rw-r--r--odb/common.cxx4
-rw-r--r--odb/common.hxx3
4 files changed, 97 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 576aad1..0dfd128 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,11 @@ Version 2.4.0
(translated to the ON DELETE SQL clause) for an object pointer. For more
information, refer to Section 14.4.15, "on_delete" in the ODB manual.
+ * Support for defining persistent objects as instantiations of C++ class
+ templates, similar to composite value types. For details, refer to
+ Section 15.2, "Persistent Class Template Instantiations" in the ODB
+ manual.
+
* User-supplied prologues and epilogues are now generated outside the
pre.hxx/post.hxx includes. This allows the use of precompiled headers
with the generated files.
diff --git a/doc/manual.xhtml b/doc/manual.xhtml
index 06d7c82..57b95af 100644
--- a/doc/manual.xhtml
+++ b/doc/manual.xhtml
@@ -664,6 +664,7 @@ for consistency.
<th>15</th><td><a href="#15">Advanced Techniques and Mechanisms</a>
<table class="toc">
<tr><th>15.1</th><td><a href="#15.1">Transaction Callbacks</a></td></tr>
+ <tr><th>15.2</th><td><a href="#15.2">Persistent Class Template Instantiations</a></td></tr>
</table>
</td>
</tr>
@@ -17931,6 +17932,93 @@ class object
};
</pre>
+ <h2><a name="15.2">15.2 Persistent Class Template Instantiations</a></h2>
+
+ <p>Similar to composite value types (<a href="#7.2">Section 7.2, "Composite
+ Value Types"</a>), a persistent object can be defined as an instantiation
+ of a C++ class template, for example:</p>
+
+ <pre class="cxx">
+template &lt;typename T>
+class person
+{
+ ...
+
+ T first_;
+ T last_;
+};
+
+typedef person&lt;std::string> std_person;
+
+#pragma db object(std_person)
+#pragma db member(std_person::last_) id
+ </pre>
+
+ <p>Note that the database support code for such a persistent object
+ is generated when compiling the header containing the
+ <code>db&nbsp;object</code> pragma and not the header containing
+ the template definition or the <code>typedef</code> name. This
+ allows us to use templates defined in other files, for example:</p>
+
+ <pre class="cxx">
+#include &lt;utility> // std::pair
+
+typedef std::pair&lt;unsigned int, std::string> person;
+#pragma db object(person)
+#pragma db member(person::first) id auto column("id")
+#pragma db member(person::second) column("name")
+ </pre>
+
+ <p>You may also have to explicitly specify the object type in
+ calls to certain <code>database</code> class functions due
+ to the inability do distinguish, at the API level, between
+ smart pointers and persistent objects defined as class
+ template instantiations. For example:</p>
+
+ <pre class="cxx">
+person p;
+
+db.update (p); // Error.
+db.reload (p); // Error.
+db.erase (p); // Error.
+
+db.update&lt;person> (p); // Ok.
+db.reload&lt;person> (p); // Ok.
+db.erase&lt;person> (p); // Ok.
+ </pre>
+
+ <p>It also makes sense to factor persistent data members that do not
+ depend on template arguments into a common, non-template base class.
+ The following more realistic example illustrates this approach:</p>
+
+ <pre class="cxx">
+#pragma db object abstract
+class base_common
+{
+ ...
+
+ #pragma db id auto
+ unsigned long id;
+};
+
+template &lt;typename T>
+class base: public base_common
+{
+ ...
+
+ T value;
+};
+
+typedef base&lt;std::string> string_base;
+#pragma db object(string_base) abstract
+
+#pragma db object
+class derived: public string_base
+{
+ ...
+};
+ </pre>
+
<!-- PART -->
diff --git a/odb/common.cxx b/odb/common.cxx
index f52cee6..b75d323 100644
--- a/odb/common.cxx
+++ b/odb/common.cxx
@@ -504,9 +504,9 @@ check (semantics::typedefs& t)
if (ci == 0)
return false;
- // It must be a composite value.
+ // It must be an object or composite value.
//
- if (!composite (*ci))
+ if (!object (*ci) && !composite (*ci))
return false;
// This typedef name should be the one that was used in the pragma.
diff --git a/odb/common.hxx b/odb/common.hxx
index 0fcd481..6e70f43 100644
--- a/odb/common.hxx
+++ b/odb/common.hxx
@@ -420,7 +420,8 @@ private:
columns columns_;
};
-// Traverse composite values that are class template instantiations.
+// Traverse objects and composite values that are class template
+// instantiations.
//
struct typedefs: traversal::typedefs, context
{