From 8c5d8c5aa003f58fe561293e5fe197691e697841 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov A newly created instance of a persistent class is transient.
We use the Here and in the rest of the manual,
+ The first 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);
+ 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.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.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
+ function template. This function has three overloaded versions with + the following signatures:database::update()
- function template: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 theodb::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 (); ++
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