summaryrefslogtreecommitdiff
path: root/src/user.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/user.clj')
-rw-r--r--src/user.clj60
1 files changed, 55 insertions, 5 deletions
diff --git a/src/user.clj b/src/user.clj
index 1d59944..7641bd8 100644
--- a/src/user.clj
+++ b/src/user.clj
@@ -16,12 +16,62 @@
(> (count n) 16) "NICK_TOO_LONG"
(not (re-matches *nick-regex* n)) "NICK_INVALID_CHARS"))
+;;; User info cache
+
+(def user-cache-size 500)
+(def user-nick-cache (ref {}))
+(def user-id-cache (ref {}))
+
+(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)))))
+
+
(defn fetch-nick [nick]
- (let [q1 "SELECT * FROM users WHERE nick = ? LIMIT 1"
- ; ORDER BY ensures consistent retrieval of ambiguious names
- q2 "SELECT * FROM users WHERE lower(nick) = ? ORDER BY nick LIMIT 1"]
- (or (first-or-nil (do-select [q1 nick]))
- (first-or-nil (do-select [q2 (lower-case 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 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)))))
+
+(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)))))
(defn authorize-nick-hash [nick hash]
(let [db-user (fetch-nick nick)]