diff options
Diffstat (limited to 'src/user.clj')
| -rw-r--r-- | src/user.clj | 93 |
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))) |
