Adding operators DSL in order to use Clojure functions instead of hashes.

Casbah has a similar concept called Bareword Operators.
Korma uses operators a bit differently, but idea is quite same, too. 

One of the obvious advantages is that you can make sure you didn't screw make a typo 
in operator name during compile-time. Plus, we can guarantee that there is a subset
of used / supported operators, and add them gradually, keeping track of them in one place, 
which will simplify tests, too.
This commit is contained in:
Oleksandr Petrov 2011-11-08 00:12:10 +01:00
parent 6dd3491d39
commit bb169d3ae3
2 changed files with 44 additions and 13 deletions

28
src/monger/operators.clj Normal file
View file

@ -0,0 +1,28 @@
(ns monger.operators)
(defmacro defoperator
[operator]
(let [operator-name (symbol (str operator))]
`(defn ~operator-name
[arg#]
{ (str '~operator-name) arg# }
)))
(defoperator $gt)
(defoperator $inc)
(defoperator $set)
(defoperator $unset)
;; $lt
;; $lte
;; $all
;; $in
;; $set
;; $unset
;; $inc
;; $push
;; $pushAll
;; $addToSet
;; $pop
;; $pull
;; $pullAll
;; $rename

View file

@ -3,14 +3,16 @@
(ns monger.test.atomic-modifiers (ns monger.test.atomic-modifiers
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject CommandResult$CommandFailure] (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject CommandResult$CommandFailure]
[org.bson.types ObjectId] [org.bson.types ObjectId]
[java.util Date]) [java.util Date]
)
(:require [monger core util] (:require [monger core util]
[monger.collection :as mgcol] [monger.collection :as mgcol]
[monger.result :as mgres]) [monger.result :as mgres])
(:use [clojure.test] (:use [clojure.test]
[monger.operators]
[monger.test.fixtures])) [monger.test.fixtures]))
(defn purge-scores-collection (defn purge-scores-collection
[f] [f]
(purge-collection "scores" f)) (purge-collection "scores" f))
@ -28,8 +30,9 @@
(deftest increment-a-single-existing-field-using-$inc-modifier (deftest increment-a-single-existing-field-using-$inc-modifier
(let [coll "scores" (let [coll "scores"
oid (ObjectId.)] oid (ObjectId.)]
(println ($inc { :score 20 } ))
(mgcol/insert coll { :_id oid :username "l33r0y" :score 100 }) (mgcol/insert coll { :_id oid :username "l33r0y" :score 100 })
(mgcol/update coll { :_id oid } { "$inc" { :score 20 } }) (mgcol/update coll { :_id oid } ($inc { :score 20 } ))
(is (= 120 (:score (mgcol/find-map-by-id coll oid)))))) (is (= 120 (:score (mgcol/find-map-by-id coll oid))))))
@ -37,7 +40,7 @@
(let [coll "scores" (let [coll "scores"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :username "l33r0y" }) (mgcol/insert coll { :_id oid :username "l33r0y" })
(mgcol/update coll { :_id oid } { "$inc" { :score 30 } }) (mgcol/update coll { :_id oid } ($inc { :score 30 } ))
(is (= 30 (:score (mgcol/find-map-by-id coll oid)))))) (is (= 30 (:score (mgcol/find-map-by-id coll oid))))))
@ -45,7 +48,7 @@
(let [coll "scores" (let [coll "scores"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :username "l33r0y" :score 100 :bonus 0 }) (mgcol/insert coll { :_id oid :username "l33r0y" :score 100 :bonus 0 })
(mgcol/update coll { :_id oid } { "$inc" { :score 20 :bonus 10 } }) (mgcol/update coll { :_id oid } ($inc { :score 20 :bonus 10 } ))
(is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mgcol/find-map-by-id coll oid))))) (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mgcol/find-map-by-id coll oid)))))
@ -53,7 +56,7 @@
(let [coll "scores" (let [coll "scores"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :username "l33r0y" :score 100 }) (mgcol/insert coll { :_id oid :username "l33r0y" :score 100 })
(mgcol/update coll { :_id oid } { "$inc" { :score 20 :bonus 10 } }) (mgcol/update coll { :_id oid } ($inc { :score 20 :bonus 10 } ))
(is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mgcol/find-map-by-id coll oid))))) (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mgcol/find-map-by-id coll oid)))))
@ -66,21 +69,21 @@
(let [coll "things" (let [coll "things"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 }) (mgcol/insert coll { :_id oid :weight 10.0 })
(mgcol/update coll { :_id oid } { "$set" { :weight 20.5 } }) (mgcol/update coll { :_id oid } ( $set { :weight 20.5 } ))
(is (= 20.5 (:weight (mgcol/find-map-by-id coll oid [:weight])))))) (is (= 20.5 (:weight (mgcol/find-map-by-id coll oid [:weight]))))))
(deftest set-a-single-non-existing-field-using-$set-modifier (deftest set-a-single-non-existing-field-using-$set-modifier
(let [coll "things" (let [coll "things"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 }) (mgcol/insert coll { :_id oid :weight 10.0 })
(mgcol/update coll { :_id oid } { "$set" { :height 17.2 } }) (mgcol/update coll { :_id oid } ( $set { :height 17.2 } ))
(is (= 17.2 (:height (mgcol/find-map-by-id coll oid [:height])))))) (is (= 17.2 (:height (mgcol/find-map-by-id coll oid [:height]))))))
(deftest update-multiple-existing-fields-using-$set-modifier (deftest update-multiple-existing-fields-using-$set-modifier
(let [coll "things" (let [coll "things"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 :height 15.2 }) (mgcol/insert coll { :_id oid :weight 10.0 :height 15.2 })
(mgcol/update coll { :_id oid } { "$set" { :weight 20.5 :height 25.6 } }) (mgcol/update coll { :_id oid } ( $set { :weight 20.5 :height 25.6 } ))
(is (= { :_id oid :weight 20.5 :height 25.6 } (mgcol/find-map-by-id coll oid [:weight]))))) (is (= { :_id oid :weight 20.5 :height 25.6 } (mgcol/find-map-by-id coll oid [:weight])))))
@ -88,7 +91,7 @@
(let [coll "things" (let [coll "things"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 }) (mgcol/insert coll { :_id oid :weight 10.0 })
(mgcol/update coll { :_id oid } { "$set" { :weight 20.5 :height 25.6 } }) (mgcol/update coll { :_id oid } ($set { :weight 20.5 :height 25.6 } ))
(is (= { :_id oid :weight 20.5 :height 25.6 } (mgcol/find-map-by-id coll oid [:weight]))))) (is (= { :_id oid :weight 20.5 :height 25.6 } (mgcol/find-map-by-id coll oid [:weight])))))
@ -100,7 +103,7 @@
(let [coll "docs" (let [coll "docs"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :title "Document 1" :published true }) (mgcol/insert coll { :_id oid :title "Document 1" :published true })
(mgcol/update coll { :_id oid } { "$unset" { :published 1 } }) (mgcol/update coll { :_id oid } ( $unset { :published 1 } ))
(is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid))))) (is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid)))))
@ -108,7 +111,7 @@
(let [coll "docs" (let [coll "docs"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :title "Document 1" :published true :featured true }) (mgcol/insert coll { :_id oid :title "Document 1" :published true :featured true })
(mgcol/update coll { :_id oid } { "$unset" { :published 1 :featured true } }) (mgcol/update coll { :_id oid } ( $unset { :published 1 :featured true } ))
(is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid))))) (is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid)))))
@ -116,7 +119,7 @@
(let [coll "docs" (let [coll "docs"
oid (ObjectId.)] oid (ObjectId.)]
(mgcol/insert coll { :_id oid :title "Document 1" :published true }) (mgcol/insert coll { :_id oid :title "Document 1" :published true })
(is (mgres/ok? (mgcol/update coll { :_id oid } { "$unset" { :published 1 :featured true } }))) (is (mgres/ok? (mgcol/update coll { :_id oid } ( $unset { :published 1 :featured true } ))))
(is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid))))) (is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid)))))