From 18aeb349f502bfdf3ddc64e6a3f671a0a818a3f3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 1 Aug 2014 07:15:19 +0200 Subject: Add support for defining persistent objects as class template instantiations --- doc/manual.xhtml | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'doc/manual.xhtml') 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. 15Advanced Techniques and Mechanisms +
15.1Transaction Callbacks
15.2Persistent Class Template Instantiations
@@ -17931,6 +17932,93 @@ class object }; +

15.2 Persistent Class Template Instantiations

+ +

Similar to composite value types (Section 7.2, "Composite + Value Types"), a persistent object can be defined as an instantiation + of a C++ class template, for example:

+ +
+template <typename T>
+class person
+{
+  ...
+
+  T first_;
+  T last_;
+};
+
+typedef person<std::string> std_person;
+
+#pragma db object(std_person)
+#pragma db member(std_person::last_) id
+  
+ +

Note that the database support code for such a persistent object + is generated when compiling the header containing the + db object pragma and not the header containing + the template definition or the typedef name. This + allows us to use templates defined in other files, for example:

+ +
+#include <utility> // std::pair
+
+typedef std::pair<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")
+  
+ +

You may also have to explicitly specify the object type in + calls to certain database 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:

+ +
+person p;
+
+db.update (p); // Error.
+db.reload (p); // Error.
+db.erase (p);  // Error.
+
+db.update<person> (p); // Ok.
+db.reload<person> (p); // Ok.
+db.erase<person> (p);  // Ok.
+  
+ +

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:

+ +
+#pragma db object abstract
+class base_common
+{
+  ...
+
+  #pragma db id auto
+  unsigned long id;
+};
+
+template <typename T>
+class base: public base_common
+{
+  ...
+
+  T value;
+};
+
+typedef base<std::string> string_base;
+#pragma db object(string_base) abstract
+
+#pragma db object
+class derived: public string_base
+{
+  ...
+};
+  
+ -- cgit v1.1