/
mongo.clj
67 lines (60 loc) · 2.41 KB
/
mongo.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
(ns foreclojure.mongo
(:use somnium.congomongo
[foreclojure.data-set :only [load-problems]]
[foreclojure.config :only [config]]
[foreclojure.problems :only [number-from-mongo-key solved-stats get-problem-list]]
[foreclojure.users :only [get-users]]))
(defn connect-to-db []
(let [{:keys [db-user db-pwd db-host db-name]} config]
(mongo!
:host (or db-host "localhost")
:db (or db-name "mydb"))
(when (and db-user db-pwd)
(authenticate db-user db-pwd))))
(defn prepare-problems []
(when-not (fetch-one :problems)
(load-problems))
(add-index! :problems [:solved]))
(defn prepare-seqs []
(update! :seqs
{:_id "problems"}
{:$set {:seq (->> (fetch :problems :only [:_id])
(map :_id)
(apply max)
(inc))}}))
;; make it easier to get off the ground by marking contributors automatically
;; useful since some "in-development" features aren't enabled for all users
(defn prepare-users []
(add-index! :users [:user] :unique true)
(add-index! :users [[:solved -1]])
(add-index! :users [:email])
(update! :users
{:user {:$in (:contributors config)}}
{:$set {:contributor true}}
:upsert false
:multiple true))
(defn prepare-solutions []
(add-index! :solutions [:user :problem]))
(defn reconcile-solved-count
"Overwrites the times-solved field in the problems collection based on data from the users collection. Should only be called on server startup since it isn't a safe operation. Also updates the total-solved agent."
[]
(let [+ (fnil + 0)
users (fetch :users :only [:scores :solved])
scores (->> users
(mapcat :scores)
(frequencies)
(reduce (fn [scores [[id score] times]]
(update-in scores
[(number-from-mongo-key id) score]
+ times))
{}))
solved-counts (frequencies (map int (mapcat :solved users)))
total (reduce + (vals solved-counts))]
(send solved-stats (constantly (assoc scores :total total :solved-counts solved-counts)))))
(defn prepare-mongo []
(connect-to-db)
(prepare-problems)
(prepare-seqs)
(prepare-users)
(prepare-solutions)
(reconcile-solved-count))