From 662d76ebb86b06c6aa754b0c52c07efbde80f943 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 17 Jan 2011 14:09:57 +0200 Subject: Add chapter on session --- doc/manual.xhtml | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) 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` ( +

Q Session

+ +

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.

+ +

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 odb::session class and is automatically terminated + when this instance is destroyed. You will need to include the + <odb/session.hxx> header file to make this class + available in your application. For example:

+ +
+#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.
+}
+  
+ +

The odb::session class has the following interface:

+ +
+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&);
+  };
+}
+  
+ +

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 odb::already_in_session exception. The + destructor clears the current session for this thread if this + session is the current one.

+ +

The static current() accessor returns the currently active + session for this thread. If there is no active session, this function + throws the odb::not_in_session exception. You can check + whether there is a session in effect in this thread using the + has_current() static function.

+ +

The static current() modifier allows you to set the + current session for this thread. The reset_current + 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.

+ +

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.

+ +

Q.1 Object Cache

+ +

A session is an object cache. Every time an object is made persistent + by calling the database::persist() function (@@ ref), loaded + by calling the database::load() or database::find() + 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 database::erase() function (@@ ref), the + cached object pointer is removed from the session. For example:

+ +
+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 ();
+  
+ + +

The per-object caching policies depend on the object pointer kind + (@@ ref). Objects with a unique pointer, such as std::auto_ptr, + 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.

+ +

Finally, the session caches both constant and non-constant objects, + depending on whether a constant reference or constant pointer was + passed to the database::persist() 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 odb::const_object + exception is thrown. The following transaction illustartes the + situation where this would happen:

+ +
+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 ();
+  
+ + + + +

4 Querying the Database

If you don't know the identifiers of the objects that you are looking -- cgit v1.1