From d001ec3018787138c2db6c5f6949a00807582774 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 21 Sep 2011 13:00:34 +0200 Subject: Rework const object handling Now objects are always loaded as non-const and the object cache in session treats all objects as non-const. --- doc/manual.xhtml | 59 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 25 deletions(-) (limited to 'doc') diff --git a/doc/manual.xhtml b/doc/manual.xhtml index 13c694f..7e68f6f 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -3060,12 +3060,6 @@ namespace odb what () const throw (); }; - struct const_object: exception - { - virtual const char* - what () const throw (); - }; - // Database operations exceptions. // struct recoverable: exception @@ -3137,11 +3131,9 @@ namespace odb odb::transaction class and are discussed in Section 3.4, "Transactions".

-

The next three exceptions (already_in_session, - not_in_session, and - const_object) are thrown by the - odb::session class and are discussed - in Chapter 9, "Session".

+

The next two exceptions (already_in_session, and + not_in_session) are thrown by the odb::session + class and are discussed in Chapter 9, "Session".

The recoverable exception serves as a common base for all the recoverable exceptions, which are: connection_lost, @@ -6051,26 +6043,43 @@ t.commit (); a pre-allocated instance, the object is only cached if its object pointer is a raw pointer.

-

Finally, the session caches both constant and unrestricted objects, - depending on whether a constant reference or constant pointer was - passed to the database::persist() function (in contrast, - when loaded, objects are always created and cached as unrestricted). - If we try to load an object as unrestricted that was previously - persisted and cached as constant, the odb::const_object - exception is thrown. The following transaction shows the - situation where this would happen:

+

Also note that when we persist an object as a constant reference + or constant pointer, the session caches such an object as + unrestricted (non-const). This can lead to undefined + behavior if the object being persisted was actually created as + const and is later found in the session cache and + used as non-const. As a result, when using sessions, + it is recommended that all persistent objects are created as + non-const instances. The following code fragment + illustrates this point:

-shared_ptr<const person> p (new person ("John", "Doe"));
+void save (database& db, shared_ptr<const person> p)
+{
+  transaction t (db.begin ());
+  db.persist (p); // Persisted as const pointer.
+  t.commit ();
+}
 
 session s;
-transaction t (db.begin ());
 
-unsigned long id (db.persist (p));
-shared_ptr<const person> p1 (db.load<const person> (id)); // Ok.
-shared_ptr<person> p2 (db.load<person> (id));             // Exception.
+shared_ptr<const person> p1 (new const person ("John", "Doe"));
+unsigned long id1 (save (db, p1)); // p1 is cached in s as non-const.
 
-t.commit ();
+{
+  transaction t (db.begin ());
+  shared_ptr<person> p (db.load<person> (id1)); // p == p1
+  p->age (30); // Undefined behavior since p1 was created const.
+}
+
+shared_ptr<const person> p2 (new person ("Jane", "Doe"));
+unsigned long id2 (save (db, p2)); // p2 is cached in s as non-const.
+
+{
+  transaction t (db.begin ());
+  shared_ptr<person> p (db.load<person> (id2)); // p == p2
+  p->age (30); // Ok, since p2 was not created const.
+}
   
-- cgit v1.1