mirror of
https://github.com/vale981/lack
synced 2025-03-05 09:21:39 -05:00
Add :record-timestamps to dbi-store for recording created_at & updated_at.
This commit is contained in:
parent
ac68b5c167
commit
17d15c7102
2 changed files with 79 additions and 5 deletions
|
@ -27,6 +27,7 @@
|
||||||
(deserializer (lambda (data)
|
(deserializer (lambda (data)
|
||||||
(unmarshal (read-from-string
|
(unmarshal (read-from-string
|
||||||
(utf-8-bytes-to-string (base64-string-to-usb8-array data))))))
|
(utf-8-bytes-to-string (base64-string-to-usb8-array data))))))
|
||||||
|
(record-timestamps nil :type boolean)
|
||||||
(table-name "sessions"))
|
(table-name "sessions"))
|
||||||
|
|
||||||
(defmethod fetch-session ((store dbi-store) sid)
|
(defmethod fetch-session ((store dbi-store) sid)
|
||||||
|
@ -45,6 +46,13 @@
|
||||||
nil))
|
nil))
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
|
(defun current-timestamp ()
|
||||||
|
(multiple-value-bind (sec min hour date month year)
|
||||||
|
(decode-universal-time (get-universal-time))
|
||||||
|
(format nil "~D-~2,'0D-~2,'0DT~2,'0D:~2,'0D:~2,'0D"
|
||||||
|
year month date
|
||||||
|
hour min sec)))
|
||||||
|
|
||||||
(defmethod store-session ((store dbi-store) sid session)
|
(defmethod store-session ((store dbi-store) sid session)
|
||||||
(let ((conn (funcall (dbi-store-connector store)))
|
(let ((conn (funcall (dbi-store-connector store)))
|
||||||
(serialized-session (funcall (dbi-store-serializer store) session)))
|
(serialized-session (funcall (dbi-store-serializer store) session)))
|
||||||
|
@ -58,14 +66,19 @@
|
||||||
((equal current-session serialized-session))
|
((equal current-session serialized-session))
|
||||||
;; Session exists and is going to be changed
|
;; Session exists and is going to be changed
|
||||||
(current-session
|
(current-session
|
||||||
(dbi:do-sql conn (format nil "UPDATE ~A SET session_data = ? WHERE id = ?"
|
(dbi:do-sql conn
|
||||||
(dbi-store-table-name store))
|
(format nil "UPDATE ~A SET session_data = ?~:[~*~;, updated_at = '~A'~] WHERE id = ?"
|
||||||
|
(dbi-store-table-name store)
|
||||||
|
(dbi-store-record-timestamps store)
|
||||||
|
(current-timestamp))
|
||||||
serialized-session
|
serialized-session
|
||||||
sid))
|
sid))
|
||||||
;; New session
|
;; New session
|
||||||
(t
|
(t
|
||||||
(dbi:do-sql conn (format nil "INSERT INTO ~A (id, session_data) VALUES (?, ?)"
|
(dbi:do-sql conn (format nil "INSERT INTO ~A (id, session_data~:[~;, created_at, updated_at~]) VALUES (?, ?~:*~:[~*~;, '~A', ~:*'~A'~])"
|
||||||
(dbi-store-table-name store))
|
(dbi-store-table-name store)
|
||||||
|
(dbi-store-record-timestamps store)
|
||||||
|
(current-timestamp))
|
||||||
sid
|
sid
|
||||||
serialized-session)))))))
|
serialized-session)))))))
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
:prove))
|
:prove))
|
||||||
(in-package :t.lack.session.store.dbi)
|
(in-package :t.lack.session.store.dbi)
|
||||||
|
|
||||||
(plan 3)
|
(plan 4)
|
||||||
|
|
||||||
(defvar *test-db* (asdf:system-relative-pathname :lack "data/test.db"))
|
(defvar *test-db* (asdf:system-relative-pathname :lack "data/test.db"))
|
||||||
(when (probe-file *test-db*)
|
(when (probe-file *test-db*)
|
||||||
|
@ -83,6 +83,67 @@
|
||||||
(is (getf session :|count|) 2
|
(is (getf session :|count|) 2
|
||||||
"'sessions' has two records"))
|
"'sessions' has two records"))
|
||||||
|
|
||||||
|
(dbi:disconnect *conn*)
|
||||||
|
(delete-file *test-db*)
|
||||||
|
|
||||||
|
(setf *conn*
|
||||||
|
(dbi:connect :sqlite3 :database-name *test-db*))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; record-timestamps t
|
||||||
|
|
||||||
|
(dbi:do-sql *conn*
|
||||||
|
"CREATE TABLE sessions (id CHAR(72) PRIMARY KEY, session_data TEXT, created_at DATETIME, updated_at DATETIME)")
|
||||||
|
|
||||||
|
(subtest "session middleware"
|
||||||
|
(let ((app
|
||||||
|
(builder
|
||||||
|
(:session
|
||||||
|
:store (make-dbi-store
|
||||||
|
:connector (lambda () *conn*)
|
||||||
|
:record-timestamps t))
|
||||||
|
(lambda (env)
|
||||||
|
(unless (gethash :counter (getf env :lack.session))
|
||||||
|
(setf (gethash :counter (getf env :lack.session)) 0))
|
||||||
|
`(200
|
||||||
|
(:content-type "text/plain")
|
||||||
|
(,(format nil "Hello, you've been here for ~Ath times!"
|
||||||
|
(incf (gethash :counter (getf env :lack.session)))))))))
|
||||||
|
session
|
||||||
|
now)
|
||||||
|
(diag "1st request")
|
||||||
|
(destructuring-bind (status headers body)
|
||||||
|
(funcall app (generate-env "/"))
|
||||||
|
(is status 200)
|
||||||
|
(setf session (parse-lack-session headers))
|
||||||
|
(ok session)
|
||||||
|
(is body '("Hello, you've been here for 1th times!")))
|
||||||
|
|
||||||
|
(let ((records (dbi:fetch-all
|
||||||
|
(dbi:execute
|
||||||
|
(dbi:prepare *conn* "SELECT * FROM sessions")))))
|
||||||
|
(is (length records) 1)
|
||||||
|
(is (getf (first records) :|id|) session)
|
||||||
|
(setf now (getf (first records) :|created_at|))
|
||||||
|
(is (getf (first records) :|updated_at|) now))
|
||||||
|
|
||||||
|
(sleep 2)
|
||||||
|
|
||||||
|
(diag "2nd request")
|
||||||
|
(destructuring-bind (status headers body)
|
||||||
|
(funcall app (generate-env "/" :cookies `(("lack.session" . ,session))))
|
||||||
|
(declare (ignore headers))
|
||||||
|
(is status 200)
|
||||||
|
(is body '("Hello, you've been here for 2th times!")))
|
||||||
|
|
||||||
|
(let ((records (dbi:fetch-all
|
||||||
|
(dbi:execute
|
||||||
|
(dbi:prepare *conn* "SELECT * FROM sessions")))))
|
||||||
|
(is (length records) 1)
|
||||||
|
(is (getf (first records) :|id|) session)
|
||||||
|
(is (getf (first records) :|created_at|) now)
|
||||||
|
(isnt (getf (first records) :|updated_at|) now))))
|
||||||
|
|
||||||
(dbi:disconnect *conn*)
|
(dbi:disconnect *conn*)
|
||||||
|
|
||||||
(finalize)
|
(finalize)
|
||||||
|
|
Loading…
Add table
Reference in a new issue