Browse Source

migrated to carmine

master
Christian Mueller 12 years ago
parent
commit
6c5121e865
  1. 1
      Makefile
  2. 2
      project.clj
  3. 1
      settings
  4. 5
      src/NoteHub/api.clj
  5. 125
      src/NoteHub/storage.clj
  6. 2
      test/NoteHub/test/api.clj

1
Makefile

@ -3,5 +3,4 @@ run:
lein run dev lein run dev
server: server:
lein cljsbuild auto &
redis-server & redis-server &

2
project.clj

@ -4,7 +4,7 @@
[hiccup "1.0.0"] [hiccup "1.0.0"]
[cheshire "5.3.1"] [cheshire "5.3.1"]
[ring/ring-core "1.1.0"] [ring/ring-core "1.1.0"]
[clj-redis "0.0.12"] [com.taoensso/carmine "2.4.4"]
[noir "1.3.0-beta1"]] [noir "1.3.0-beta1"]]
:jvm-opts ["-Dfile.encoding=utf-8"] :jvm-opts ["-Dfile.encoding=utf-8"]
:main NoteHub.server) :main NoteHub.server)

1
settings

@ -1,2 +1,3 @@
max-title-length = 40 max-title-length = 40
domain = http://notehub.org domain = http://notehub.org
db-url = http://localhost:6379

5
src/NoteHub/api.clj

