Initial Ring session store implementation

This commit is contained in:
Michael S. Klishin 2012-05-14 16:10:55 +04:00
parent 0f1debd4f3
commit 87184af396
4 changed files with 117 additions and 5 deletions

View file

@ -1,6 +1,17 @@
## Changes between 1.0.0-beta6 and 1.0.0-beta7
No changes yet.
### ring.session.store implementation
Monger now features a [Ring session store](https://github.com/mmcgrana/ring/blob/master/ring-core/src/ring/middleware/session/store.clj) implementation. To use it, require `monger.ring.session-store` and use
`monger.ring.session-store/monger-store` function like so:
``` clojure
(ns my.service
(:use monger.ring.session-store))
(let [store (monger-store "web_sessions")]
...)
```

View file

@ -21,12 +21,13 @@
:1.5 {:dependencies [[org.clojure/clojure "1.5.0-master-SNAPSHOT"]]}
:dev {:resource-paths ["test/resources"]
:dependencies [[clj-time "0.4.2" :exclusions [org.clojure/clojure]]
[org.clojure/data.json "0.1.2" :exclusions [org.clojure/clojure]]
[org.clojure/tools.cli "0.2.1" :exclusions [org.clojure/clojure]]
[org.clojure/core.cache "0.5.0" :exclusions [org.clojure/clojure]]]}}
[org.clojure/data.json "0.1.2" :exclusions [org.clojure/clojure]]
[org.clojure/tools.cli "0.2.1" :exclusions [org.clojure/clojure]]
[org.clojure/core.cache "0.5.0" :exclusions [org.clojure/clojure]]
[ring/ring-core "1.1.0"]]}}
:aliases {"all" ["with-profile" "dev:dev,1.4:dev,1.5"]}
:repositories {"sonatype" {:url "http://oss.sonatype.org/content/repositories/releases"
:snapshots false,
:snapshots false
:releases {:checksum :fail :update :always}}
"sonatype-snapshots" {:url "http://oss.sonatype.org/content/repositories/snapshots"
:snapshots true

View file

@ -0,0 +1,46 @@
(ns monger.ring.session-store
(:require [ring.middleware.session.store :as ringstore]
[monger.collection :as mc])
(:use monger.conversion)
(:import [java.util UUID Date]))
;;
;; Implementation
;;
(def ^{:const true}
default-session-store-collection "web_sessions")
;;
;; API
;;
(defrecord MongoDBSessionStore [^String collection-name])
(extend-protocol ringstore/SessionStore
MongoDBSessionStore
(read-session [store key]
(if-let [m (and key
(mc/find-one-as-map (.collection-name store) {:_id key}))]
m
{}))
(write-session [store key data]
(let [key (or key (str (UUID/randomUUID)))]
(mc/save (.collection-name store) (assoc data :date (Date.) :_id key))
key))
(delete-session [store key]
(mc/remove-by-id (.collection-name store) key)
nil))
(defn monger-store
([]
(MongoDBSessionStore. default-session-store-collection))
([^String s]
(MongoDBSessionStore. s)))

View file

@ -0,0 +1,54 @@
(ns monger.test.ring.session-store-test
(:require [monger core util]
[monger.collection :as mc]
[monger.test.helper :as helper])
(:use clojure.test
ring.middleware.session.store
monger.ring.session-store))
(helper/connect!)
(defn purge-sessions
[f]
(mc/remove "web_sessions")
(mc/remove "sessions")
(f)
(mc/remove "web_sessions")
(mc/remove "sessions"))
(use-fixtures :each purge-sessions)
(deftest test-reading-a-session-that-does-not-exist
(let [store (monger-store)]
(is (= {} (read-session store "a-missing-key-1228277")))))
(deftest test-reading-a-session-that-does-exist
(let [store (monger-store)
sk (write-session store nil {:library "Monger"})
m (read-session store sk)]
(is sk)
(is (and (:_id m) (:date m)))
(is (= (dissoc m :_id :date)
{:library "Monger"}))))
(deftest test-updating-a-session
(let [store (monger-store)
sk1 (write-session store nil {:library "Monger"})
sk2 (write-session store sk1 {:library "Ring"})
m (read-session store sk2)]
(is (and sk1 sk2))
(is (and (:_id m) (:date m)))
(is (= sk1 sk2))
(is (= (dissoc m :_id :date)
{:library "Ring"}))))
(deftest test-deleting-a-session
(let [store (monger-store)
sk (write-session store nil {:library "Monger"})]
(is (nil? (delete-session store sk)))
(is (= {} (read-session store sk)))))