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