Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
d5cce8c97b
7 changed files with 118 additions and 35 deletions
44
ChangeLog.md
Normal file
44
ChangeLog.md
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
## Changes between 1.0.0-beta1 and 1.0.0-beta2
|
||||||
|
|
||||||
|
### 3-arity of monger.collection/find-one-as-map now takes a vector of fields
|
||||||
|
|
||||||
|
3-arity of monger.collection/find-one-as-map now takes a vector of fields
|
||||||
|
instead of `keywordize` to better fit a more commonly needed case.
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
;; 3-arity in 1.0.0-beta1
|
||||||
|
(monger.collection/find-one-as-map "documents" { :first_name "John" } false)
|
||||||
|
```
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
;; 3-arity in 1.0.0-beta2
|
||||||
|
(monger.collection/find-one-as-map "documents" { :first_name "John" } [:first_name, :last_name, :age])
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
If you need to use `keywordize`, use 4-arity:
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
(monger.collection/find-one-as-map "documents" { :first_name "John" } [:first_name, :last_name, :age] false)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Query DSL has a way to specify if fields need to be keywordized
|
||||||
|
|
||||||
|
It is now possible to opt-out of field keywordization in the query DSL:
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
(with-collection coll
|
||||||
|
(find {})
|
||||||
|
(limit 3)
|
||||||
|
(sort { :population -1 })
|
||||||
|
(keywordize-fields false))
|
||||||
|
```
|
||||||
|
|
||||||
|
the default value is still true, field names will be converted to keywords.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### monger.collection/find-by-id and /find-map-by-id fail fast when id is nil
|
||||||
|
|
||||||
|
monger.collection/find-by-id and /find-map-by-id now will throw IllegalArgumentException when id is nil
|
||||||
10
README.md
10
README.md
|
|
@ -216,13 +216,13 @@ for client libraries like Monger.
|
||||||
Here is what monger.query DSL feels like:
|
Here is what monger.query DSL feels like:
|
||||||
|
|
||||||
``` clojure
|
``` clojure
|
||||||
(with-collection "docs"
|
(with-collection "movies"
|
||||||
(find { :inception_year { $lt 2000 $gte 2011 } })
|
(find { :year { $lt 2010 $gte 2000 }, :revenue { $gt 20000000 } })
|
||||||
(fields [ :inception_year :name ])
|
(fields [ :year :title :producer :cast :budget :revenue ])
|
||||||
|
(sort-by { :revenue -1 })
|
||||||
(skip 10)
|
(skip 10)
|
||||||
(limit 20)
|
(limit 20)
|
||||||
(batch-size 50)
|
(hint "year-by-year-revenue-idx")
|
||||||
(hint "my-index-name")
|
|
||||||
(snapshot))
|
(snapshot))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
[com.novemberain/validateur "1.0.0"]]
|
[com.novemberain/validateur "1.0.0"]]
|
||||||
}
|
}
|
||||||
:dev-dependencies [[org.clojure/data.json "0.1.2" :exclusions [org.clojure/clojure]]
|
:dev-dependencies [[org.clojure/data.json "0.1.2" :exclusions [org.clojure/clojure]]
|
||||||
[clj-time "0.3.3" :exclusions [org.clojure/clojure]]
|
[clj-time "0.3.6" :exclusions [org.clojure/clojure]]
|
||||||
[codox "0.3.4" :exclusions [org.clojure/clojure]]]
|
[codox "0.3.4" :exclusions [org.clojure/clojure]]]
|
||||||
:dev-resources-path "test/resources"
|
:dev-resources-path "test/resources"
|
||||||
:warn-on-reflection true
|
:warn-on-reflection true
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,20 @@
|
||||||
(:require [monger core result])
|
(:require [monger core result])
|
||||||
(:use [monger.conversion]))
|
(:use [monger.conversion]))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Implementation
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defn- fields-to-db-object
|
||||||
|
[^List fields]
|
||||||
|
(zipmap fields (repeat 1)))
|
||||||
|
|
||||||
|
(definline check-not-nil!
|
||||||
|
[ref message]
|
||||||
|
`(when (nil? ~ref)
|
||||||
|
(throw (IllegalArgumentException. ~message))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; API
|
;; API
|
||||||
;;
|
;;
|
||||||
|
|
@ -66,7 +80,6 @@
|
||||||
;;
|
;;
|
||||||
;; monger.collection/find
|
;; monger.collection/find
|
||||||
;;
|
;;
|
||||||
(declare fields-to-db-object)
|
|
||||||
|
|
||||||
(defn ^DBCursor find
|
(defn ^DBCursor find
|
||||||
"Queries for objects in this collection.
|
"Queries for objects in this collection.
|
||||||
|
|
@ -161,12 +174,6 @@
|
||||||
(from-db-object ^DBObject (find-one collection ref fields) keywordize)))
|
(from-db-object ^DBObject (find-one collection ref fields) keywordize)))
|
||||||
|
|
||||||
|
|
||||||
; ([^String collection ^Map ref keywordize]
|
|
||||||
; (from-db-object ^DBObject (find-one collection ref fields) keywordize))
|
|
||||||
; ([^String collection ^Map ref ^List fields keywordize]
|
|
||||||
; (from-db-object ^DBObject (find-one collection ref fields) keywordize)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; monger.collection/find-by-id
|
;; monger.collection/find-by-id
|
||||||
|
|
@ -177,26 +184,32 @@
|
||||||
|
|
||||||
EXAMPLES:
|
EXAMPLES:
|
||||||
|
|
||||||
(mgcol/find-one-by-id collection \"4ef45ab4744e9fd632640e2d\")
|
(mgcol/find-one-by-id collection (ObjectId. \"4ef45ab4744e9fd632640e2d\"))
|
||||||
|
|
||||||
;; Return only :language field.
|
;; Return only :language field.
|
||||||
;; Note that _id field is always returned.
|
;; Note that _id field is always returned.
|
||||||
(mgcol/find-one-by-id collection \"4ef45ab4744e9fd632640e2d\" [:language])
|
(mgcol/find-one-by-id collection (ObjectId. \"4ef45ab4744e9fd632640e2d\") [:language])
|
||||||
"
|
"
|
||||||
([^String collection id]
|
([^String collection id]
|
||||||
|
(check-not-nil! id "id must not be nil")
|
||||||
(find-one collection { :_id id }))
|
(find-one collection { :_id id }))
|
||||||
([^String collection id ^List fields]
|
([^String collection id ^List fields]
|
||||||
|
(check-not-nil! id "id must not be nil")
|
||||||
(find-one collection { :_id id } fields))
|
(find-one collection { :_id id } fields))
|
||||||
([^DB db ^String collection id ^List fields]
|
([^DB db ^String collection id ^List fields]
|
||||||
|
(check-not-nil! id "id must not be nil")
|
||||||
(find-one db collection { :_id id } fields)))
|
(find-one db collection { :_id id } fields)))
|
||||||
|
|
||||||
(defn ^IPersistentMap find-map-by-id
|
(defn ^IPersistentMap find-map-by-id
|
||||||
"Returns a single object, converted to map with matching _id field."
|
"Returns a single object, converted to map with matching _id field."
|
||||||
([^String collection id]
|
([^String collection id]
|
||||||
|
(check-not-nil! id "id must not be nil")
|
||||||
(from-db-object ^DBObject (find-one-as-map collection { :_id id }) true))
|
(from-db-object ^DBObject (find-one-as-map collection { :_id id }) true))
|
||||||
([^String collection id keywordize]
|
([^String collection id keywordize]
|
||||||
|
(check-not-nil! id "id must not be nil")
|
||||||
(from-db-object ^DBObject (find-one-as-map collection { :_id id }) keywordize))
|
(from-db-object ^DBObject (find-one-as-map collection { :_id id }) keywordize))
|
||||||
([^String collection id ^List fields keywordize]
|
([^String collection id ^List fields keywordize]
|
||||||
|
(check-not-nil! id "id must not be nil")
|
||||||
(from-db-object ^DBObject (find-one-as-map collection { :_id id } fields) keywordize)))
|
(from-db-object ^DBObject (find-one-as-map collection { :_id id } fields) keywordize)))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -509,13 +522,3 @@
|
||||||
([^DB db ^String collection ^String key ^Map query]
|
([^DB db ^String collection ^String key ^Map query]
|
||||||
(let [^DBCollection coll (.getCollection db collection)]
|
(let [^DBCollection coll (.getCollection db collection)]
|
||||||
(.distinct coll ^String (to-db-object key) ^DBObject (to-db-object query)))))
|
(.distinct coll ^String (to-db-object key) ^DBObject (to-db-object query)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Implementation
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defn- fields-to-db-object
|
|
||||||
[^List fields]
|
|
||||||
(zipmap fields (repeat 1)))
|
|
||||||
|
|
|
||||||
|
|
@ -36,14 +36,15 @@
|
||||||
(defn empty-query
|
(defn empty-query
|
||||||
([]
|
([]
|
||||||
{
|
{
|
||||||
:query {}
|
:query {}
|
||||||
:sort {}
|
:sort {}
|
||||||
:fields []
|
:fields []
|
||||||
:skip 0
|
:skip 0
|
||||||
:limit 0
|
:limit 0
|
||||||
:batch-size 256
|
:batch-size 256
|
||||||
:hint nil
|
:hint nil
|
||||||
:snapshot false
|
:snapshot false
|
||||||
|
:keywordize-fields true
|
||||||
})
|
})
|
||||||
([^DBCollection coll]
|
([^DBCollection coll]
|
||||||
(merge (empty-query) { :collection coll })))
|
(merge (empty-query) { :collection coll })))
|
||||||
|
|
@ -53,7 +54,7 @@
|
||||||
(to-db-object (zipmap fields (repeat 1))))
|
(to-db-object (zipmap fields (repeat 1))))
|
||||||
|
|
||||||
(defn exec
|
(defn exec
|
||||||
[{ :keys [collection query fields skip limit sort batch-size hint snapshot read-preference] :or { limit 0 batch-size 256 skip 0 } }]
|
[{ :keys [collection query fields skip limit sort batch-size hint snapshot read-preference keywordize-fields] :or { limit 0 batch-size 256 skip 0 } }]
|
||||||
(let [cursor (doto ^DBCursor (.find ^DBCollection collection (to-db-object query) (fields-to-db-object fields))
|
(let [cursor (doto ^DBCursor (.find ^DBCollection collection (to-db-object query) (fields-to-db-object fields))
|
||||||
(.limit limit)
|
(.limit limit)
|
||||||
(.skip skip)
|
(.skip skip)
|
||||||
|
|
@ -64,7 +65,7 @@
|
||||||
(.snapshot cursor))
|
(.snapshot cursor))
|
||||||
(when read-preference
|
(when read-preference
|
||||||
(.setReadPreference cursor read-preference))
|
(.setReadPreference cursor read-preference))
|
||||||
(map (fn [x] (from-db-object x true))
|
(map (fn [x] (from-db-object x keywordize-fields))
|
||||||
(seq cursor))))
|
(seq cursor))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
@ -107,6 +108,10 @@
|
||||||
[m ^ReadPreference rp]
|
[m ^ReadPreference rp]
|
||||||
(merge m { :read-preference rp }))
|
(merge m { :read-preference rp }))
|
||||||
|
|
||||||
|
(defn keywordize-fields
|
||||||
|
[m bool]
|
||||||
|
(merge m { :keywordize-fields bool }))
|
||||||
|
|
||||||
(defn paginate
|
(defn paginate
|
||||||
[m & { :keys [page per-page] :or { page 1 per-page 10 } }]
|
[m & { :keys [page per-page] :or { page 1 per-page 10 } }]
|
||||||
(merge m { :limit per-page :skip (monger.internal.pagination/offset-for page per-page) }))
|
(merge m { :limit per-page :skip (monger.internal.pagination/offset-for page per-page) }))
|
||||||
|
|
|
||||||
|
|
@ -260,3 +260,23 @@
|
||||||
(merge top3)
|
(merge top3)
|
||||||
(merge by-population-desc))]
|
(merge by-population-desc))]
|
||||||
(is (= result [ca-doc tx-doc ny-doc]))))
|
(is (= result [ca-doc tx-doc ny-doc]))))
|
||||||
|
|
||||||
|
(deftest combined-querying-dsl-example2
|
||||||
|
(let [coll "docs"
|
||||||
|
ma-doc { :_id (ObjectId.) :name "Massachusetts" :iso "MA" :population 6547629 :joined_in 1788 :capital "Boston" }
|
||||||
|
de-doc { :_id (ObjectId.) :name "Delaware" :iso "DE" :population 897934 :joined_in 1787 :capital "Dover" }
|
||||||
|
ny-doc { :_id (ObjectId.) :name "New York" :iso "NY" :population 19378102 :joined_in 1788 :capital "Albany" }
|
||||||
|
ca-doc { :_id (ObjectId.) :name "California" :iso "CA" :population 37253956 :joined_in 1850 :capital "Sacramento" }
|
||||||
|
tx-doc { :_id (ObjectId.) :name "Texas" :iso "TX" :population 25145561 :joined_in 1845 :capital "Austin" }
|
||||||
|
top3 (partial-query (limit 3))
|
||||||
|
by-population-desc (partial-query (sort { :population -1 }))
|
||||||
|
_ (mgcol/insert-batch coll [ma-doc de-doc ny-doc ca-doc tx-doc])
|
||||||
|
result (with-collection coll
|
||||||
|
(find {})
|
||||||
|
(merge top3)
|
||||||
|
(merge by-population-desc)
|
||||||
|
(keywordize-fields false))]
|
||||||
|
;; documents have fields as strings,
|
||||||
|
;; not keywords
|
||||||
|
(is (= (map #(% "name") result)
|
||||||
|
(map #(% :name) [ca-doc tx-doc ny-doc])))))
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,11 @@
|
||||||
doc-id (monger.util/random-uuid)]
|
doc-id (monger.util/random-uuid)]
|
||||||
(is (nil? (mgcol/find-by-id collection doc-id)))))
|
(is (nil? (mgcol/find-by-id collection doc-id)))))
|
||||||
|
|
||||||
|
(deftest find-full-document-by-string-id-when-id-is-nil
|
||||||
|
(let [collection "libraries"
|
||||||
|
doc-id nil]
|
||||||
|
(is (thrown? IllegalArgumentException (mgcol/find-by-id collection doc-id)))))
|
||||||
|
|
||||||
(deftest find-full-document-by-object-id-when-that-document-does-not-exist
|
(deftest find-full-document-by-object-id-when-that-document-does-not-exist
|
||||||
(let [collection "libraries"
|
(let [collection "libraries"
|
||||||
doc-id (ObjectId.)]
|
doc-id (ObjectId.)]
|
||||||
|
|
@ -111,6 +116,12 @@
|
||||||
doc-id (monger.util/random-uuid)]
|
doc-id (monger.util/random-uuid)]
|
||||||
(is (nil? (mgcol/find-map-by-id collection doc-id)))))
|
(is (nil? (mgcol/find-map-by-id collection doc-id)))))
|
||||||
|
|
||||||
|
(deftest find-full-document-by-id-as-map-when-id-is-nil
|
||||||
|
(let [collection "libraries"
|
||||||
|
doc-id nil]
|
||||||
|
(is (thrown? IllegalArgumentException
|
||||||
|
(mgcol/find-map-by-id collection doc-id)))))
|
||||||
|
|
||||||
|
|
||||||
(deftest find-full-document-by-string-id-when-document-does-exist
|
(deftest find-full-document-by-string-id-when-document-does-exist
|
||||||
(let [collection "libraries"
|
(let [collection "libraries"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue