Installation
To download the planet package:
(require (planet bzlib/session))
The package comes with three separate database installation scripts (one each for sqlite, mysql, and postgresql). You can call them via the following:
;; installing to a sqlite database
(require (planet bzlib/session/setup/jsqlite))
(setup-session-store/jsqlite! <path-to-sqlite-db>)
;; installing to a mysql database
(require (planet bzlib/session/setup/jazmysql))
(setup-session-store/jazmysql! <host> <port> <user>
<password> <schema>)
;; installing to a postgresql database
(require (planet bzlib/session/setup/spgsql))
(setup-session-store/spgsql! <host> <port> <user>
<password> <database>)
Known Issue: the script currently can only be run once and it assumes the table session_t does not exist in the target database. This will be rectified in the future.Session ID
The session store uses uuid for session IDs.
bzlib/base provides API for manipulation of uuids.To create an uuid, just run
(make-uuid). It can optionally takes in a parameter that are either an uuid in string, and then create the corresponding uuid structure (it can also takes in another uuid structure and make an equivalent uuid structure).
> (require (planet bzlib/base))
> (make-uuid)
#<uuid:4ba52eac-a0b4-415a-88f5-57d1fadd1aba>
> (make-uuid "4ba52eac-a0b4-415a-88f5-57d1fadd1aba")
#<uuid:4ba52eac-a0b4-415a-88f5-57d1fadd1aba>
> (make-uuid (make-uuid "4ba52eac-a0b4-415a-88f5-57d1fadd1aba"))
#<uuid:4ba52eac-a0b4-415a-88f5-57d1fadd1aba>
bzlib/session.plt does not handle parsing cookies into uuids.Creating a Session Object
In order to create a session object, you first need to make a
dbi handle with either dbd-spgsql, dbd-jazmysql, or dbd-jsqlite driver to where you have setup the session_t table, and you need to pass in the corresponding query script so the prepared statements ('make-session!, 'load-session, 'save-session!, and destroy-session!) can be loaded:
(require (planet bzlib/session) (planet bzlib/dbi))
;; loading 'jsqlite
(require (planet bzlib/dbd-jsqlite))
(define h (connect 'jsqlite <path-to-db>
'#:load (session-query-path/sqlite)))
;; loading 'spgsql
(require (planet bzlib/dbd-spgsql))
(define h (connect 'spgsql <spgsql-parameters> ...
'#:load (session-query-path/postgres)))
;; loading 'jazmysql
(require (planet bzlib/dbd-jazmysql))
(define h (connect 'jazmysql <jazmysql-parameters> ...
'#:load (session-query-path/mysql)))
Then you can pass the handle to build-session to create the session object.
;; create a new session with a new uuid
(define s (build-session h))
;; create a new session with a known uuid
(define s (build-session h <uuid>))
As soon as build-session is called, you'll find a corresponding session record in session_t. Accessing Session Key/Value Pairs
session-ref, session-set!, session-del! modifies the values of session key/value pairs:
(session-ref <session> <key> <optional-default-value>)
(session-set! <session> <key> <value>)
(session-del! <session> <key>)
Writing Out Sessions
save-session! saves the sessions out to the database:
(save-session! <session>)
refresh-session! will reload the session from the database:
(refresh-session! <session>)
And destroy-session! will delete the session record from session_t:
(destroy-session! <session>)
call-with-session and with-session will help you manage the call to save-session! so you do not have to write it with every request:
(call-with-session (build-session h)
(lambda (session)
<... do something with session ...>))
(with-session (build-session h)
(lambda ()
<... do something with session via (current-session) ...>))
with-session works via (current-session), which is a parameter that holds either #f or a session structure. By passing the session object via with-session it will automatically parameterize current-session.Session Expirations
You can use
session-expired? to test whether the session object has expired:
(session-expired? <session>)
The expiration value is stored as a number (in Julian days) in session_t, which by default will be 14 days in the future from the time when save-session! is called. The default session expiration value of 14 days can be controlled via the
session-expiration-interval parameter.Web Server Continuation
To simplify the usage of
bzlib/session with web-server continuation calls, the following wrappers are exported to replace the send/suspend family:
(require (planet bzlib/session/web-server))
;; you then have access to...
send/back
send/finish
send/suspend
send/suspend/url
send/forward
send/suspend/dispatch
redirect/get
redirect/get/forget
These wrappers have the same corresponding APIs from web-server itself, and they'll call save-session! before making the continuation, and call refresh-session! before returning from the continuation.That's it for now, enjoy.
Hi, I got following error:
ReplyDelete> (refresh-session! s)
. . procedure build-session: no clause matching 4 arguments: # # 2455299.8333333917 #
Hi - thanks for the bug report.
ReplyDeleteI have uploaded a fix to planet.
Please do (require (planet bzlib/session:1:1)) to get the fix and that should remove the refresh-session! error.
Thanks.