From 8c5d8c5aa003f58fe561293e5fe197691e697841 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 14 Jan 2011 17:21:02 +0200 Subject: Update database operations documentation with object pointer versions --- doc/manual.xhtml | 127 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 32 deletions(-) diff --git a/doc/manual.xhtml b/doc/manual.xhtml index b192b11..242b01d 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -2061,7 +2061,7 @@ update_age (database& db, person& p)

A newly created instance of a persistent class is transient. We use the database::persist() function template - to make a transient instance persistent. This function has two + to make a transient instance persistent. This function has four overloaded versions with the following signatures:

@@ -2071,17 +2071,38 @@ update_age (database& db, person& p)
 
   template <typename T>
   typename object_traits<T>::id_type
+  persist (const object_traits<T>::const_pointer_type& object);
+
+  template <typename T>
+  typename object_traits<T>::id_type
   persist (T& object);
+
+  template <typename T>
+  typename object_traits<T>::id_type
+  persist (const object_traits<T>::pointer_type& object);
   
+

Here and in the rest of the manual, + object_traits<T>::pointer_type and + object_traits<T>::const_pointer_type denote the + unrestricted and constant object pointer types (Section + 3.2, "Object Pointer"), respectively. + Similarly, object_traits<T>::id_type denotes the object + id type. The odb::object_traits template is part of the + database support code generated by the ODB compiler.

+

The first persist() function expects a constant reference - to an instance being persisted and is used on objects with - application-assigned object ids (see Section 5.4, - "Data Member Pragmas"). The second - function expects an unrestricted reference and, if the object id is - assigned by the database, it updates the id member of the passed instance - with the assigned value. Both functions return the object id of the - newly persistent object.

+ to an instance being persisted. The second function expects a constant + object pointer. Both of these functions can only be used on objects with + application-assigned object ids (Section 5.4.2, + "auto").

+ +

The second and third persist() versions are similar to the + first two except that they operate on unrestricted references and object + pointers. If the identifier of the object being persisted is assigned + by the database, these functions update the id member of the passed + instance with the assigned value. All four functions return the object + id of the newly persistent object.

If the database already contains an object of this type with this identifier, the persist() functions throw the @@ -2092,15 +2113,12 @@ update_age (database& db, person& p)

When calling the persist() functions, we don't need to explicitly specify the template type since it will be automatically - deduced from the argument being passed. The odb::object_traits - template used in the signature above is part of the database support - code generated by the ODB compiler.

- -

The following example shows how we can call these functions:

+ deduced from the argument being passed. The following example shows + how we can call these functions:

 person john ("John", "Doe", 33);
-person jane ("Jane", "Doe", 32);
+shared_ptr<person> jane (new person ("Jane", "Doe", 32));
 
 transaction t (db.begin ());
 
@@ -2121,8 +2139,8 @@ cerr << "Jane's id: " << jane_id << endl;
      transaction consumes both your application's resources, such as
      a database connection, as well as the database server's
      resources, such as object locks. By following the above rule you
-     make sure these resources are made available to other threads
-     in your application and to other applications as soon as
+     make sure these resources are released and made available to other
+     threads in your application and to other applications as soon as
      possible.

3.6 Loading Persistent Objects

@@ -2194,17 +2212,27 @@ t.commit ();

If a persistent object has been modified, we can store the updated state in the database using the database::update() - function template:

+ function template. This function has three overloaded versions with + the following signatures:

   template <typename T>
   void
   update (const T& object);
+
+  template <typename T>
+  void
+  update (const object_traits<T>::const_pointer_type& object);
+
+  template <typename T>
+  void
+  update (const object_traits<T>::pointer_type& object);
   
-

If the object passed to this function does not exist in the - database, update() throws the - odb::object_not_persistent exception.

+

The first update() function expects an object reference, + while the other two expect object pointers. If the object passed to + these functions does not exist in the database, update() + throws the odb::object_not_persistent exception.

Below is an example of the funds transfer that we talked about in the earlier section on transactions. It uses the hypothetical @@ -2238,6 +2266,29 @@ transfer (database& db, }

+

The same can be acomplished using dynamically allocated objects + and the object pointer version of the update() function, + for example:

+ +
+  transaction t (db.begin ());
+
+  shared_ptr<bank_account> from (db.load<bank_account> (from_acc));
+
+  if (from->balance () < amount)
+    throw insufficient_funds ();
+
+  shared_ptr<bank_account> to (db.load<bank_account> (to_acc));
+
+  to->balance (to->balance () + amount);
+  from->balance (from->balance () - amount);
+
+  db.update (to);
+  db.update (from);
+
+  t.commit ();
+  
+

3.8 Deleting Persistent Objects

To delete a persistent object's state from the database we use the @@ -2253,30 +2304,42 @@ transfer (database& db, template <typename T> void + erase (const object_traits<T>::const_pointer_type& object); + + template <typename T> + void + erase (const object_traits<T>::pointer_type& object); + + template <typename T> + void erase (const typename object_traits<T>::id_type& id); -

The first erase() function uses an object itself to - delete its state from the database. Note that the passed object - is unchanged. It simply becomes transient. The second function uses - the object id to identify the object to be deleted. If the object - does not exist in the database, both functions throw the - odb::object_not_persistent exception.

- +

The first erase() function uses an object itself, in + the form of an object reference, to delete its state from the + database. The next two functions accomplish the same but using + object pointers. Note that all three functions leave the passed + object unchanged. It simply becomes transient. The last function + uses the object id to identify the object to be deleted. If the + object does not exist in the database, then all four functions + throw the odb::object_not_persistent exception.

-

We have to specify the object type when calling the second +

We have to specify the object type when calling the last erase() function. The same is unnecessary for the - first function because the object type will be automatically - deduced from its argument. The following example shows how we + first three functions because the object type will be automatically + deduced from their arguments. The following example shows how we can call these functions:

-const person& john = ...
+person& john = ...
+shared_ptr<jane> jane = ...
+unsigned long joe_id = ...
 
 transaction t (db.begin ());
 
 db.erase (john);
-db.erase<person> (jane_id);
+db.erase (jane);
+db.erase<person> (joe_id);
 
 t.commit ();
   
-- cgit v1.1