diff options
Diffstat (limited to 'doc/manual.xhtml')
-rw-r--r-- | doc/manual.xhtml | 127 |
1 files 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) <p>A newly created instance of a persistent class is transient. We use the <code>database::persist()</code> 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:</p> <pre class="c++"> @@ -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); </pre> + <p>Here and in the rest of the manual, + <code>object_traits<T>::pointer_type</code> and + <code>object_traits<T>::const_pointer_type</code> denote the + unrestricted and constant object pointer types (<a href="#3.2">Section + 3.2, "Object Pointer"</a>), respectively. + Similarly, <code>object_traits<T>::id_type</code> denotes the object + id type. The <code>odb::object_traits</code> template is part of the + database support code generated by the ODB compiler.</p> + <p>The first <code>persist()</code> function expects a constant reference - to an instance being persisted and is used on objects with - application-assigned object ids (see <a href="#5.4">Section 5.4, - "Data Member Pragmas"</a>). 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.</p> + 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 (<a href="#5.4.2">Section 5.4.2, + "<code>auto</code>"</a>).</p> + + <p>The second and third <code>persist()</code> 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.</p> <p>If the database already contains an object of this type with this identifier, the <code>persist()</code> functions throw the @@ -2092,15 +2113,12 @@ update_age (database& db, person& p) <p>When calling the <code>persist()</code> functions, we don't need to explicitly specify the template type since it will be automatically - deduced from the argument being passed. The <code>odb::object_traits</code> - template used in the signature above is part of the database support - code generated by the ODB compiler.</p> - - <p>The following example shows how we can call these functions:</p> + deduced from the argument being passed. The following example shows + how we can call these functions:</p> <pre class="c++"> 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.</p> <h2><a name="3.6">3.6 Loading Persistent Objects</a></h2> @@ -2194,17 +2212,27 @@ t.commit (); <p>If a persistent object has been modified, we can store the updated state in the database using the <code>database::update()</code> - function template:</p> + function template. This function has three overloaded versions with + the following signatures:</p> <pre class="c++"> 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); </pre> - <p>If the object passed to this function does not exist in the - database, <code>update()</code> throws the - <code>odb::object_not_persistent</code> exception.</p> + <p>The first <code>update()</code> 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, <code>update()</code> + throws the <code>odb::object_not_persistent</code> exception.</p> <p>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, } </pre> + <p>The same can be acomplished using dynamically allocated objects + and the object pointer version of the <code>update()</code> function, + for example:</p> + + <pre class="c++"> + 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 (); + </pre> + <h2><a name="3.8">3.8 Deleting Persistent Objects</a></h2> <p>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); </pre> - <p>The first <code>erase()</code> 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 - <code>odb::object_not_persistent</code> exception.</p> - + <p>The first <code>erase()</code> 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 <code>odb::object_not_persistent</code> exception.</p> - <p>We have to specify the object type when calling the second + <p>We have to specify the object type when calling the last <code>erase()</code> 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:</p> <pre class="c++"> -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 (); </pre> |