summaryrefslogtreecommitdiff
path: root/src/user.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/user.clj')
-rw-r--r--src/user.clj93
1 files changed, 35 insertions, 58 deletions
diff --git a/src/user.clj b/src/user.clj
index 8380bce..c516fd2 100644
--- a/src/user.clj
+++ b/src/user.clj
@@ -1,5 +1,7 @@
(ns user
- (:use compojure
+ (:use clojure.contrib.sql
+ compojure
+ cache-dot-clj.cache
utils))
(defstruct user-struct :nick :user_id :avatar :last-seen)
@@ -18,71 +20,38 @@
;;; User info cache
-(def user-cache-size 99999)
-(def user-nick-cache (ref {}))
-(def user-id-cache (ref {}))
+(defn-cached fetch-nick-cached
+ (lru-cache-strategy 2000)
+ "Retrieves user info from database"
+ [nick]
+ (first (do-select ["SELECT * FROM users WHERE lower(nick) = ? LIMIT 1"
+ (lower-case nick)])))
-(defn update-cache! [uid attr val]
- (dosync
- (if-let [info (get @user-id-cache uid)]
- (let [nick (lower-case (:nick info))
- new-info (assoc info attr val)]
- (alter user-id-cache assoc uid new-info)
- (alter user-nick-cache assoc nick new-info)))))
-
+(def fetch-nick (comp fetch-nick-cached lower-case))
-(defn fetch-nick [nick]
- (let [lcnick (lower-case nick)]
- (if (contains? user-nick-cache lcnick)
- (get user-nick-cache lcnick)
- (let [info (first
- (do-select ["SELECT * FROM users WHERE lower(nick) = ? LIMIT 1"
- lcnick]))
- user-id (:user_id info)]
- (dosync
- (alter user-nick-cache assoc lcnick info)
- (if (and info user-id)
- (alter user-id-cache assoc user-id info)))
- info))))
+(defn-cached nick-from-user-id
+ (lru-cache-strategy 10000)
+ "Retrieves nick for user id"
+ [uid]
+ (:nick (first (do-select ["SELECT nick FROM users WHERE user_id = ? LIMIT 1" uid]))))
-(defn fetch-nicks [nicks]
- (let [lcnicks (map lower-case nicks)
- cache @user-nick-cache
- to-fetch (filter #(not (contains? cache %)) lcnicks)
- fetched-info (do-select ["SELECT * FROM users WHERE lower(nick) = ANY(?)"
- (sql-array "text" to-fetch)])
- info-map (zipmap (map (comp lower-case :nick) fetched-info)
- fetched-info)]
- (doseq [nick to-fetch]
- (let [info (get info-map nick)]
- (dosync
- (alter user-nick-cache assoc nick info)
- (if info
- (alter user-id-cache assoc (:user_id info) info)))))
- (filter
- boolean
- (for [nick lcnicks]
- (get @user-nick-cache nick)))))
+(def fetch-user-id
+ (comp fetch-nick nick-from-user-id))
-(defn fetch-user-id [uid]
- (if (contains? @user-id-cache uid)
- (get @user-id-cache uid)
- (if-let [info (first
- (do-select ["SELECT * FROM users WHERE user_id = ? LIMIT 1" uid]))]
- (dosync
- (alter user-nick-cache assoc (lower-case (:nick info)) info)
- (alter user-id-cache assoc uid info)))))
+(def user-id-from-nick
+ (comp :user_id fetch-nick))
+
+;; user login
(defn authorize-nick-hash [nick hash]
- (let [db-user (fetch-nick nick)]
- (and db-user (= (db-user :hash) hash) db-user)))
+ (if-let [db-user (fetch-nick nick)]
+ (and (= (db-user :hash) hash) db-user)))
(defn update-nick-hash [nick hash]
- (if (not (assert-update
- (do-update :users ["nick=?" nick]
- {:hash hash})))
- ; TODO: logging
- (println (format "Error updating hash for %s" nick))))
+ (do-update :users ["nick=?" nick]
+ {:hash hash}))
+
+;; user pw reset
(defn reset-token [nick hash ts]
(sha1-hash nick hash ts))
@@ -96,3 +65,11 @@
(if-let [info (and nick (fetch-nick nick))]
(and (= token (reset-token (info :nick) (info :hash) ts))
(>= ts (ms-ago (days 2))))))
+
+
+;; user db update & cache invalidation
+
+(defn update-user-info! [nick user-id attr val]
+ (with-connection *db*
+ (update-values "users" ["user_id = ?" user-id] {attr val}))
+ (invalidate-cache fetch-nick-cached (lower-case nick)))