Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #115 from fukamachi/fix/110

Add clack-session-store-dbi again
  • Loading branch information...
commit e9d1ebfe695b09eea1cb3c9ac71733a7537ac132 2 parents 0ebd152 + a736e66
@fukamachi authored
View
15 v1-compat/clack-session-store-dbi.asd
@@ -0,0 +1,15 @@
+(in-package :cl-user)
+(defpackage clack-session-store-dbi-asd
+ (:use :cl :asdf))
+(in-package :clack-session-store-dbi-asd)
+
+(defsystem clack-session-store-dbi
+ :version "0.1.0"
+ :author "Eitaro Fukamachi"
+ :license "LLGPL"
+ :depends-on (:clack-v1-compat
+ :dbi
+ :cl-base64
+ :marshal)
+ :components ((:file "src/contrib/session/store/dbi"))
+ :description "CL-DBI-based session store for Clack.Middleware.Session")
View
77 v1-compat/src/contrib/session/store/dbi.lisp
@@ -0,0 +1,77 @@
+(in-package :cl-user)
+(defpackage clack.session.store.dbi
+ (:use :cl
+ :clack.session.store)
+ (:import-from :marshal
+ :marshal
+ :unmarshal)
+ (:import-from :base64
+ :base64-string-to-string
+ :string-to-base64-string))
+(in-package :clack.session.store.dbi)
+
+(syntax:use-syntax :annot)
+
+@export
+(defclass <clack-session-store-dbi> (<clack-session-store>)
+ ((connect-args :type list
+ :initarg :connect-args
+ :reader store-connect-args)
+ (connector :type function
+ :initarg :connector
+ :reader store-connector)
+ (table-name :type string
+ :initarg :table-name
+ :initform "sessions"
+ :reader store-table-name)
+ (%connection)))
+
+(defmethod initialize-instance :after ((store <clack-session-store-dbi>) &key)
+ (unless (or (slot-boundp store 'connector)
+ (slot-boundp store 'connect-args))
+ (error ":connect-args or :connector is required.")))
+
+(defun store-connection (store)
+ (cond
+ ((slot-boundp store 'connector)
+ (funcall (slot-value store 'connector)))
+ ((slot-boundp store '%connection)
+ (slot-value store '%connection))
+ (T (setf (slot-value store '%connection)
+ (apply #'dbi:connect (store-connect-args store))))))
+
+(defmethod fetch ((store <clack-session-store-dbi>) sid)
+ (let* ((query (dbi:prepare (store-connection store)
+ (format nil "SELECT session_data FROM ~A WHERE id = ?"
+ (store-table-name store))))
+ (result (dbi:fetch (dbi:execute query sid))))
+ (if result
+ (ignore-errors
+ (unmarshal
+ (read-from-string
+ (base64-string-to-string
+ (getf result :|session_data|)))))
+ nil)))
+
+(defmethod store-session ((store <clack-session-store-dbi>) sid session)
+ (let* ((conn (store-connection store))
+ (query (dbi:prepare conn
+ (format nil "SELECT 1 FROM ~A WHERE id = ?"
+ (store-table-name store))))
+ (existsp (dbi:fetch (dbi:execute query sid)))
+ (base64-session (string-to-base64-string (prin1-to-string (marshal session)))))
+ (if existsp
+ (dbi:do-sql conn (format nil "UPDATE ~A SET session_data = ? WHERE id = ?"
+ (store-table-name store))
+ base64-session
+ sid)
+ (dbi:do-sql conn (format nil "INSERT INTO ~A (id, session_data) VALUES (?, ?)"
+ (store-table-name store))
+ sid
+ base64-session))))
+
+(defmethod remove-session ((store <clack-session-store-dbi>) sid)
+ (dbi:do-sql (store-connection store)
+ (format nil "DELETE FROM ~A WHERE id = ?"
+ (store-table-name store))
+ sid))
Please sign in to comment.
Something went wrong with that request. Please try again.