Introduce monger.collection/insert-and-return
Per discussion in Raynes/refheap#89
This commit is contained in:
parent
8f8b4387b6
commit
080ef6b896
3 changed files with 87 additions and 7 deletions
22
ChangeLog.md
22
ChangeLog.md
|
|
@ -1,6 +1,26 @@
|
||||||
## Changes between 1.0.0-alpha3 and 1.1.0-alpha4
|
## Changes between 1.0.0-alpha3 and 1.1.0-alpha4
|
||||||
|
|
||||||
No changes yet.
|
### monger.collection/insert-and-return
|
||||||
|
|
||||||
|
`monger.collection/insert-and-return` is a new function that solves the biggest complain about Monger's `monger.collection/insert` behavior
|
||||||
|
from Monger 1.0 users. Because `monger.collection/insert` returns a write result and is supposed to be used with Validateur and
|
||||||
|
`monger.result/ok?` and similar functions, it is hard to retrieve object id in case it wasn't explicitly passed in.
|
||||||
|
|
||||||
|
This resulted in code that looks more or less like this:
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
(let [oid (ObjectId.)
|
||||||
|
result (merge doc {:_id oid)]
|
||||||
|
(monger.collection/insert "documents" result)
|
||||||
|
result)
|
||||||
|
```
|
||||||
|
|
||||||
|
To solve this problem, we introduce a new function, `monger.collection/insert-and-return`, that returns the exact inserted document
|
||||||
|
as an immutable Clojure map. The `:_id` key will be available on the returned map, even if wasn't present and had to be generated.
|
||||||
|
|
||||||
|
`monger.collection/insert` behavior stays the same both because of backwards compatibility concerns and because there are valid cases
|
||||||
|
when a user may want to have the write result returned.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Changes between 1.0.0-alpha2 and 1.1.0-alpha3
|
## Changes between 1.0.0-alpha2 and 1.1.0-alpha3
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,14 @@
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defn ^WriteResult insert
|
(defn ^WriteResult insert
|
||||||
"Saves @document@ to @collection@. You can optionally specify WriteConcern.
|
"Saves @document@ to @collection@ and returns write result monger.result/ok? and similar functions operate on. You can optionally specify WriteConcern.
|
||||||
|
|
||||||
|
In case you need the exact inserted document returned, with the :_id key generated, use monger.collection/insert-and-return
|
||||||
|
instead.
|
||||||
|
|
||||||
EXAMPLES:
|
EXAMPLES:
|
||||||
|
|
||||||
|
;; returns write result
|
||||||
(monger.collection/insert \"people\" {:name \"Joe\", :age 30})
|
(monger.collection/insert \"people\" {:name \"Joe\", :age 30})
|
||||||
|
|
||||||
(monger.collection/insert \"people\" {:name \"Joe\", :age 30, WriteConcern/SAFE})
|
(monger.collection/insert \"people\" {:name \"Joe\", :age 30, WriteConcern/SAFE})
|
||||||
|
|
@ -72,6 +76,32 @@
|
||||||
concern)))
|
concern)))
|
||||||
|
|
||||||
|
|
||||||
|
(defn ^clojure.lang.IPersistentMap insert-and-return
|
||||||
|
"Like monger.collection/insert but returns the inserted document as a persistent Clojure map.
|
||||||
|
|
||||||
|
If the :_id key wasn't set on the document, it will be generated and merged into the returned map.
|
||||||
|
|
||||||
|
EXAMPLES:
|
||||||
|
|
||||||
|
;; returns the entire document with :_id generated
|
||||||
|
(monger.collection/insert-and-return \"people\" {:name \"Joe\", :age 30})
|
||||||
|
|
||||||
|
(monger.collection/insert-and-return \"people\" {:name \"Joe\", :age 30, WriteConcern/SAFE})
|
||||||
|
"
|
||||||
|
([^String collection document]
|
||||||
|
(insert-and-return ^DB monger.core/*mongodb-database* collection document ^WriteConcern monger.core/*mongodb-write-concern*))
|
||||||
|
([^String collection document ^WriteConcern concern]
|
||||||
|
(insert-and-return ^DB monger.core/*mongodb-database* collection document concern))
|
||||||
|
([^DB db ^String collection document ^WriteConcern concern]
|
||||||
|
;; MongoDB Java driver will generate the _id and set it but it tries to mutate the inserted DBObject
|
||||||
|
;; and it does not work very well in our case, because that DBObject is short lived and produced
|
||||||
|
;; from the Clojure map we are passing in. Plus, this approach is very awkward with immutable data
|
||||||
|
;; structures being the default. MK.
|
||||||
|
(let [doc (merge document {:_id (ObjectId.)})]
|
||||||
|
(insert db collection doc concern)
|
||||||
|
doc)))
|
||||||
|
|
||||||
|
|
||||||
(defn ^WriteResult insert-batch
|
(defn ^WriteResult insert-batch
|
||||||
"Saves @documents@ do @collection@. You can optionally specify WriteConcern as a third argument.
|
"Saves @documents@ do @collection@. You can optionally specify WriteConcern as a third argument.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,36 @@
|
||||||
(is (= dbref fo)))))
|
(is (= dbref fo)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; insert-and-return
|
||||||
|
;;
|
||||||
|
|
||||||
|
(deftest insert-and-return-a-basic-document-without-id-and-with-default-write-concern
|
||||||
|
(let [collection "people"
|
||||||
|
doc {:name "Joe" :age 30}
|
||||||
|
result (mc/insert-and-return "people" doc)]
|
||||||
|
(is (= (:name doc)
|
||||||
|
(:name result)))
|
||||||
|
(is (= (:age doc)
|
||||||
|
(:age result)))
|
||||||
|
(is (:_id result))
|
||||||
|
(is (= 1 (mc/count collection)))))
|
||||||
|
|
||||||
|
(deftest insert-and-return-a-basic-document-without-id-but-with-a-write-concern
|
||||||
|
(let [collection "people"
|
||||||
|
doc {:name "Joe" :age 30 :ratio 3/4}
|
||||||
|
result (mc/insert-and-return "people" doc WriteConcern/FSYNC_SAFE)]
|
||||||
|
(is (= (:name doc)
|
||||||
|
(:name result)))
|
||||||
|
(is (= (:age doc)
|
||||||
|
(:age result)))
|
||||||
|
(is (= (:ratio doc)
|
||||||
|
(:ratio result)))
|
||||||
|
(is (:_id result))
|
||||||
|
(is (= 1 (mc/count collection)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; insert-batch
|
;; insert-batch
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue