A Clojure library for JDBC backed Ring sessions.
Use the jdbc-ring-session.core/jdbc-store
function to create a new store. The function accepts
a next.jdbc
datasource definition:
(ns db.core
(:require [jdbc-ring-session.core :refer [jdbc-store]]))
(def db
{:dbtype "postgresql"
:dbname "session"
:user "admin"
:password "admin"})
(def store (jdbc-store db))
The function also accepts an existing datasource, e.g. the connection pool of your application.
The session will be stored as a byte array serialized using nippy. The table formats are shown below.
PostgeSQL:
CREATE TABLE session_store
(
session_id VARCHAR(36) NOT NULL PRIMARY KEY,
idle_timeout BIGINT,
absolute_timeout BIGINT,
value BYTEA
)
Oracle:
CREATE TABLE SESSION_STORE
(
session_id VARCHAR2(100 BYTE) NOT NULL PRIMARY KEY,
absolute_timeout NUMBER,
idle_timeout NUMBER,
value BLOB
)
MySQL:
CREATE TABLE `session_store` (
`session_id` VARCHAR(36) NOT NULL,
`idle_timeout` DOUBLE DEFAULT NULL,
`absolute_timeout` DOUBLE DEFAULT NULL,
`value` BLOB,
PRIMARY KEY (`session_id`)
)
H2:
CREATE TABLE session_store (
session_id VARCHAR(36) NOT NULL,
idle_timeout BIGINT DEFAULT NULL,
absolute_timeout BIGINT DEFAULT NULL,
value BINARY(10000),
PRIMARY KEY (session_id)
)
SQL Server:
CREATE TABLE session_store (
session_id VARCHAR(36) NOT NULL,
idle_timeout BIGINT DEFAULT NULL,
absolute_timeout BIGINT DEFAULT NULL,
value VARBINARY(max),
PRIMARY KEY (session_id)
)
SQLite:
CREATE TABLE session_store
(
session_id VARCHAR NOT NULL PRIMARY KEY,
idle_timeout INTEGER,
absolute_timeout INTEGER,
value BLOB
)
The jdbc-store
function accepts an optional map with the keys called :table
, :serializer
and :deserializer
. The :table
defaults to :session_store
, while the :serializer
and :deserializer
keys are used to specify how the session data should be serialized and deserialized for the specific database. The library will attempt to figure out the appropriate serializer/deserializer based on the connection type. MySQL, PostgeSQL and Oracle BLOB formats are supported out of the box.
(jdbc-store db {:table :sessions})
The serializer function accepts the session map and returns the serialized value that will be inserted in the table, eg:
(defn serialize-postgres [value]
(nippy/freeze value))
The deserializer function receives the session value in the database and returns the deserialized session, eg:
(defn deserialize-postgres [value]
(when value
(nippy/thaw value)))
A cleaner thread is provided in the ring-jdbc-session.cleaner
for removing expired sessions from the database. The idle_timeout
and absolute_timeout
keys are expected to be populated by the ring-session-timeout library. These keys are used by the cleaner to remove stale sessions. The cleaner can be started and stopped as follows:
(ns db.core
(:require [jdbc-ring-session.cleaner :refer [start-cleaner stop-cleaner]]))
(start-cleaner db)
(stop-cleaner session-cleaner)
The start-cleaner
function accepts an optional map with the :interval
key that defaults to 60. This is the number of seconds to sleep between runs.
(start-cleaner {:interval 120})
Note that when running a database on a non-standard port, the jdbc datasource definition must be formatted as follows (from jdbc source):
DriverManager (alternative):
:dbtype (required) a String, the type of the database (the jdbc subprotocol)
:dbname (required) a String, the name of the database
:host (optional) a String, the host name/IP of the database
(defaults to 127.0.0.1)
:port (optional) a Long, the port of the database
(defaults to 3306 for mysql, 1433 for mssql/jtds, else nil)
(others) (optional) passed to the driver as properties.
Adding a :port
key to the standard DriverManager map will result in the database connection failing with a org.postgresql.util.PSQLException: FATAL: password authentication failed for user
, and it can be difficult to trace it back to the DriverManager format.
Using a string subprotocol://user:password@host:post/subname
, instead of a DriverManager map will also work.
Copyright © 2015 Yogthos
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.