@ -9,7 +9,7 @@
[ring.util.codec] [ring.util.codec]
[NoteHub.storage :as storage])) [NoteHub.storage :as storage]))
(def version "1.0") (def version "1.1")
(def domain (get-setting :domain)) (def domain (get-setting :domain))
@ -45,8 +45,7 @@
(if description (if description
(str domain "/" (storage/get-short-url noteID)) (str domain "/" (storage/get-short-url noteID))
(let [[year month day title] (split noteID #" ")] (let [[year month day title] (split noteID #" ")]
(apply str (interpose "/" (apply str (interpose "/" [domain year month day (ring.util.codec/url-encode title)])))))
[domain year month day (ring.util.codec/url-encode title)])))))
(let [md5Instance (java.security.MessageDigest/getInstance "MD5")] (let [md5Instance (java.security.MessageDigest/getInstance "MD5")]
(defn get-signature (defn get-signature

125
src/NoteHub/storage.clj

@ -3,18 +3,18 @@
[clojure.string :only (blank?)] [clojure.string :only (blank?)]
[noir.util.crypt :only [encrypt]] [noir.util.crypt :only [encrypt]]
[noir.options :only [dev-mode?]]) [noir.options :only [dev-mode?]])
(:require [clj-redis.client :as redis])) (:require [taoensso.carmine :as car :refer (wcar)]))
; Initialize the data base (def conn {:pool {} :spec {:uri (get-setting :db-url)}})
(def db (defmacro redis [cmd & body]
(redis/init `(car/wcar conn
(when-not (dev-mode?) (~(symbol "car" (name cmd))
{:url (get-setting :db-url)}))) ~@body)))
(defn get-current-date [] (defn get-current-date []
(str (java.util.Date.))) (str (java.util.Date.)))
; DB hierarchy levels ; hierarchy levels
(def note "note") (def note "note")
(def published "published") (def published "published")
(def edited "edited") (def edited "edited")
@ -26,107 +26,90 @@
(def publisher-key "publisher-key") (def publisher-key "publisher-key")
(defn valid-publisher? [pid] (defn valid-publisher? [pid]
(redis/hexists db publisher-key pid)) (= 1 (redis :hexists publisher-key pid)))
(defn register-publisher [pid] (defn register-publisher [pid]
"Returns nil if given PID exists or a PSK otherwise" "Returns nil if given PID exists or a PSK otherwise"
(when (not (valid-publisher? pid)) (when (not (valid-publisher? pid))
(let [psk (encrypt (str (rand-int Integer/MAX_VALUE) pid)) (let [psk (encrypt (str (rand-int Integer/MAX_VALUE) pid))]
_ (redis/hset db publisher-key pid psk)] (redis :hset publisher-key pid psk)
psk))) psk)))
(defn revoke-publisher [pid] (defn revoke-publisher [pid]
(redis/hdel db publisher-key pid)) (redis :hdel publisher-key pid))
(defn get-psk [pid] (defn get-psk [pid]
(redis/hget db publisher-key pid)) (redis :hget publisher-key pid))
(defn create-session [] (defn create-session []
(let [token (encrypt (str (rand-int Integer/MAX_VALUE)))] (let [token (encrypt (str (rand-int Integer/MAX_VALUE)))]
(do (redis/sadd db sessions token) (do (redis :sadd sessions token)
token))) token)))
(defn invalidate-session [token] (defn invalidate-session [token]
(let [was-valid (redis/sismember db sessions token)] (let [was-valid (redis :sismember sessions token)]
(redis/srem db sessions token) (redis :srem sessions token)
was-valid)) (= 1 was-valid)))
(defn edit-note (defn edit-note [noteID text]
[noteID text] (redis :hset edited noteID (get-current-date))
(do (redis :hset note noteID text))
(redis/hset db edited noteID (get-current-date))
(redis/hset db note noteID text)))
(defn add-note (defn add-note
([noteID text pid] (add-note noteID text pid nil)) ([noteID text pid] (add-note noteID text pid nil))
([noteID text pid passwd] ([noteID text pid passwd]
(do (redis :hset note noteID text)
(redis/hset db note noteID text) (redis :hset published noteID (get-current-date))
(redis/hset db published noteID (get-current-date)) (redis :hset publisher noteID pid)
(redis/hset db publisher noteID pid)
(when (not (blank? passwd)) (when (not (blank? passwd))
(redis/hset db password noteID passwd))))) (redis :hset password noteID passwd))))
(defn valid-password? [noteID passwd] (defn valid-password? [noteID passwd]
(let [stored (redis/hget db password noteID)] (let [stored (redis :hget password noteID)]
(and stored (= stored passwd)))) (and (not (= 0 stored)) (= stored passwd))))
(defn get-note
[noteID]
(let [text (redis/hget db note noteID)]
(when text
(do
(redis/hincrby db views noteID 1)
text))))
(defn get-note-views (defn get-note-views [noteID]
[noteID] (redis :hget views noteID))
(redis/hget db views noteID))
(defn get-publisher (defn get-publisher [noteID]
[noteID] (redis :hget publisher noteID))
(redis/hget db publisher noteID))
(defn get-note-statistics (defn get-note-statistics [noteID]
"Return views, publishing and editing timestamp"
[noteID]
{:views (get-note-views noteID) {:views (get-note-views noteID)
:published (redis/hget db published noteID) :published (redis :hget published noteID)
:edited (redis/hget db edited noteID) :edited (redis :hget edited noteID)
:publisher (get-publisher noteID)}) :publisher (get-publisher noteID)})
(defn note-exists? (defn note-exists? [noteID]
[noteID] (= 1 (redis :hexists note noteID)))
(redis/hexists db note noteID))
(defn get-note [noteID]
(when (note-exists? noteID)
(do
(redis :hincrby views noteID 1)
(redis :hget note noteID))))
(defn delete-note (defn delete-note [noteID]
[noteID]
(doseq [kw [password views note published edited publisher]] (doseq [kw [password views note published edited publisher]]
; TODO: delete short url by looking for the title ; TODO: delete short url by looking for the title
(redis/hdel db kw noteID))) (redis :hdel kw noteID)))
(defn short-url-exists? (defn short-url-exists? [url]
"Checks whether the provided short url is taken (for testing only)" (= 1 (redis :hexists short-url url)))
[url]
(redis/hexists db short-url url))
(defn get-short-url [noteID] (defn get-short-url [noteID]
(redis/hget db short-url noteID)) (redis :hget short-url noteID))
(defn resolve-url (defn resolve-url [url]
"Resolves short url by providing all metadata of the request" (let [value (redis :hget short-url url)]
[url]
(let [value (redis/hget db short-url url)]
(when value (when value
(read-string value)))) (read-string value))))
(defn delete-short-url (defn delete-short-url [noteID]
"Deletes a short url (for testing only)" (let [value (redis :hget short-url noteID)]
[noteID]
(let [value (redis/hget db short-url noteID)]
(do (do
(redis/hdel db short-url noteID) (redis :hdel short-url noteID)
(redis/hdel db short-url value)))) (redis :hdel short-url value))))
(defn create-short-url (defn create-short-url
"Creates a short url for the given request metadata or noteID or extracts "Creates a short url for the given request metadata or noteID or extracts
@ -134,7 +117,7 @@
[arg] [arg]
(let [key (if (map? arg) (str (into (sorted-map) arg)) arg)] (let [key (if (map? arg) (str (into (sorted-map) arg)) arg)]
(if (short-url-exists? key) (if (short-url-exists? key)
(redis/hget db short-url key) (redis :hget short-url key)
(let [hash-stream (partition 5 (repeatedly #(rand-int 36))) (let [hash-stream (partition 5 (repeatedly #(rand-int 36)))
hash-to-string (fn [hash] hash-to-string (fn [hash]
(apply str (apply str
@ -147,6 +130,6 @@
(do (do
; we create two mappings: key params -> short url and back, ; we create two mappings: key params -> short url and back,
; s.t. we can later easily check whether a short url already exists ; s.t. we can later easily check whether a short url already exists
(redis/hset db short-url url key) (redis :hset short-url url key)
(redis/hset db short-url key url) (redis :hset short-url key url)
url))))) url)))))

2
test/NoteHub/test/api.clj

@ -37,9 +37,9 @@
(isnt (storage/valid-publisher? pid2)))) (isnt (storage/valid-publisher? pid2))))
(testing "note publishing & retrieval" (testing "note publishing & retrieval"
(isnt (:success (:status (get-note "some note id")))) (isnt (:success (:status (get-note "some note id"))))
(is (= "note is empty" (:message (:status (post-note "" pid (get-signature pid psk ""))))))
(let [post-response (post-note note pid (get-signature pid psk note)) (let [post-response (post-note note pid (get-signature pid psk note))
get-response (get-note (:noteID post-response))] get-response (get-note (:noteID post-response))]
(is (= "note is empty" (:message (:status (post-note "" pid (get-signature pid psk ""))))))
(is (:success (:status post-response))) (is (:success (:status post-response)))
(is (:success (:status get-response))) (is (:success (:status get-response)))
(is (= note (:note get-response))) (is (= note (:note get-response)))

Loading…
Cancel
Save