aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-01-14 17:21:02 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-01-14 17:21:02 +0200
commit8c5d8c5aa003f58fe561293e5fe197691e697841 (patch)
tree59c97a4df12289b43fb7446feb36a835cb2f464d
parente4d9767e7f3b160a063567b9101acb30d67c97ab (diff)
Update database operations documentation with object pointer versions
-rw-r--r--doc/manual.xhtml127
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&amp; db, person&amp; 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&amp; db, person&amp; p)
template &lt;typename T>
typename object_traits&lt;T>::id_type
+ persist (const object_traits&lt;T>::const_pointer_type&amp; object);
+
+ template &lt;typename T>
+ typename object_traits&lt;T>::id_type
persist (T&amp; object);
+
+ template &lt;typename T>
+ typename object_traits&lt;T>::id_type
+ persist (const object_traits&lt;T>::pointer_type&amp; object);
</pre>
+ <p>Here and in the rest of the manual,
+ <code>object_traits&lt;T>::pointer_type</code> and
+ <code>object_traits&lt;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&lt;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&amp; db, person&amp; 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&lt;person> jane (new person ("Jane", "Doe", 32));
transaction t (db.begin ());
@@ -2121,8 +2139,8 @@ cerr &lt;&lt; "Jane's id: " &lt;&lt; jane_id &lt;&lt; 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 &lt;typename T>
void
update (const T&amp; object);
+
+ template &lt;typename T>
+ void
+ update (const object_traits&lt;T>::const_pointer_type&amp; object);
+
+ template &lt;typename T>
+ void
+ update (const object_traits&lt;T>::pointer_type&amp; 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&amp; 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&lt;bank_account> from (db.load&lt;bank_account> (from_acc));
+
+ if (from->balance () &lt; amount)
+ throw insufficient_funds ();
+
+ shared_ptr&lt;bank_account> to (db.load&lt;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&amp; db,
template &lt;typename T>
void
+ erase (const object_traits&lt;T>::const_pointer_type&amp; object);
+
+ template &lt;typename T>
+ void
+ erase (const object_traits&lt;T>::pointer_type&amp; object);
+
+ template &lt;typename T>
+ void
erase (const typename object_traits&lt;T>::id_type&amp; 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&amp; john = ...
+person&amp; john = ...
+shared_ptr&lt;jane> jane = ...
+unsigned long joe_id = ...
transaction t (db.begin ());
db.erase (john);
-db.erase&lt;person> (jane_id);
+db.erase (jane);
+db.erase&lt;person> (joe_id);
t.commit ();
</pre>