diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-01-17 14:09:57 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-01-17 14:09:57 +0200 |
commit | 662d76ebb86b06c6aa754b0c52c07efbde80f943 (patch) | |
tree | 9df770bad8ebe3cc723b54ed1053b79540d27d34 /doc | |
parent | 8c5d8c5aa003f58fe561293e5fe197691e697841 (diff) |
Add chapter on session
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual.xhtml | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/doc/manual.xhtml b/doc/manual.xhtml index 242b01d..95c0ddc 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -4129,6 +4129,190 @@ CREATE TABLE `person_nickname` ( <!-- CHAPTER --> + <h1><a name="Q">Q Session</a></h1> + + <p>A session is an application's unit of work that may encompass several + database transactions (@@ ref Transaction). In this version of ODB a + session is just an object cache. In the future versions it will provide + additional functionality, such as automatic object state change flushing + and optimistic concurrency.</p> + + <p>Each thread of execution in an application can have only one active + session at a time. A session is started by creating an instance of + the <code>odb::session</code> class and is automatically terminated + when this instance is destroyed. You will need to include the + <code><odb/session.hxx></code> header file to make this class + available in your application. For example:</p> + + <pre class="c++"> +#include <odb/database.hxx> +#include <odb/session.hxx> +#include <odb/transaction.hxx> + +using namespace odb; + +{ + session s; + + // First transaction. + // + { + transaction t (db.begin ()); + ... + t.commit (); + } + + // Second transaction. + // + { + transaction t (db.begin ()); + ... + t.commit (); + } + + // Session 's' is terminated here. +} + </pre> + + <p>The <code>odb::session</code> class has the following interface:</p> + + <pre class="c++"> +namespace odb +{ + class session + { + public: + session (); + ~session (); + + // Copying or assignment of sessions is not supported. + // + private: + session (const session&); + session& operator= (const session&); + + // Current session interface. + // + public: + static session& + current (); + + static bool + has_current (); + + static void + current (session&); + + static void + reset_current (); + + // Object cache interface. + // + public: + typedef odb::database database_type; + + template <typename T> + void + insert (database_type&, + const object_traits<T>::id_type&, + const object_traits<T>::pointer_type&); + + template <typename T> + object_traits<T>::pointer_type + find (database_type&, const object_traits<T>::id_type&) const; + + template <typename T> + void + erase (database_type&, const object_traits<T>::id_type&); + }; +} + </pre> + + <p>The session constructor creates a new session and sets it as a + current session for this thread. If you try to create a session + while there is already a current session in effect, this constructor + throws the <code>odb::already_in_session</code> exception. The + destructor clears the current session for this thread if this + session is the current one.</p> + + <p>The static <code>current()</code> accessor returns the currently active + session for this thread. If there is no active session, this function + throws the <code>odb::not_in_session</code> exception. You can check + whether there is a session in effect in this thread using the + <code>has_current()</code> static function.</p> + + <p>The static <code>current()</code> modifier allows you to set the + current session for this thread. The <code>reset_current</code> + static function clears the current session. These two functions + allow for more advanced use cases, such as multiplexing + between two or more sessions in the same thread.</p> + + <p>We normally don't use the object cache interface directly. However, + it could be useful in some cases, for example, to find out whether + an object has already been loaded.</p> + + <h2><a name="Q.1">Q.1 Object Cache</a></h2> + + <p>A session is an object cache. Every time an object is made persistent + by calling the <code>database::persist()</code> function (@@ ref), loaded + by calling the <code>database::load()</code> or <code>database::find()</code> + function (@@ ref), or loaded by iterating over a query result (@@ ref), + the pointer to the persistent object, in the form of the canonical object + pouinter (@@ ref), is stored in the session. For as long as the + session is in effect, any subsequent calls to load the same object will + return the cached instance. When an object's state is deleted from the + database with the <code>database::erase()</code> function (@@ ref), the + cached object pointer is removed from the session. For example:</p> + + <pre class="c++"> +shared_ptr<person> p (new person ("John", "Doe")); + +session s; +transaction t (db.begin ()); + +unsigned long id (db.persist (p)); // p is cached in s. +shared_ptr<person> p1 (db.load<person> (id)); // p1 same as p. + +t.commit (); + </pre> + + + <p>The per-object caching policies depend on the object pointer kind + (@@ ref). Objects with a unique pointer, such as <code>std::auto_ptr</code>, + as an object pointer are never cached since it is not possible to have + two such pointers pointing to the same object. When an object is + persisted via a pointer or loaded as a dynamically allocated instance, + objects with both raw and shared pointers as object pointers are + cached. If an object is persisted as a reference or loaded into + a pre-allocated instance, the object is only cached if its object + pointer is a raw pointer.</p> + + <p>Finally, the session caches both constant and non-constant objects, + depending on whether a constant reference or constant pointer was + passed to the <code>database::persist()</code> function (in contrast, + when loaded, objects are always created and cached as non-constant). + If we try to load an object as non-constant that was previously + persisted and cached as constant, the <code>odb::const_object</code> + exception is thrown. The following transaction illustartes the + situation where this would happen:</p> + + <pre class="c++"> +shared_ptr<const person> p (new person ("John", "Doe")); + +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. + +t.commit (); + </pre> + + + <!-- CHAPTER --> + + <h1><a name="4">4 Querying the Database</a></h1> <p>If you don't know the identifiers of the objects that you are looking |