Skip to content

Commit

Permalink
Merge pull request #115 from fukamachi/fix/110
Browse files Browse the repository at this point in the history
Add clack-session-store-dbi again
  • Loading branch information
fukamachi committed Jun 3, 2015
2 parents 0ebd152 + a736e66 commit e9d1ebf
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
15 changes: 15 additions & 0 deletions v1-compat/clack-session-store-dbi.asd
Original file line number Diff line number Diff line change
@@ -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")
77 changes: 77 additions & 0 deletions v1-compat/src/contrib/session/store/dbi.lisp
Original file line number Diff line number Diff line change
@@ -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))

0 comments on commit e9d1ebf

Please sign in to comment.