Reputation: 4173
If I'm using a Clojure atom to keep count of something (votes for example), I can do this:
(def votes (atom {}))
(defn vote! [candidate]
(swap! votes update-in [candidate] (fnil inc 0)))
(vote! "Abraham Lincoln")
(vote! "Abraham Lincoln")
(vote! "Winston Churchill")
votes ;=> {"Abraham Lincoln" 2, "Winston Churchill" 2}
Here, update-in
neatly transforms the value at the given key, without having to look it up first.
How can I accomplish the same in Datomic? I could do something like this...
(defn vote! [db candidate]
(let [[e v] (first (q '[:find ?e ?v
:in $ ?candidate
:where [[?e :name ?candidate]
[?e :votes ?v]] db candidate)
(transact! conn [{:db/id e :votes (inc v)}]))
But it seems a bit cumbersome, having to run the query, return the value and then transact with the new value. Is there a more idiomatic way of doing this (like a swap!
or update-in
)?
Upvotes: 1
Views: 141
Reputation: 494
To me it seems most idiomatic to record the fact of the vote, then make a count query when you want to know the total. Depending on the needs of your application, this approach supports things like checking for double votes, vote change/retraction, counts in the last 24 hours, ...
Upvotes: 3