Merge pull request #78 from michaelklishin/explicit-db-argument

Finishes #76
This commit is contained in:
Michael Klishin 2014-05-12 08:20:29 +04:00
commit da2effbfc9
50 changed files with 2614 additions and 4568 deletions

View file

@ -1,6 +1,62 @@
## Changes between 1.8.0 and 2.0.0
No changes yet.
`2.0` is a major release that has **breaking public API changes**.
### Explicit Connection/DB/GridFS Argument
In Monger 2.0, all key public API functions require an explicit
DB/connection/GridFS object to be provided instead of relying on
a shared dynamic var. This makes Monger much easier to use with
systems such as Component and Jig, as well as concurrent
applications that need to work with multiple connections, database,
or GridFS filesystems.
In other words, instead of
``` clojure
(require '[monger.collection :as mc])
(mc/insert "libraries" {:name "Monger"})
```
it is now necessary to do
``` clojure
(require '[monger.collection :as mc])
(mc/insert db "libraries" {:name "Monger"})
```
This also means that `monger.core/connect!` and
`monger.core/connect-via-uri!` were removed, as was
`monger.multi` namespaces.
To connect to MongoDB, use `monger.core/connect`:
``` clojure
(require '[monger.core :as mg])
(let [conn (mg/connect)])
```
or `monger.core/connect-via-uri`:
``` clojure
(require '[monger.core :as mg])
(let [{:keys [conn db]} (mg/connect-via-uri "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")])
```
To get a database reference, use `monger.core/get-db`, which now requires a connection
object:
``` clojure
(require '[monger.core :as mg])
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")])
```
## Changes between 1.8.0-beta2 and 1.8.0

View file

@ -40,9 +40,9 @@
[cheshire "5.3.1" :exclusions [org.clojure/clojure]]
[org.clojure/tools.cli "0.3.1" :exclusions [org.clojure/clojure]]
[org.clojure/core.cache "0.6.3" :exclusions [org.clojure/clojure]]
[ring/ring-core "1.2.1"]
[com.novemberain/validateur "2.1.0"]
[ragtime/ragtime.core "0.3.4"]]
[ring/ring-core "1.2.1" :exclusions [org.clojure/clojure]]
[com.novemberain/validateur "2.1.0" :exclusions [org.clojure/clojure]]
[ragtime/ragtime.core "0.3.4" :exclusions [org.clojure/clojure]]]
:plugins [[codox "0.6.6"]]
:codox {:sources ["src/clojure"]
:output-dir "doc/api"

View file

@ -11,7 +11,7 @@
"clojure.core.cache implementation(s) on top of MongoDB.
Related documentation guide: http://clojuremongodb.info/articles/integration.html"
(:require [monger.collection :as mc]
(:require [monger.collection :as mc :refer [find-one find-by-id find-map-by-id]]
[clojure.core.cache :as cache]
[monger.conversion :as cnv])
(:import clojure.core.cache.CacheProtocol
@ -25,87 +25,37 @@
(def ^{:const true}
default-cache-collection "cache_entries")
(defn- ^DBObject find-one
[^DB db ^String collection ^Map ref]
(.findOne (.getCollection db (name collection))
(cnv/to-db-object ref)))
(defn- find-by-id
"A version of monger.collection/find-by-id that does not require the
fields argument"
[^DB db ^String collection id]
(find-one db collection {:_id id}))
(defn- find-map-by-id
"A version of monger.collection/find-by-map-id that accepts database
as an argument"
[^DB db ^String collection id]
(cnv/from-db-object ^DBObject (find-one db collection {:_id id}) true))
;;
;; API
;;
(defrecord BasicMongerCache [collection])
(defrecord BasicMongerCache [db collection])
(extend-protocol cache/CacheProtocol
BasicMongerCache
(lookup [c k]
(let [m (mc/find-map-by-id (:collection c) k)]
(let [m (mc/find-map-by-id (:db c) (:collection c) k)]
(:value m)))
(has? [c k]
(not (nil? (mc/find-by-id (get c :collection) k))))
(not (nil? (mc/find-by-id (:db c) (:collection c) k))))
(hit [this k]
this)
(miss [c k v]
(mc/insert (get c :collection) {:_id k :value v})
c)
(evict [c k]
(mc/remove-by-id (get c :collection) k)
c)
(seed [c m]
(mc/insert-batch (get c :collection) (map (fn [[k v]]
{:_id k :value v}) m))
c))
(defn basic-monger-cache-factory
([]
(BasicMongerCache. default-cache-collection))
([collection]
(BasicMongerCache. collection))
([collection base]
(cache/seed (BasicMongerCache. collection) base)))
(defrecord DatabaseAwareMongerCache [db collection])
(extend-protocol cache/CacheProtocol
DatabaseAwareMongerCache
(lookup [c k]
(let [m (find-map-by-id (:db c) (:collection c) k)]
(:value m)))
(has? [c k]
(not (nil? (find-by-id (:db c) (:collection c) k))))
(hit [this k]
this)
(miss [c k v]
(mc/insert (:db c) (:collection c) {:_id k :value v} WriteConcern/SAFE)
(mc/insert (:db c) (:collection c) {:_id k :value v})
c)
(evict [c k]
(mc/remove-by-id (:db c) (:collection c) k)
c)
(seed [c m]
(mc/insert-batch (:db c) (:collection c) (map (fn [[k v]]
{:_id k :value v}) m) WriteConcern/SAFE)
{:_id k :value v}) m))
c))
(defn db-aware-monger-cache-factory
([db]
(DatabaseAwareMongerCache. db default-cache-collection))
([db collection]
(DatabaseAwareMongerCache. db collection))
([db collection base]
(cache/seed (DatabaseAwareMongerCache. db collection) base)))
(defn basic-monger-cache-factory
([^DB db]
(BasicMongerCache. db default-cache-collection))
([^DB db collection]
(BasicMongerCache. db collection))
([^DB db collection base]
(cache/seed (BasicMongerCache. db collection) base)))

View file

@ -46,26 +46,22 @@
(defn ^WriteResult insert
"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.
In case you need the exact inserted document returned, with the :_id key generated,
use monger.collection/insert-and-return instead.
EXAMPLES:
;; returns write result
(monger.collection/insert \"people\" {:name \"Joe\", :age 30})
(monger.collection/insert db \"people\" {:name \"Joe\", :age 30})
(monger.collection/insert \"people\" {:name \"Joe\", :age 30, WriteConcern/SAFE})
(monger.collection/insert db \"people\" {:name \"Joe\", :age 30, WriteConcern/SAFE})
"
([^String collection document]
(.insert (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll document]
(.insert (.getCollection db (name coll))
(to-db-object document)
^WriteConcern monger.core/*mongodb-write-concern*))
([^String collection document ^WriteConcern concern]
(.insert (.getCollection monger.core/*mongodb-database* (name collection))
(to-db-object document)
concern))
([^DB db ^String collection document ^WriteConcern concern]
(.insert (.getCollection db (name collection))
([^DB db ^String coll document ^WriteConcern concern]
(.insert (.getCollection db (name coll))
(to-db-object document)
concern)))
@ -78,21 +74,19 @@
EXAMPLES:
;; returns the entire document with :_id generated
(monger.collection/insert-and-return \"people\" {:name \"Joe\", :age 30})
(monger.collection/insert-and-return db \"people\" {:name \"Joe\", :age 30})
(monger.collection/insert-and-return \"people\" {:name \"Joe\", :age 30, WriteConcern/SAFE})
(monger.collection/insert-and-return db \"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]
([^DB db ^String coll document]
(insert-and-return db coll document ^WriteConcern monger.core/*mongodb-write-concern*))
([^DB db ^String coll 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 {:_id (ObjectId.)} document)]
(insert db collection doc concern)
(insert db coll doc concern)
doc)))
@ -101,21 +95,17 @@
EXAMPLES:
(monger.collection/insert-batch \"people\" [{:name \"Joe\", :age 30}, {:name \"Paul\", :age 27}])
(monger.collection/insert-batch db \"people\" [{:name \"Joe\", :age 30}, {:name \"Paul\", :age 27}])
(monger.collection/insert-batch \"people\" [{:name \"Joe\", :age 30}, {:name \"Paul\", :age 27}] WriteConcern/NORMAL)
(monger.collection/insert-batch db \"people\" [{:name \"Joe\", :age 30}, {:name \"Paul\", :age 27}] WriteConcern/NORMAL)
"
([^String collection ^List documents]
(.insert (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll ^List documents]
(.insert (.getCollection db (name coll))
^List (to-db-object documents)
^WriteConcern monger.core/*mongodb-write-concern*))
([^String collection ^List documents ^WriteConcern concern]
(.insert (.getCollection monger.core/*mongodb-database* (name collection))
^List (to-db-object documents)
concern))
([^DB db ^String collection ^List documents ^WriteConcern concern]
(.insert (.getCollection db (name collection))
([^DB db ^String coll ^List documents ^WriteConcern concern]
(.insert (.getCollection db (name coll))
^List (to-db-object documents)
concern)))
@ -130,25 +120,21 @@
EXAMPLES:
;; return all objects in this collection.
(mgcol/find \"people\")
(mgcol/find db \"people\")
;; return all objects matching query
(mgcol/find \"people\" {:company \"Comp Corp\"})
(mgcol/find db \"people\" {:company \"Comp Corp\"})
;; return all objects matching query, taking only specified fields
(mgcol/find \"people\" {:company \"Comp Corp\"} [:first_name :last_name])
(mgcol/find db \"people\" {:company \"Comp Corp\"} [:first_name :last_name])
"
([^String collection]
(.find (.getCollection monger.core/*mongodb-database* (name collection))))
([^String collection ^Map ref]
(.find (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll]
(.find (.getCollection db (name coll))))
([^DB db ^String coll ^Map ref]
(.find (.getCollection db (name coll))
(to-db-object ref)))
([^String collection ^Map ref fields]
(.find (.getCollection monger.core/*mongodb-database* (name collection))
(to-db-object ref)
(as-field-selector fields)))
([^DB db ^String collection ^Map ref fields]
(.find (.getCollection db (name collection))
([^DB db ^String coll ^Map ref fields]
(.find (.getCollection db (name coll))
(to-db-object ref)
(as-field-selector fields))))
@ -157,32 +143,26 @@
This function returns clojure Seq of Maps.
If you want to work directly with DBObject, use find.
"
([^String collection]
(with-open [dbc (find collection)]
([^DB db ^String coll]
(with-open [dbc (find db coll)]
(map (fn [x] (from-db-object x true)) dbc)))
([^String collection ^Map ref]
(with-open [dbc (find collection ref)]
([^DB db ^String coll ^Map ref]
(with-open [dbc (find db coll ref)]
(map (fn [x] (from-db-object x true)) dbc)))
([^String collection ^Map ref fields]
(with-open [dbc (find collection ref fields)]
(map (fn [x] (from-db-object x true)) dbc)))
([^DB db ^String collection ^Map ref fields]
(with-open [dbc (find db collection ref fields)]
([^DB db ^String coll ^Map ref fields]
(with-open [dbc (find db coll ref fields)]
(map (fn [x] (from-db-object x true)) dbc))))
(defn find-seq
"Queries for objects in this collection, returns ISeq of DBObjects."
([^String collection]
(with-open [dbc (find collection)]
([^DB db ^String coll]
(with-open [dbc (find db coll)]
(seq dbc)))
([^String collection ^Map ref]
(with-open [dbc (find collection ref)]
([^DB db ^String coll ^Map ref]
(with-open [dbc (find db coll ref)]
(seq dbc)))
([^String collection ^Map ref fields]
(with-open [dbc (find collection ref fields)]
(seq dbc)))
([^DB db ^String collection ^Map ref fields]
(with-open [dbc (find db collection ref fields)]
([^DB db ^String coll ^Map ref fields]
(with-open [dbc (find db coll ref fields)]
(seq dbc))))
;;
@ -194,33 +174,29 @@
EXAMPLES:
(mgcol/find-one collection {:language \"Clojure\"})
(mgcol/find-one db collection {:language \"Clojure\"})
;; Return only :language field.
;; Note that _id field is always returned.
(mgcol/find-one collection {:language \"Clojure\"} [:language])
(mgcol/find-one db collection {:language \"Clojure\"} [:language])
"
([^String collection ^Map ref]
(.findOne (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll ^Map ref]
(.findOne (.getCollection db (name coll))
(to-db-object ref)))
([^String collection ^Map ref fields]
(.findOne (.getCollection monger.core/*mongodb-database* (name collection))
(to-db-object ref)
^DBObject (as-field-selector fields)))
([^DB db ^String collection ^Map ref fields]
(.findOne (.getCollection db (name collection))
([^DB db ^String coll ^Map ref fields]
(.findOne (.getCollection db (name coll))
(to-db-object ref)
^DBObject (as-field-selector fields))))
(defn ^IPersistentMap find-one-as-map
"Returns a single object converted to Map from this collection matching the query."
([^String collection ^Map ref]
(from-db-object ^DBObject (find-one collection ref) true))
([^String collection ^Map ref fields]
(from-db-object ^DBObject (find-one collection ref fields) true))
([^String collection ^Map ref fields keywordize]
(from-db-object ^DBObject (find-one collection ref fields) keywordize)))
([^DB db ^String coll ^Map ref]
(from-db-object ^DBObject (find-one db coll ref) true))
([^DB db ^String coll ^Map ref fields]
(from-db-object ^DBObject (find-one db coll ref fields) true))
([^DB db ^String coll ^Map ref fields keywordize]
(from-db-object ^DBObject (find-one db coll ref fields) keywordize)))
;;
@ -233,27 +209,32 @@
EXAMPLES:
;; Find and modify a document
(mgcol/find-and-modify collection {:language \"Python\"} {:language \"Clojure\"})
(mgcol/find-and-modify db collection {:language \"Python\"} {:language \"Clojure\"})
;; If multiple documents match, choose the first one in the specified order
(mgcol/find-and-modify collection {:language \"Python\"} {:language \"Clojure\"} :sort {:language -1})
(mgcol/find-and-modify db collection {:language \"Python\"} {:language \"Clojure\"} {:sort {:language -1}})
;; Remove the object before returning
(mgcol/find-and-modify collection {:language \"Python\"} {} :remove true)
(mgcol/find-and-modify db collection {:language \"Python\"} {} {:remove true})
;; Return the modified object instead of the old one
(mgcol/find-and-modify collection {:language \"Python\"} {:language \"Clojure\"} :return-new true)
(mgcol/find-and-modify db collection {:language \"Python\"} {:language \"Clojure\"} {:return-new true})
;; Retrieve a subset of fields
(mgcol/find-and-modify collection {:language \"Python\"} {:language \"Clojure\"} :fields [ :language ])
(mgcol/find-and-modify db collection {:language \"Python\"} {:language \"Clojure\"} {:fields [ :language ]})
;; Create the object if it doesn't exist
(mgcol/find-and-modify collection {:language \"Factor\"} {:language \"Clojure\"} :upsert true)
(mgcol/find-and-modify db collection {:language \"Factor\"} {:language \"Clojure\"} {:upsert true})
"
([^String collection ^Map conditions ^Map document & {:keys [fields sort remove return-new upsert keywordize] :or
{fields nil sort nil remove false return-new false upsert false keywordize true}}]
(let [coll (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll ^Map conditions ^Map document {:keys [fields sort remove return-new upsert keywordize] :or
{fields nil
sort nil
remove false
return-new false
upsert false
keywordize true}}]
(let [coll (.getCollection db (name coll))
maybe-fields (when fields (as-field-selector fields))
maybe-sort (when sort (to-db-object sort))]
(from-db-object
@ -275,54 +256,41 @@
;; Note that _id field is always returned.
(mgcol/find-one-by-id collection (ObjectId. \"4ef45ab4744e9fd632640e2d\") [:language])
"
([^String collection id]
([^DB db ^String coll id]
(check-not-nil! id "id must not be nil")
(find-one collection {:_id id}))
([^String collection id fields]
(find-one db coll {:_id id}))
([^DB db ^String coll id fields]
(check-not-nil! id "id must not be nil")
(find-one collection {:_id id} fields))
([^DB db ^String collection id fields]
(check-not-nil! id "id must not be nil")
(find-one db collection {:_id id} fields)))
(find-one db coll {:_id id} fields)))
(defn ^IPersistentMap find-map-by-id
"Returns a single object, converted to map with matching _id field."
([^String collection id]
([^DB db ^String coll id]
(check-not-nil! id "id must not be nil")
(from-db-object ^DBObject (find-one-as-map collection {:_id id}) true))
([^String collection id fields]
(from-db-object ^DBObject (find-one-as-map db coll {:_id id}) true))
([^DB db ^String coll id fields]
(check-not-nil! id "id must not be nil")
(from-db-object ^DBObject (find-one-as-map collection {:_id id} fields) true))
([^String collection id fields keywordize]
(from-db-object ^DBObject (find-one-as-map db coll {:_id id} fields) true))
([^DB db ^String coll id fields keywordize]
(check-not-nil! id "id must not be nil")
(from-db-object ^DBObject (find-one-as-map collection {:_id id} fields) keywordize)))
;;
;; monger.collection/group
;;
;; TBD
(from-db-object ^DBObject (find-one-as-map db coll {:_id id} fields) keywordize)))
;;
;; monger.collection/count
;;
(defn count
"Returns the number of documents in this collection.
Takes optional conditions as an argument.
(monger.collection/count collection)
(monger.collection/count db coll)
(monger.collection/count collection {:first_name \"Paul\"})"
(^long [^String collection]
(.count (.getCollection monger.core/*mongodb-database* (name collection))))
(^long [^String collection ^Map conditions]
(.count (.getCollection monger.core/*mongodb-database* (name collection)) (to-db-object conditions)))
(^long [^DB db ^String collection ^Map conditions]
(.count (.getCollection db (name collection)) (to-db-object conditions))))
(monger.collection/count db coll {:first_name \"Paul\"})"
(^long [^DB db ^String coll]
(.count (.getCollection db (name coll))))
(^long [^DB db ^String coll ^Map conditions]
(.count (.getCollection db (name coll)) (to-db-object conditions))))
(defn any?
"Whether the collection has any items at all, or items matching query.
@ -330,28 +298,24 @@
EXAMPLES:
;; whether the collection has any items
(mgcol/any? collection)
(mgcol/any? db coll)
(mgcol/any? collection {:language \"Clojure\"}))
(mgcol/any? db coll {:language \"Clojure\"}))
"
([^String collection]
(> (count collection) 0))
([^String collection ^Map conditions]
(> (count collection conditions) 0))
([^DB db ^String collection ^Map conditions]
(> (count db collection conditions) 0)))
([^DB db ^String coll]
(> (count db coll) 0))
([^DB db ^String coll ^Map conditions]
(> (count db coll conditions) 0)))
(defn empty?
"Whether the collection is empty.
EXAMPLES:
(mgcol/empty? \"things\")
(mgcol/empty? db \"things\")
"
([^String collection]
(= (count collection) 0))
([^DB db ^String collection]
(= (count db collection {}) 0)))
[^DB db ^String coll]
(= (count db coll {}) 0))
;; monger.collection/update
@ -364,17 +328,17 @@
EXAMPLES
(monger.collection/update \"people\" {:first_name \"Raul\"} {\"$set\" {:first_name \"Paul\"}})
(monger.collection/update db \"people\" {:first_name \"Raul\"} {\"$set\" {:first_name \"Paul\"}})
You can use all the Mongodb Modifier Operations ($inc, $set, $unset, $push, $pushAll, $addToSet, $pop, $pull
$pullAll, $rename, $bit) here, as well
EXAMPLES
(monger.collection/update \"people\" {:first_name \"Paul\"} {\"$set\" {:index 1}})
(monger.collection/update \"people\" {:first_name \"Paul\"} {\"$inc\" {:index 5}})
(monger.collection/update db \"people\" {:first_name \"Paul\"} {\"$set\" {:index 1}})
(monger.collection/update db \"people\" {:first_name \"Paul\"} {\"$inc\" {:index 5}})
(monger.collection/update \"people\" {:first_name \"Paul\"} {\"$unset\" {:years_on_stage 1}})
(monger.collection/update db \"people\" {:first_name \"Paul\"} {\"$unset\" {:years_on_stage 1}})
It also takes modifiers, such as :upsert and :multi.
@ -382,16 +346,19 @@
;; add :band field to all the records found in \"people\" collection, otherwise only the first matched record
;; will be updated
(monger.collection/update \"people\" {} {\"$set\" {:band \"The Beatles\"}} :multi true)
(monger.collection/update db \"people\" {} {\"$set\" {:band \"The Beatles\"}} :multi true)
;; inserts the record if it did not exist in the collection
(monger.collection/update \"people\" {:first_name \"Yoko\"} {:first_name \"Yoko\" :last_name \"Ono\"} :upsert true)
(monger.collection/update db \"people\" {:first_name \"Yoko\"} {:first_name \"Yoko\" :last_name \"Ono\"} {:upsert true)
By default :upsert and :multi are false."
([^String collection ^Map conditions ^Map document & {:keys [upsert multi write-concern] :or {upsert false
([^DB db ^String coll ^Map conditions ^Map document]
(update db coll conditions document {}))
([^DB db ^String coll ^Map conditions ^Map document {:keys [upsert multi write-concern]
:or {upsert false
multi false
write-concern monger.core/*mongodb-write-concern*}}]
(.update (.getCollection monger.core/*mongodb-database* (name collection))
(.update (.getCollection db (name coll))
(to-db-object conditions)
(to-db-object document)
upsert
@ -405,21 +372,27 @@
sets :upsert to true.
See monger.collection/update documentation"
[^String collection ^Map conditions ^Map document & {:keys [multi write-concern] :or {multi false
([^DB db ^String coll ^Map conditions ^Map document]
(upsert db coll conditions document {}))
([^DB db ^String coll ^Map conditions ^Map document {:keys [multi write-concern]
:or {multi false
write-concern monger.core/*mongodb-write-concern*}}]
(update collection conditions document :multi multi :write-concern write-concern :upsert true))
(update db coll conditions document {:multi multi :write-concern write-concern :upsert true})))
(defn ^WriteResult update-by-id
"Update a document with given id"
[^String collection id ^Map document & {:keys [upsert write-concern] :or {upsert false
([^DB db ^String coll id ^Map document]
(update-by-id db coll id document {}))
([^DB db ^String coll id ^Map document {:keys [upsert write-concern]
:or {upsert false
write-concern monger.core/*mongodb-write-concern*}}]
(check-not-nil! id "id must not be nil")
(.update (.getCollection monger.core/*mongodb-database* (name collection))
(.update (.getCollection db (name coll))
(to-db-object {:_id id})
(to-db-object document)
upsert
false
write-concern))
write-concern)))
;; monger.collection/save
@ -435,18 +408,14 @@
EXAMPLES
(monger.collection/save \"people\" {:first_name \"Ian\" :last_name \"Gillan\"})
(monger.collection/save db \"people\" {:first_name \"Ian\" :last_name \"Gillan\"})
"
([^String collection ^Map document]
(.save (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll ^Map document]
(.save (.getCollection db (name coll))
(to-db-object document)
monger.core/*mongodb-write-concern*))
([^String collection ^Map document ^WriteConcern write-concern]
(.save (.getCollection monger.core/*mongodb-database* (name collection))
(to-db-object document)
write-concern))
([^DB db ^String collection ^Map document ^WriteConcern write-concern]
(.save (.getCollection db (name collection))
([^DB db ^String coll ^Map document ^WriteConcern write-concern]
(.save (.getCollection db (name coll))
(to-db-object document)
write-concern)))
@ -465,15 +434,13 @@
(monger.collection/save-and-return \"people\" {:first_name \"Ian\" :last_name \"Gillan\"})
"
([^String collection ^Map document]
(save-and-return ^DB monger.core/*mongodb-database* collection document ^WriteConcern monger.core/*mongodb-write-concern*))
([^String collection ^Map document ^WriteConcern write-concern]
(save-and-return ^DB monger.core/*mongodb-database* collection document write-concern))
([^DB db ^String collection ^Map document ^WriteConcern write-concern]
([^DB db ^String coll ^Map document]
(save-and-return db coll document ^WriteConcern monger.core/*mongodb-write-concern*))
([^DB db ^String coll ^Map document ^WriteConcern write-concern]
;; see the comment in insert-and-return. Here we additionally need to make sure to not scrap the :_id key if
;; it is already present. MK.
(let [doc (merge {:_id (ObjectId.)} document)]
(save db collection doc write-concern)
(save db coll doc write-concern)
doc)))
@ -484,28 +451,30 @@
EXAMPLES
(monger.collection/remove collection) ;; Removes all documents from DB
(monger.collection/remove db collection) ;; Removes all documents from DB
(monger.collection/remove collection {:language \"Clojure\"}) ;; Removes documents based on given query
(monger.collection/remove db collection {:language \"Clojure\"}) ;; Removes documents based on given query
"
([^String collection]
(.remove (.getCollection monger.core/*mongodb-database* (name collection)) (to-db-object {})))
([^String collection ^Map conditions]
(.remove (.getCollection monger.core/*mongodb-database* (name collection)) (to-db-object conditions)))
([^DB db ^String collection ^Map conditions]
(.remove (.getCollection db (name collection)) (to-db-object conditions))))
([^DB db ^String coll]
(.remove (.getCollection db (name coll)) (to-db-object {})))
([^DB db ^String coll ^Map conditions]
(.remove (.getCollection db (name coll)) (to-db-object conditions))))
(defn ^WriteResult remove-by-id
"Removes a single document with given id"
([^String collection id]
(remove-by-id monger.core/*mongodb-database* collection id))
([^DB db ^String collection id]
[^DB db ^String coll id]
(check-not-nil! id "id must not be nil")
(let [coll (.getCollection db (name collection))]
(.remove coll (to-db-object {:_id id})))))
(let [coll (.getCollection db (name coll))]
(.remove coll (to-db-object {:_id id}))))
(defn purge-many
"Purges (removes all documents from) multiple collections. Intended
to be used in test environments."
[^DB db xs]
(doseq [coll xs]
(remove db coll)))
;;
;; monger.collection/create-index
@ -517,18 +486,14 @@
EXAMPLES
;; Will create an index on the \"language\" field
(monger.collection/create-index collection {\"language\" 1})
(monger.collection/create-index collection {\"language\" 1} {:unique true :name \"unique_language\"})
(monger.collection/create-index db collection {\"language\" 1})
(monger.collection/create-index db collection {\"language\" 1} {:unique true :name \"unique_language\"})
"
([^String collection ^Map keys]
(.createIndex (.getCollection monger.core/*mongodb-database* (name collection)) (as-field-selector keys)))
([^String collection ^Map keys options]
(.createIndex (.getCollection monger.core/*mongodb-database* (name collection))
(as-field-selector keys)
(to-db-object options)))
([^DB db ^String collection ^Map keys ^Map options]
(.createIndex (.getCollection db (name collection))
([^DB db ^String coll ^Map keys]
(.createIndex (.getCollection db (name coll)) (as-field-selector keys)))
([^DB db ^String coll ^Map keys ^Map options]
(.createIndex (.getCollection db (name coll))
(as-field-selector keys)
(to-db-object options))))
@ -550,18 +515,18 @@
;; create a regular index
;; clojure.core/array-map produces an ordered map
(monger.collection/ensure-index \"documents\" (array-map \"language\" 1))
(monger.collection/ensure-index db \"documents\" (array-map \"language\" 1))
;; create a unique index
(monger.collection/ensure-index \"pages\" (array-map :url 1) {:unique true})
(monger.collection/ensure-index db \"pages\" (array-map :url 1) {:unique true})
"
([^String collection ^Map keys]
(.ensureIndex (.getCollection monger.core/*mongodb-database* (name collection)) (as-field-selector keys)))
([^String collection ^Map keys ^Map options]
(.ensureIndex (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll ^Map keys]
(.ensureIndex (.getCollection db (name coll)) (as-field-selector keys)))
([^DB db ^String coll ^Map keys ^Map options]
(.ensureIndex (.getCollection db (name coll))
(as-field-selector keys)
(to-db-object options)))
([^String collection ^Map keys ^String name ^Boolean unique?]
(.ensureIndex (.getCollection monger.core/*mongodb-database* (name collection))
([^DB db ^String coll ^Map keys ^String name unique?]
(.ensureIndex (.getCollection db (name coll))
(as-field-selector keys)
name
unique?)))
@ -579,8 +544,8 @@
(monger.collection/indexes-on collection)
"
[^String collection]
(from-db-object (.getIndexInfo (.getCollection monger.core/*mongodb-database* (name collection))) true))
[^DB db ^String coll]
(from-db-object (.getIndexInfo (.getCollection db (name coll))) true))
;;
@ -589,17 +554,13 @@
(defn drop-index
"Drops an index from this collection."
([^String collection ^String idx-name]
(.dropIndex (.getCollection monger.core/*mongodb-database* (name collection)) idx-name))
([^DB db ^String collection ^String idx-name]
(.dropIndex (.getCollection db (name collection)) idx-name)))
[^DB db ^String coll ^String idx-name]
(.dropIndex (.getCollection db (name coll)) idx-name))
(defn drop-indexes
"Drops all indixes from this collection."
([^String collection]
(.dropIndexes (.getCollection monger.core/*mongodb-database* (name collection))))
([^DB db ^String collection]
(.dropIndexes (.getCollection db (name collection)))))
[^DB db ^String coll]
(.dropIndexes (.getCollection db (name coll))))
;;
@ -612,12 +573,10 @@
EXAMPLE:
(monger.collection/exists? \"coll\")
(monger.collection/exists? db \"coll\")
"
([^String collection]
(.collectionExists monger.core/*mongodb-database* collection))
([^DB db ^String collection]
(.collectionExists db collection)))
([^DB db ^String coll]
(.collectionExists db coll)))
(defn create
"Creates a collection with a given name and options.
@ -631,12 +590,10 @@
EXAMPLE:
;; create a capped collection
(monger.collection/create \"coll\" {:capped true :size 100000 :max 10})
(monger.collection/create db \"coll\" {:capped true :size 100000 :max 10})
"
([^String collection ^Map options]
(.createCollection monger.core/*mongodb-database* collection (to-db-object options)))
([^DB db ^String collection ^Map options]
(.createCollection db collection (to-db-object options))))
[^DB db ^String coll ^Map options]
(.createCollection db coll (to-db-object options)))
(defn drop
"Deletes collection from database.
@ -645,24 +602,20 @@
(monger.collection/drop \"collection-to-drop\")
"
([^String collection]
(.drop (.getCollection monger.core/*mongodb-database* (name collection))))
([^DB db ^String collection]
(.drop (.getCollection db (name collection)))))
[^DB db ^String coll]
(.drop (.getCollection db (name coll))))
(defn rename
"Renames collection.
EXAMPLE:
(monger.collection/rename \"old_name\" \"new_name\")
(monger.collection/rename db \"old_name\" \"new_name\")
"
([^String from, ^String to]
(.rename (.getCollection monger.core/*mongodb-database* from) to))
([^String from ^String to ^Boolean drop-target]
(.rename (.getCollection monger.core/*mongodb-database* from) to drop-target))
([^DB db ^String from ^String to ^Boolean drop-target]
(.rename (.getCollection db from) to drop-target)))
([^DB db ^String from, ^String to]
(.rename (.getCollection db from) to))
([^DB db ^String from ^String to drop-target?]
(.rename (.getCollection db from) to drop-target?)))
;;
;; Map/Reduce
@ -670,11 +623,11 @@
(defn map-reduce
"Performs a map reduce operation"
([^String collection ^String js-mapper ^String js-reducer ^String output ^Map query]
(let [coll (.getCollection monger.core/*mongodb-database* (name collection))]
([^DB db ^String coll ^String js-mapper ^String js-reducer ^String output ^Map query]
(let [coll (.getCollection db (name coll))]
(.mapReduce coll js-mapper js-reducer output (to-db-object query))))
([^String collection ^String js-mapper ^String js-reducer ^String output ^MapReduceCommand$OutputType output-type ^Map query]
(let [coll (.getCollection monger.core/*mongodb-database* (name collection))]
([^DB db ^String coll ^String js-mapper ^String js-reducer ^String output ^MapReduceCommand$OutputType output-type ^Map query]
(let [coll (.getCollection db (name coll))]
(.mapReduce coll js-mapper js-reducer output output-type (to-db-object query)))))
@ -684,12 +637,10 @@
(defn distinct
"Finds distinct values for a key"
([^String collection ^String key]
(.distinct (.getCollection monger.core/*mongodb-database* (name collection)) ^String (to-db-object key)))
([^String collection ^String key ^Map query]
(.distinct (.getCollection monger.core/*mongodb-database* (name collection)) ^String (to-db-object key) (to-db-object query)))
([^DB db ^String collection ^String key ^Map query]
(.distinct (.getCollection db (name collection)) ^String (to-db-object key) (to-db-object query))))
([^DB db ^String coll ^String key]
(.distinct (.getCollection db (name coll)) ^String (to-db-object key)))
([^DB db ^String coll ^String key ^Map query]
(.distinct (.getCollection db (name coll)) ^String (to-db-object key) (to-db-object query))))
;;
@ -697,12 +648,12 @@
;;
(defn aggregate
"Performs aggregation query. MongoDB 2.1/2.2+ only.
"Executes an aggregation query. MongoDB 2.2+ only.
See http://docs.mongodb.org/manual/applications/aggregation/ to learn more."
[^String collection stages]
(let [res (monger.core/command {:aggregate collection :pipeline stages})]
;; this is what DBCollection#distinct does. Turning a blind eye!
[^DB db ^String coll stages]
(let [res (monger.core/command db {:aggregate coll :pipeline stages})]
;; this is what DBCollection#distinct does. Turning a blind's eye!
(.throwOnError res)
(map #(from-db-object % true) (.get res "result"))))
@ -717,5 +668,5 @@
(defn system-collection?
"Evaluates to true if the given collection name refers to a system collection. System collections
are prefixed with system. or fs. (default GridFS collection prefix)"
[^String collection]
(re-find system-collection-pattern collection))
[^String coll]
(re-find system-collection-pattern coll))

View file

@ -20,7 +20,7 @@
* http://clojuremongodb.info/articles/mapreduce.html"
(:require monger.core
[monger.conversion :refer :all])
(:import [com.mongodb DB DBObject]))
(:import [com.mongodb MongoClient DB DBObject]))
;;
@ -29,77 +29,59 @@
(defn admin-command
"Executes a command on the admin database"
[m]
(monger.core/command (monger.core/admin-db) m))
[^MongoClient conn m]
(monger.core/command (monger.core/admin-db conn) m))
(defn raw-admin-command
"Executes a command on the admin database"
[^DBObject cmd]
(monger.core/raw-command (monger.core/admin-db) cmd))
[^MongoClient conn ^DBObject cmd]
(monger.core/raw-command (monger.core/admin-db conn) cmd))
(defn collection-stats
([collection]
(collection-stats monger.core/*mongodb-database* collection))
([^DB database collection]
(monger.core/command database {:collstats collection})))
[^DB database collection]
(monger.core/command database {:collstats collection}))
(defn db-stats
([]
(db-stats monger.core/*mongodb-database*))
([^DB database]
(monger.core/command database {:dbStats 1})))
[^DB database]
(monger.core/command database {:dbStats 1}))
(defn reindex-collection
"Forces an existing collection to be reindexed using the reindexCollection command"
([^String collection]
(reindex-collection monger.core/*mongodb-database* collection))
([^DB database ^String collection]
(monger.core/command database {:reIndex collection})))
[^DB database ^String collection]
(monger.core/command database {:reIndex collection}))
(defn rename-collection
"Changes the name of an existing collection using the renameCollection command"
([^String from ^String to]
(reindex-collection monger.core/*mongodb-database* from to))
([^DB database ^String from ^String to]
(monger.core/command database (sorted-map :renameCollection from :to to))))
[^DB db ^String from ^String to]
(monger.core/command db (sorted-map :renameCollection from :to to)))
(defn convert-to-capped
"Converts an existing, non-capped collection to a capped collection using the convertToCapped command"
([^String collection ^long size]
(convert-to-capped monger.core/*mongodb-database* collection size))
([^DB database ^String collection ^long size]
(monger.core/command database (sorted-map :convertToCapped collection :size size))))
[^DB db ^String collection ^long size]
(monger.core/command db (sorted-map :convertToCapped collection :size size)))
(defn empty-capped
"Removes all documents from a capped collection using the emptycapped command"
([^String collection]
(empty-capped monger.core/*mongodb-database* collection))
([^DB database ^String collection]
(monger.core/command database {:emptycapped collection})))
[^DB db ^String collection]
(monger.core/command db {:emptycapped collection}))
(defn compact
"Rewrites and defragments a single collection using the compact command. This also forces all indexes on the collection to be rebuilt"
([^String collection]
(compact monger.core/*mongodb-database* collection))
([^DB database ^String collection]
(monger.core/command database {:compact collection})))
[^DB db ^String collection]
(monger.core/command db {:compact collection}))
(defn server-status
([]
(server-status monger.core/*mongodb-database*))
([^DB database]
(monger.core/command database {:serverStatus 1})))
[^DB db]
(monger.core/command db {:serverStatus 1}))
(defn top
[]
(monger.core/command (monger.core/get-db "admin") {:top 1}))
[^MongoClient conn]
(monger.core/command (monger.core/admin-db conn) {:top 1}))
(defn search
([^String collection query]
(monger.core/command {"text" collection "search" query}))
([^DB database ^String collection query]
(monger.core/command database {"text" collection "search" query})))
[^DB db ^String collection query]
(monger.core/command db {"text" collection "search" query}))

View file

@ -31,28 +31,24 @@
(def ^:dynamic ^String *mongodb-host* "127.0.0.1")
(def ^:dynamic ^long *mongodb-port* 27017)
(declare ^:dynamic ^MongoClient *mongodb-connection*)
(declare ^:dynamic ^DB *mongodb-database*)
(def ^:dynamic ^WriteConcern *mongodb-write-concern* WriteConcern/ACKNOWLEDGED)
(declare ^:dynamic ^GridFS *mongodb-gridfs*)
;;
;; API
;;
(defn ^com.mongodb.MongoClient connect
(defn ^MongoClient connect
"Connects to MongoDB. When used without arguments, connects to
Arguments:
:host (*mongodb-host* by default)
:port (*mongodb-port* by default)
:host (\"127.0.0.1\" by default)
:port (27017 by default)
EXAMPLES
(monger.core/connect)
(monger.core/connect { :host \"db3.intranet.local\", :port 27787 })
(monger.core/connect {:host \"db3.intranet.local\" :port 27787})
;; Connecting to a replica set with a couple of seeds
(let [^MongoClientOptions opts (mg/mongo-options :threads-allowed-to-block-for-connection-multiplier 300)
@ -79,55 +75,32 @@
(defn get-db-names
"Gets a list of all database names present on the server"
([]
(get-db-names *mongodb-connection*))
([^MongoClient connection]
(set (.getDatabaseNames connection))))
[^MongoClient conn]
(set (.getDatabaseNames conn)))
(defn ^com.mongodb.DB get-db
(defn ^DB get-db
"Get database reference by name.
EXAMPLES
(monger.core/get-db \"myapp_production\")
(monger.core/get-db connection \"myapp_production\")"
([]
*mongodb-database*)
([^String name]
(.getDB *mongodb-connection* name))
([^MongoClient connection ^String name]
(.getDB connection name)))
(defn ^com.mongodb.DB current-db
"Returns currently used database"
[]
*mongodb-database*)
[^MongoClient conn ^String name]
(.getDB conn name))
(defn drop-db
"Drops a database"
([^String db]
(.dropDatabase *mongodb-connection* db))
([^MongoClient conn ^String db]
(.dropDatabase conn db)))
[^MongoClient conn ^String db]
(.dropDatabase conn db))
(defn ^GridFS get-gridfs
"Get GridFS for the given database.
(defmacro with-connection
[conn & body]
`(binding [*mongodb-connection* ~conn]
(do ~@body)))
(defmacro with-db
[db & body]
`(binding [*mongodb-database* ~db]
(do ~@body)))
(defmacro with-gridfs
[fs & body]
`(binding [*mongodb-gridfs* ~fs]
(do ~@body)))
EXAMPLES
(monger.core/get-gridfs connection \"myapp_production\")"
[^MongoClient conn ^String name]
(GridFS. (.getDB conn name)))
(defn server-address
([^String hostname]
@ -135,7 +108,6 @@
([^String hostname ^Long port]
(ServerAddress. hostname port)))
(defn mongo-options
[& { :keys [connections-per-host threads-allowed-to-block-for-connection-multiplier
max-wait-time connect-timeout socket-timeout socket-keep-alive auto-connect-retry max-auto-connect-retry-time
@ -165,57 +137,27 @@
(.cursorFinalizerEnabled mob cursor-finalizer-enabled))
(.build mob)))
(defn set-connection!
"Sets given MongoDB connection as default by altering *mongodb-connection* var"
^MongoClient [^MongoClient conn]
(alter-var-root (var *mongodb-connection*) (constantly conn)))
(defn connect!
"Connect to MongoDB, store connection in the *mongodb-connection* var"
^MongoClient [& args]
(let [c (apply connect args)]
(set-connection! c)))
(defn disconnect!
(defn disconnect
"Closes default connection to MongoDB"
[]
(.close *mongodb-connection*))
(defn set-db!
"Sets *mongodb-database* var to given db, updates *mongodb-gridfs* var state. Recommended to be used for
applications that only use one database."
[db]
(alter-var-root (var *mongodb-database*) (constantly db))
(alter-var-root (var *mongodb-gridfs*) (constantly (GridFS. db))))
(def ^{:doc "Combines set-db! and get-db, so (use-db \"mydb\") is the same as (set-db! (get-db \"mydb\"))"}
use-db! (comp set-db! get-db))
[^MongoClient conn]
(.close conn))
(def ^:const admin-db-name "admin")
(defn ^DB admin-db
"Returns admin database"
[]
(get-db admin-db-name))
[^MongoClient conn]
(get-db conn admin-db-name))
(defn set-default-write-concern!
[wc]
"Set *mongodb-write-concert* var to :wc
Unlike the official Java driver, Monger uses WriteConcern/SAFE by default. We think defaults should be safe first
and WebScale fast second."
"Sets *mongodb-write-concert*"
(alter-var-root #'*mongodb-write-concern* (constantly wc)))
(defn authenticate
([^String username ^chars password]
(authenticate *mongodb-connection* *mongodb-database* username password))
([^DB db ^String username ^chars password]
(authenticate *mongodb-connection* db username password))
([^MongoClient connection ^DB db ^String username ^chars password]
(try
(.authenticate db username password)
;; MongoDB Java driver's exception hierarchy is a little crazy
@ -234,41 +176,25 @@
user (.getUsername uri)
pwd (.getPassword uri)]
(when (and user pwd)
(when-not (authenticate conn db user pwd)
(when-not (authenticate db user pwd)
(throw (IllegalArgumentException. (format "Could not authenticate with MongoDB. Either database name or credentials are invalid. Database name: %s, username: %s" (.getName db) user)))))
{:conn conn, :db db}))
(defn connect-via-uri!
"Connects to MongoDB using a URI, sets up default connection and database. Commonly used for PaaS-based applications,
for example, running on Heroku. If username and password are provided, performs authentication."
[uri-string]
(let [{:keys [conn db]} (connect-via-uri uri-string)]
(set-connection! conn)
(when db
(set-db! db))
conn))
{:conn conn :db db}))
(defn ^com.mongodb.CommandResult command
"Runs a database command (please check MongoDB documentation for the complete list of commands).
Ordering of keys in the command document may matter. Please use sorted maps instead of map literals, for example:
(sorted-map geoNear \"bars\" :near 50 :test 430 :num 10)
(sorted-map geoNear db \"bars\" :near 50 :test 430 :num 10)
For commonly used commands (distinct, count, map/reduce, etc), use monger.command and monger.collection functions such as
/distinct, /count, /drop, /dropIndexes, and /mapReduce respectively."
([^Map cmd]
(.command ^DB *mongodb-database* ^DBObject (to-db-object cmd)))
([^DB database ^Map cmd]
(.command ^DB database ^DBObject (to-db-object cmd))))
[^DB database ^Map cmd]
(.command ^DB database ^DBObject (to-db-object cmd)))
(defn ^com.mongodb.CommandResult raw-command
"Like monger.core/command but accepts DBObjects"
([^DBObject cmd]
(.command ^DB *mongodb-database* cmd))
([^DB database ^DBObject cmd]
(.command database cmd)))
[^DB database ^DBObject cmd]
(.command database cmd))
(defprotocol Countable
(count [this] "Returns size of the object"))
@ -295,8 +221,6 @@
Important note: when calling this method directly, it is undefined which connection \"getLastError\" is called on.
You may need to explicitly use a \"consistent Request\", see requestStart() For most purposes it is better not to call this method directly but instead use WriteConcern."
([]
(get-last-error *mongodb-database*))
([^DB database]
(.getLastError ^DB database))
([^DB database ^Integer w ^Integer wtimeout ^Boolean fsync]

View file

@ -11,7 +11,7 @@
"Helper-functions for dbCursor object:
* to initialize new cursor,
* for CRUD functionality of options of dbCursor"
(:import [com.mongodb DBCursor Bytes]
(:import [com.mongodb DB DBCursor Bytes]
[java.util List Map]
[java.lang Integer]
[clojure.lang Keyword])
@ -20,13 +20,13 @@
(defn ^DBCursor make-db-cursor
"initializes new db-cursor."
([^String collection]
(make-db-cursor collection {} {}))
([^String collection ^Map ref]
(make-db-cursor collection ref {}))
([^String collection ^Map ref fields]
([^DB db ^String coll]
(make-db-cursor db coll {} {}))
([^DB db ^String coll ^Map ref]
(make-db-cursor db coll ref {}))
([^DB db ^String coll ^Map ref fields]
(.find
(.getCollection monger.core/*mongodb-database* (name collection))
(.getCollection db (name coll))
(to-db-object ref)
(as-field-selector fields))))

View file

@ -16,25 +16,22 @@
[monger.conversion :refer :all]))
;;
;; API
;;
(defn add-user
"Adds a new user for this db"
([^String username, ^chars password]
(.addUser ^DB monger.core/*mongodb-database* username password))
([^DB database ^String username ^chars password]
(.addUser ^DB database username password)))
[^DB db ^String username ^chars password]
(.addUser db username password))
(defn drop-db
"Drops the currently set database (via core/set-db) or the specified database."
([]
(.dropDatabase ^DB monger.core/*mongodb-database*))
([^DB database]
(.dropDatabase ^DB database)))
[^DB db]
(.dropDatabase db))
(defn get-collection-names
"Returns a set containing the names of all collections in this database."
([]
(set (.getCollectionNames ^DB monger.core/*mongodb-database*)))
([^DB database]
(set (.getCollectionNames ^DB database))))
([^DB db]
(set (.getCollectionNames db))))

View file

@ -18,8 +18,9 @@
[monger.conversion :refer :all]
[clojurewerkz.support.fn :refer [fpartial]])
(:import [com.mongodb DB DBObject]
org.bson.types.ObjectId
[com.mongodb.gridfs GridFS GridFSInputFile]
[java.io InputStream File]))
[java.io InputStream ByteArrayInputStream File]))
;;
;; Implementation
@ -41,24 +42,16 @@
(defn remove
([]
(remove {}))
([query]
(.remove ^GridFS monger.core/*mongodb-gridfs* ^DBObject (to-db-object query)))
([^GridFS fs query]
(.remove fs ^DBObject (to-db-object query))))
[^GridFS fs query]
(.remove fs ^DBObject (to-db-object query)))
(defn remove-all
([]
(remove {}))
([^GridFS fs]
(remove fs {})))
[^GridFS fs]
(remove fs {}))
(defn all-files
([]
(.getFileList ^GridFS monger.core/*mongodb-gridfs*))
([query]
(.getFileList ^GridFS monger.core/*mongodb-gridfs* query))
([^GridFS fs]
(.getFileList fs (to-db-object {})))
([^GridFS fs query]
(.getFileList fs query)))
@ -66,10 +59,8 @@
(fpartial from-db-object true))
(defn files-as-maps
([]
(map converter (all-files)))
([query]
(map converter (all-files (to-db-object query))))
([^GridFS fs]
(files-as-maps fs {}))
([^GridFS fs query]
(map converter (all-files fs (to-db-object query)))))
@ -78,27 +69,30 @@
;; Plumbing (low-level API)
;;
(defprotocol GridFSInputFileFactory
(^com.mongodb.gridfs.GridFSInputFile make-input-file [input] "Makes GridFSInputFile out of the given input"))
(defprotocol InputStreamFactory
(^InputStream to-input-stream [input] "Makes InputStream out of the given input"))
(extend byte-array-type
GridFSInputFileFactory
{:make-input-file (fn [^bytes input]
(.createFile ^GridFS monger.core/*mongodb-gridfs* input))})
InputStreamFactory
{:to-input-stream (fn [^bytes input]
(ByteArrayInputStream. input))})
(extend-protocol GridFSInputFileFactory
(extend-protocol InputStreamFactory
String
(make-input-file [^String input]
(.createFile ^GridFS monger.core/*mongodb-gridfs* ^InputStream (io/make-input-stream input {:encoding "UTF-8"})))
(to-input-stream [^String input]
(io/make-input-stream input {:encoding "UTF-8"}))
File
(make-input-file [^File input]
(.createFile ^GridFS monger.core/*mongodb-gridfs* ^InputStream (io/make-input-stream input {:encoding "UTF-8"})))
(to-input-stream [^File input]
(io/make-input-stream input {:encoding "UTF-8"}))
InputStream
(make-input-file [^InputStream input]
(.createFile ^GridFS monger.core/*mongodb-gridfs* ^InputStream input)))
(to-input-stream [^InputStream input]
input))
(defn ^GridFSInputFile make-input-file
[^GridFS fs input]
(.createFile fs (to-input-stream input)))
(defmacro store
[^GridFSInputFile input & body]
@ -106,9 +100,8 @@
(.save f# GridFS/DEFAULT_CHUNKSIZE)
(from-db-object f# true)))
;;
;; "New" DSL, a higher-level API
;; Higher-level API
;;
(defn save
@ -141,48 +134,34 @@
;; Finders
;;
(defprotocol Finders
(find [input] "Finds multiple files using given input (an ObjectId, filename or query)")
(find-one [input] "Finds one file using given input (an ObjectId, filename or query)")
(find-maps [input] "Finds multiple files using given input (an ObjectId, filename or query), returning a Clojure map")
(find-one-as-map [input] "Finds one file using given input (an ObjectId, filename or query), returning a Clojure map"))
(defn find
[^GridFS fs query]
(.find fs (to-db-object query)))
(extend-protocol Finders
String
(find [^String input]
(.find ^GridFS monger.core/*mongodb-gridfs* input))
(find-one [^String input]
(.findOne ^GridFS monger.core/*mongodb-gridfs* input))
(find-maps [^String input]
(map converter (find input)))
(find-one-as-map [^String input]
(converter (find-one input)))
(defn find-by-filename
[^GridFS fs ^String filename]
(.find fs (to-db-object {"filename" filename})))
org.bson.types.ObjectId
(find-one [^org.bson.types.ObjectId input]
(.findOne ^GridFS monger.core/*mongodb-gridfs* input))
(find-one-as-map [^org.bson.types.ObjectId input]
(converter (find-one input)))
(defn find-by-md5
[^GridFS fs ^String md5]
(.find fs (to-db-object {"md5" md5})))
(defn find-one
[^GridFS fs query]
(.findOne fs (to-db-object query)))
DBObject
(find [^DBObject input]
(.find ^GridFS monger.core/*mongodb-gridfs* input))
(find-one [^DBObject input]
(.findOne ^GridFS monger.core/*mongodb-gridfs* input))
(find-maps [^DBObject input]
(map converter (find input)))
(find-one-as-map [^DBObject input]
(converter (find-one input)))
(defn find-maps
[^GridFS fs query]
(map converter (find fs query)))
;; using java.util.Map here results in (occasional) recursion
clojure.lang.IPersistentMap
(find [^java.util.Map input]
(find (to-db-object input)))
(find-one [^java.util.Map input]
(find-one (to-db-object input)))
(find-maps [^java.util.Map input]
(find-maps (to-db-object input)))
(find-one-as-map [^java.util.Map input]
(find-one-as-map (to-db-object input))))
(defn find-one-as-map
[^GridFS fs query]
(converter (find-one fs query)))
(defn find-by-id
[^GridFS fs ^ObjectId id]
(.findOne fs id))
(defn find-map-by-id
[^GridFS fs ^ObjectId id]
(converter (find-one fs id)))

View file

@ -1,73 +0,0 @@
;; Copyright (c) 2011-2014 Michael S. Klishin
;;
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.
(ns monger.internal.fn)
;;
;; Implementation
;;
(defn- apply-to-values [m f]
"Applies function f to all values in map m"
(into {} (for [[k v] m]
[k (f v)])))
;;
;; API
;;
(defn fpartial
"Like clojure.core/partial but prepopulates last N arguments (first is passed in later)"
[f & args]
(fn [arg & more] (apply f arg (concat args more))))
(defprotocol IFNExpansion
(expand-all [x] "Replaces functions with their invocation results, recursively expands maps, evaluates all other values to themselves")
(expand-all-with [x f] "Replaces functions with their invocation results that function f is applied to, recursively expands maps, evaluates all other values to themselves"))
(extend-protocol IFNExpansion
java.lang.Integer
(expand-all [i] i)
(expand-all-with [i f] i)
java.lang.Long
(expand-all [l] l)
(expand-all-with [l f] l)
java.lang.String
(expand-all [s] s)
(expand-all-with [s f] s)
java.lang.Float
(expand-all [fl] fl)
(expand-all-with [fl f] fl)
java.lang.Double
(expand-all [d] d)
(expand-all-with [d f] d)
;; maps are also functions, so be careful here. MK.
clojure.lang.IPersistentMap
(expand-all [m] (apply-to-values m expand-all))
(expand-all-with [m f] (apply-to-values m (fpartial expand-all-with f)))
clojure.lang.PersistentVector
(expand-all [v] (map expand-all v))
(expand-all-with [v f] (map (fpartial expand-all-with f) v))
;; this distinguishes functions from maps, sets and so on, which are also
;; clojure.lang.AFn subclasses. MK.
clojure.lang.AFunction
(expand-all [f] (f))
(expand-all-with [f expander] (expander f))
Object
(expand-all [x] x)
(expand-all-with [x f] x))

View file

@ -1,360 +0,0 @@
(ns monger.multi.collection
"Includes versions of key monger.collection functions that always take a database
as explicit argument instead of relying on monger.core/*mongodb-database*.
Use these functions when you need to work with multiple databases or manage database
and connection lifecycle explicitly."
(:refer-clojure :exclude [find remove count empty? distinct drop])
(:import [com.mongodb Mongo DB DBCollection WriteResult DBObject WriteConcern DBCursor MapReduceCommand MapReduceCommand$OutputType]
[java.util List Map]
[clojure.lang IPersistentMap ISeq]
org.bson.types.ObjectId)
(:require monger.core
monger.result
[monger.conversion :refer :all]
[monger.constraints :refer :all]))
;;
;; API
;;
(defn ^WriteResult insert
"Like monger.collection/insert but always takes a database as explicit argument"
([^DB db ^String collection document]
(.insert (.getCollection db (name collection))
(to-db-object document)
monger.core/*mongodb-write-concern*))
([^DB db ^String collection document ^WriteConcern concern]
(.insert (.getCollection db (name collection))
(to-db-object document)
concern)))
(defn ^clojure.lang.IPersistentMap insert-and-return
"Like monger.collection/insert-and-return but always takes a database as explicit argument"
([^DB db ^String collection document]
(let [doc (merge {:_id (ObjectId.)} document)]
(insert db collection doc monger.core/*mongodb-write-concern*)
doc))
([^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 {:_id (ObjectId.)} document)]
(insert db collection doc concern)
doc)))
(defn ^WriteResult insert-batch
"Like monger.collection/insert-batch but always takes a database as explicit argument"
([^DB db ^String collection ^List documents]
(.insert (.getCollection db (name collection))
^List (to-db-object documents)
monger.core/*mongodb-write-concern*))
([^DB db ^String collection ^List documents ^WriteConcern concern]
(.insert (.getCollection db (name collection))
^List (to-db-object documents)
concern)))
;;
;; monger.multi.collection/find
;;
(defn ^DBCursor find
"Like monger.collection/find but always takes a database as explicit argument"
([^DB db ^String collection]
(.find (.getCollection db (name collection))))
([^DB db ^String collection ^Map ref]
(.find (.getCollection db (name collection))
(to-db-object ref)))
([^DB db ^String collection ^Map ref fields]
(.find (.getCollection db (name collection))
(to-db-object ref)
(as-field-selector fields))))
(defn find-maps
"Like monger.collection/find-maps but always takes a database as explicit argument"
([^DB db ^String collection]
(with-open [dbc (find db collection)]
(map (fn [x] (from-db-object x true)) dbc)))
([^DB db ^String collection ^Map ref]
(with-open [dbc (find db collection ref)]
(map (fn [x] (from-db-object x true)) dbc)))
([^DB db ^String collection ^Map ref fields]
(with-open [dbc (find db collection ref fields)]
(map (fn [x] (from-db-object x true)) dbc))))
(defn find-seq
"Like monger.collection/find-seq but always takes a database as explicit argument"
([^DB db ^String collection]
(with-open [dbc (find db collection)]
(seq dbc)))
([^DB db ^String collection ^Map ref]
(with-open [dbc (find db collection ref)]
(seq dbc)))
([^DB db ^String collection ^Map ref fields]
(with-open [dbc (find db collection ref fields)]
(seq dbc))))
;;
;; monger.multi.collection/find-one
;;
(defn ^DBObject find-one
"Like monger.collection/find-one but always takes a database as explicit argument"
([^DB db ^String collection ^Map ref]
(.findOne (.getCollection db (name collection))
(to-db-object ref)))
([^DB db ^String collection ^Map ref fields]
(.findOne (.getCollection db (name collection))
(to-db-object ref)
^DBObject (as-field-selector fields))))
(defn ^IPersistentMap find-one-as-map
"Like monger.collection/find-one-as-map but always takes a database as explicit argument"
([^DB db ^String collection ^Map ref]
(from-db-object ^DBObject (find-one db collection ref) true))
([^DB db ^String collection ^Map ref fields]
(from-db-object ^DBObject (find-one db collection ref fields) true))
([^DB db ^String collection ^Map ref fields keywordize]
(from-db-object ^DBObject (find-one db collection ref fields) keywordize)))
;;
;; monger.multi.collection/find-and-modify
;;
(defn ^IPersistentMap find-and-modify
"Like monger.collection/find-and-modify but always takes a database as explicit argument"
([^DB db ^String collection ^Map conditions ^Map document & {:keys [fields sort remove return-new upsert keywordize] :or
{fields nil sort nil remove false return-new false upsert false keywordize true}}]
(let [coll (.getCollection db (name collection))
maybe-fields (when fields (as-field-selector fields))
maybe-sort (when sort (to-db-object sort))]
(from-db-object
^DBObject (.findAndModify ^DBCollection coll (to-db-object conditions) maybe-fields maybe-sort remove
(to-db-object document) return-new upsert) keywordize))))
;;
;; monger.multi.collection/find-by-id
;;
(defn ^DBObject find-by-id
"Like monger.collection/find-by-id but always takes a database as explicit argument"
([^DB db ^String collection id]
(check-not-nil! id "id must not be nil")
(find-one db collection {:_id id}))
([^DB db ^String collection id fields]
(check-not-nil! id "id must not be nil")
(find-one db collection {:_id id} fields)))
(defn ^IPersistentMap find-map-by-id
"Like monger.collection/find-map-by-id but always takes a database as explicit argument"
([^DB db ^String collection id]
(check-not-nil! id "id must not be nil")
(from-db-object ^DBObject (find-one-as-map db collection {:_id id}) true))
([^DB db ^String collection id fields]
(check-not-nil! id "id must not be nil")
(from-db-object ^DBObject (find-one-as-map db collection {:_id id} fields) true))
([^DB db ^String collection id fields keywordize]
(check-not-nil! id "id must not be nil")
(from-db-object ^DBObject (find-one-as-map db collection {:_id id} fields) keywordize)))
;;
;; monger.multi.collection/count
;;
(defn count
"Like monger.collection/count but always takes a database as explicit argument"
(^long [^DB db ^String collection]
(.count (.getCollection db (name collection)) (to-db-object {})))
(^long [^DB db ^String collection ^Map conditions]
(.count (.getCollection db (name collection)) (to-db-object conditions))))
(defn any?
"Like monger.collection/any? but always takes a database as explicit argument"
([^DB db ^String collection]
(> (count db collection) 0))
([^DB db ^String collection ^Map conditions]
(> (count db collection conditions) 0)))
(defn empty?
"Like monger.collection/empty? but always takes a database as explicit argument"
([^DB db ^String collection]
(= (count db collection {}) 0)))
(defn ^WriteResult update
"Like monger.collection/update but always takes a database as explicit argument"
([^DB db ^String collection ^Map conditions ^Map document & {:keys [upsert multi write-concern] :or {upsert false
multi false
write-concern monger.core/*mongodb-write-concern*}}]
(.update (.getCollection db (name collection))
(to-db-object conditions)
(to-db-object document)
upsert
multi
write-concern)))
(defn ^WriteResult upsert
"Like monger.collection/upsert but always takes a database as explicit argument"
[^DB db ^String collection ^Map conditions ^Map document & {:keys [multi write-concern] :or {multi false
write-concern monger.core/*mongodb-write-concern*}}]
(update db collection conditions document :multi multi :write-concern write-concern :upsert true))
(defn ^WriteResult update-by-id
"Like monger.collection/update-by-id but always takes a database as explicit argument"
[^DB db ^String collection id ^Map document & {:keys [upsert write-concern] :or {upsert false
write-concern monger.core/*mongodb-write-concern*}}]
(check-not-nil! id "id must not be nil")
(.update (.getCollection db (name collection))
(to-db-object {:_id id})
(to-db-object document)
upsert
false
write-concern))
(defn ^WriteResult save
"Like monger.collection/save but always takes a database as explicit argument"
([^DB db ^String collection ^Map document]
(.save (.getCollection db (name collection))
(to-db-object document)
monger.core/*mongodb-write-concern*))
([^DB db ^String collection ^Map document ^WriteConcern write-concern]
(.save (.getCollection db (name collection))
(to-db-object document)
write-concern)))
(defn ^clojure.lang.IPersistentMap save-and-return
"Like monger.collection/save-and-return but always takes a database as explicit argument"
([^DB db ^String collection ^Map document]
(save-and-return ^DB db collection document ^WriteConcern monger.core/*mongodb-write-concern*))
([^DB db ^String collection ^Map document ^WriteConcern write-concern]
;; see the comment in insert-and-return. Here we additionally need to make sure to not scrap the :_id key if
;; it is already present. MK.
(let [doc (merge {:_id (ObjectId.)} document)]
(save db collection doc write-concern)
doc)))
(defn ^WriteResult remove
"Like monger.collection/remove but always takes a database as explicit argument"
([^DB db ^String collection]
(.remove (.getCollection db (name collection)) (to-db-object {})))
([^DB db ^String collection ^Map conditions]
(.remove (.getCollection db (name collection)) (to-db-object conditions))))
(defn ^WriteResult remove-by-id
"Like monger.collection/remove-by-id but always takes a database as explicit argument"
([^DB db ^String collection id]
(check-not-nil! id "id must not be nil")
(let [coll (.getCollection db (name collection))]
(.remove coll (to-db-object {:_id id})))))
;;
;; monger.multi.collection/create-index
;;
(defn create-index
"Like monger.collection/create-index but always takes a database as explicit argument"
([^DB db ^String collection ^Map keys]
(.createIndex (.getCollection db (name collection)) (as-field-selector keys)))
([^DB db ^String collection ^Map keys ^Map options]
(.createIndex (.getCollection db (name collection))
(as-field-selector keys)
(to-db-object options))))
;;
;; monger.multi.collection/ensure-index
;;
(defn ensure-index
"Like monger.collection/ensure-index but always takes a database as explicit argument"
([^DB db ^String collection ^Map keys]
(.ensureIndex (.getCollection db (name collection)) (as-field-selector keys)))
([^DB db ^String collection ^Map keys ^Map options]
(.ensureIndex (.getCollection db (name collection))
(as-field-selector keys)
(to-db-object options)))
([^DB db ^String collection ^Map keys ^String name ^Boolean unique?]
(.ensureIndex (.getCollection db (name collection))
(as-field-selector keys)
name
unique?)))
;;
;; monger.multi.collection/indexes-on
;;
(defn indexes-on
"Like monger.collection/indexes-on but always takes a database as explicit argument"
[^DB db ^String collection]
(from-db-object (.getIndexInfo (.getCollection db (name collection))) true))
;;
;; monger.multi.collection/drop-index
;;
(defn drop-index
"Like monger.collection/drop-index but always takes a database as explicit argument"
([^DB db ^String collection ^String idx-name]
(.dropIndex (.getCollection db (name collection)) idx-name)))
(defn drop-indexes
"Like monger.collection/drop-indexes but always takes a database as explicit argument"
([^DB db ^String collection]
(.dropIndexes (.getCollection db (name collection)))))
;;
;; monger.multi.collection/exists?, /create, /drop, /rename
;;
(defn exists?
"Like monger.collection/exists? but always takes a database as explicit argument"
([^DB db ^String collection]
(.collectionExists db collection)))
(defn create
"Like monger.collection/create but always takes a database as explicit argument"
([^DB db ^String collection ^Map options]
(.createCollection db collection (to-db-object options))))
(defn drop
"Like monger.collection/drop but always takes a database as explicit argument"
([^DB db ^String collection]
(.drop (.getCollection db (name collection)))))
(defn rename
"Like monger.collection/rename but always takes a database as explicit argument"
([^DB db ^String from, ^String to]
(.rename (.getCollection db from) to))
([^DB db ^String from ^String to ^Boolean drop-target]
(.rename (.getCollection db from) to drop-target)))
;;
;; Map/Reduce
;;
(defn map-reduce
"Like monger.collection/map-reduce but always takes a database as explicit argument"
([^DB db ^String collection ^String js-mapper ^String js-reducer ^String output ^Map query]
(let [coll (.getCollection db (name collection))]
(.mapReduce coll js-mapper js-reducer output (to-db-object query))))
([^DB db ^String collection ^String js-mapper ^String js-reducer ^String output ^MapReduceCommand$OutputType output-type ^Map query]
(let [coll (.getCollection db (name collection))]
(.mapReduce coll js-mapper js-reducer output output-type (to-db-object query)))))
;;
;; monger.multi.collection/distinct
;;
(defn distinct
"Like monger.collection/distinct but always takes a database as explicit argument"
([^DB db ^String collection ^String key]
(.distinct (.getCollection db (name collection)) ^String (to-db-object key)))
([^DB db ^String collection ^String key ^Map query]
(.distinct (.getCollection db (name collection)) ^String (to-db-object key) (to-db-object query))))

View file

@ -63,7 +63,19 @@
(merge (empty-query) { :collection coll })))
(defn exec
[{ :keys [^DBCollection collection query fields skip limit sort batch-size hint snapshot read-preference keywordize-fields options] :or { limit 0 batch-size 256 skip 0 } }]
[{:keys [^DBCollection collection
query
fields
skip
limit
sort
batch-size
hint
snapshot
read-preference
keywordize-fields
options]
:or { limit 0 batch-size 256 skip 0 } }]
(with-open [cursor (doto (.find collection (to-db-object query) (as-field-selector fields))
(.limit limit)
(.skip skip)
@ -132,10 +144,10 @@
(merge m { :limit per-page :skip (monger.internal.pagination/offset-for page per-page) }))
(defmacro with-collection
[^String coll & body]
[^DB db ^String coll & body]
`(let [coll# ~coll
db-coll# (if (string? coll#)
(.getCollection ^DB monger.core/*mongodb-database* ^String coll#)
(.getCollection ~db ^String coll#)
coll#)
query# (-> (empty-query db-coll#) ~@body)]
(exec query#)))

View file

@ -22,7 +22,6 @@
migrations-collection "meta.migrations")
(extend-type com.mongodb.DB
ragtime/Migratable
(add-migration-id [db id]
@ -30,15 +29,13 @@
(remove-migration-id [db id]
(mc/remove-by-id db migrations-collection id))
(applied-migration-ids [db]
(mg/with-db db
(let [xs (with-collection migrations-collection
(let [xs (with-collection db migrations-collection
(find {})
(sort {:created_at 1}))]
(vec (map :_id xs))))))
(vec (map :_id xs)))))
(defn flush-migrations!
"REMOVES all the information about previously performed migrations"
[db]
(mg/with-db db
(mc/remove migrations-collection)))
[^DB db]
(mc/remove db migrations-collection))

View file

@ -9,7 +9,7 @@
(ns monger.ring.session-store
(:require [ring.middleware.session.store :as ringstore]
[monger.multi.collection :as mc]
[monger.collection :as mc]
[monger.core :as mg]
[monger.conversion :refer :all])
(:import [java.util UUID Date]
@ -78,12 +78,8 @@
(defn session-store
([]
(ClojureReaderBasedMongoDBSessionStore. mg/*mongodb-database* default-session-store-collection))
([^String s]
(ClojureReaderBasedMongoDBSessionStore. mg/*mongodb-database* s))
([^DB db ^String s]
(ClojureReaderBasedMongoDBSessionStore. db s)))
[^DB db ^String s]
(ClojureReaderBasedMongoDBSessionStore. db s))
;; this session store won't store namespaced keywords correctly but stores results in a way
@ -111,9 +107,5 @@
(defn monger-store
([]
(MongoDBSessionStore. mg/*mongodb-database* default-session-store-collection))
([^String s]
(MongoDBSessionStore. mg/*mongodb-database* s))
([^DB db ^String s]
(MongoDBSessionStore. db s)))
[^DB db ^String s]
(MongoDBSessionStore. db s))

View file

@ -11,7 +11,7 @@
"Full text search queries support (MongoDB 2.4+)"
(:require [monger.command :as cmd]
[monger.conversion :as cnv])
(:import [com.mongodb CommandResult BasicDBList DBObject]))
(:import [com.mongodb DB CommandResult BasicDBList DBObject]))
;;
;; Implementation
@ -28,8 +28,8 @@
(defn search
"Performs a full text search query"
[^String collection query]
(cmd/search collection query))
[^DB db ^String collection query]
(cmd/search db collection query))
(defn results-from
"Returns a lazy sequence of results from a search query response, sorted by score.

View file

@ -1,44 +0,0 @@
;; Copyright (c) 2011-2014 Michael S. Klishin
;;
;; The use and distribution terms for this software are covered by the
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this distribution.
;; By using this software in any fashion, you are agreeing to be bound by
;; the terms of this license.
;; You must not remove this notice, or any other, from this software.
(ns monger.testkit
"Automated testing helpers"
(:require [monger.collection :as mc]))
;;
;; API
;;
(defmacro defcleaner
"Defines a fixture function that removes all documents from a collection. If collection is not specified,
a conventionally named var will be used. Supposed to be used with clojure.test/use-fixtures but may
be useful on its own.
Examples:
(defcleaner events) ;; collection name will be taken from the events-collection var
(defcleaner people \"accounts\") ;; collection name is given
"
([entities]
(let [coll-arg (symbol (str entities "-collection"))
fn-name (symbol (str "purge-" entities))]
`(defn ~fn-name
[f#]
(mc/remove ~coll-arg)
(f#)
(mc/remove ~coll-arg))))
([entities coll-name]
(let [coll-arg (name coll-name)
fn-name (symbol (str "purge-" entities))]
`(defn ~fn-name
[f#]
(mc/remove ~coll-arg)
(f#)
(mc/remove ~coll-arg)))))

View file

@ -1,18 +1,22 @@
(ns monger.test.aggregation-framework-test
(:require monger.core [monger.collection :as mc]
[monger.test.helper :as helper]
(:require [monger.core :as mg]
[monger.collection :as mc]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
[monger.operators :refer :all]))
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")
coll "docs"]
(defn purge-collections
[f]
(mc/purge-many db [coll])
(f)
(mc/purge-many db [coll]))
(helper/connect!)
(use-fixtures :each purge-collections)
(use-fixtures :each purge-docs)
(deftest test-basic-single-stage-$project-aggregation
(let [collection "docs"
batch [{ :state "CA" :quantity 1 :price 199.00 }
(deftest test-basic-single-stage-$project-aggregation
(let [batch [{ :state "CA" :quantity 1 :price 199.00 }
{ :state "NY" :quantity 2 :price 199.00 }
{ :state "NY" :quantity 1 :price 299.00 }
{ :state "IL" :quantity 2 :price 11.50 }
@ -24,16 +28,15 @@
{:quantity 2 :state "IL"}
{:quantity 2 :state "CA"}
{:quantity 3 :state "IL"}}]
(mc/insert-batch collection batch)
(is (= 6 (mc/count collection)))
(mc/insert-batch db coll batch)
(is (= 6 (mc/count db coll)))
(let [result (set (map #(select-keys % [:state :quantity])
(mc/aggregate "docs" [{$project {:state 1 :quantity 1}}])))]
(mc/aggregate db coll [{$project {:state 1 :quantity 1}}])))]
(is (= expected result)))))
(deftest test-basic-projection-with-multiplication
(let [collection "docs"
batch [{ :state "CA" :quantity 1 :price 199.00 }
(deftest test-basic-projection-with-multiplication
(let [batch [{ :state "CA" :quantity 1 :price 199.00 }
{ :state "NY" :quantity 2 :price 199.00 }
{ :state "NY" :quantity 1 :price 299.00 }
{ :state "IL" :quantity 2 :price 11.50 }
@ -45,23 +48,22 @@
{:_id "CA" :subtotal 5.9}
{:_id "IL" :subtotal 16.5}
{:_id "CA" :subtotal 199.0}}]
(mc/insert-batch collection batch)
(let [result (set (mc/aggregate "docs" [{$project {:subtotal {$multiply ["$quantity", "$price"]}
(mc/insert-batch db coll batch)
(let [result (set (mc/aggregate db coll [{$project {:subtotal {$multiply ["$quantity", "$price"]}
:_id "$state"}}]))]
(is (= expected result)))))
(deftest test-basic-total-aggregation
(let [collection "docs"
batch [{ :state "CA" :quantity 1 :price 199.00 }
(deftest test-basic-total-aggregation
(let [batch [{ :state "CA" :quantity 1 :price 199.00 }
{ :state "NY" :quantity 2 :price 199.00 }
{ :state "NY" :quantity 1 :price 299.00 }
{ :state "IL" :quantity 2 :price 11.50 }
{ :state "CA" :quantity 2 :price 2.95 }
{ :state "IL" :quantity 3 :price 5.50 }]
expected #{{:_id "CA" :total 204.9} {:_id "IL" :total 39.5} {:_id "NY" :total 697.0}}]
(mc/insert-batch collection batch)
(let [result (set (mc/aggregate "docs" [{$project {:subtotal {$multiply ["$quantity", "$price"]}
(mc/insert-batch db coll batch)
(let [result (set (mc/aggregate db coll [{$project {:subtotal {$multiply ["$quantity", "$price"]}
:_id 1
:state 1}}
{$group {:_id "$state"
@ -69,20 +71,18 @@
(is (= expected result)))))
(deftest test-$first-aggregation-operator
(let [collection "docs"
batch [{ :state "CA" }
(deftest test-$first-aggregation-operator
(let [batch [{ :state "CA" }
{ :state "IL"}]
expected "CA"]
(mc/insert-batch collection batch)
(let [result (:state (first (mc/aggregate collection [{$group { :_id 1 :state {$first "$state"} }}])))]
(mc/insert-batch db coll batch)
(let [result (:state (first (mc/aggregate db coll [{$group { :_id 1 :state {$first "$state"} }}])))]
(is (= expected result)))))
(deftest test-$last-aggregation-operator
(let [collection "docs"
batch [{ :state "CA" }
(deftest test-$last-aggregation-operator
(let [batch [{ :state "CA" }
{ :state "IL"}]
expected "IL"]
(mc/insert-batch collection batch)
(let [result (:state (first (mc/aggregate collection [{$group { :_id 1 :state {$last "$state"} }}])))]
(is (= expected result)))))
(mc/insert-batch db coll batch)
(let [result (:state (first (mc/aggregate db coll [{$group { :_id 1 :state {$last "$state"} }}])))]
(is (= expected result))))))

View file

@ -1,365 +1,400 @@
(ns monger.test.atomic-modifiers-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject]
(:import [com.mongodb WriteResult WriteConcern DBObject]
[org.bson.types ObjectId]
[java.util Date])
(:require [monger core util]
[monger.collection :as mgcol]
java.util.Date)
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.result :as mgres]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
(helper/connect!)
(use-fixtures :each purge-docs purge-things purge-scores)
[monger.operators :refer :all]))
;;
;; $inc
;;
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(deftest increment-a-single-existing-field-using-$inc-modifier
(defn purge-collections
[f]
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "scores")
(f)
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "scores"))
(use-fixtures :each purge-collections)
;;
;; $inc
;;
(deftest increment-a-single-existing-field-using-$inc-modifier
(let [coll "scores"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :username "l33r0y" :score 100 })
(mgcol/update coll { :_id oid } { $inc { :score 20 } })
(is (= 120 (:score (mgcol/find-map-by-id coll oid))))))
(mc/insert db coll { :_id oid :username "l33r0y" :score 100 })
(mc/update db coll { :_id oid } { $inc { :score 20 } })
(is (= 120 (:score (mc/find-map-by-id db coll oid))))))
(deftest set-a-single-non-existing-field-using-$inc-modifier
(deftest set-a-single-non-existing-field-using-$inc-modifier
(let [coll "scores"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :username "l33r0y" })
(mgcol/update coll { :_id oid } { $inc { :score 30 } })
(is (= 30 (:score (mgcol/find-map-by-id coll oid))))))
(mc/insert db coll { :_id oid :username "l33r0y" })
(mc/update db coll { :_id oid } { $inc { :score 30 } })
(is (= 30 (:score (mc/find-map-by-id db coll oid))))))
(deftest increment-multiple-existing-fields-using-$inc-modifier
(deftest increment-multiple-existing-fields-using-$inc-modifier
(let [coll "scores"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :username "l33r0y" :score 100 :bonus 0 })
(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)))))
(mc/insert db coll { :_id oid :username "l33r0y" :score 100 :bonus 0 })
(mc/update db coll { :_id oid } {$inc { :score 20 :bonus 10 } })
(is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" }
(mc/find-map-by-id db coll oid)))))
(deftest increment-and-set-multiple-existing-fields-using-$inc-modifier
(deftest increment-and-set-multiple-existing-fields-using-$inc-modifier
(let [coll "scores"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :username "l33r0y" :score 100 })
(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)))))
(mc/insert db coll { :_id oid :username "l33r0y" :score 100 })
(mc/update db coll { :_id oid } { $inc { :score 20 :bonus 10 } })
(is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" }
(mc/find-map-by-id db coll oid)))))
;;
;; $set
;;
;;
;; $set
;;
(deftest update-a-single-existing-field-using-$set-modifier
(deftest update-a-single-existing-field-using-$set-modifier
(let [coll "things"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 })
(mgcol/update coll { :_id oid } { $set { :weight 20.5 } })
(is (= 20.5 (:weight (mgcol/find-map-by-id coll oid [:weight]))))))
(mc/insert db coll { :_id oid :weight 10.0 })
(mc/update db coll { :_id oid } { $set { :weight 20.5 } })
(is (= 20.5 (:weight (mc/find-map-by-id db 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"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 })
(mgcol/update coll { :_id oid } { $set { :height 17.2 } })
(is (= 17.2 (:height (mgcol/find-map-by-id coll oid [:height]))))))
(mc/insert db coll { :_id oid :weight 10.0 })
(mc/update db coll { :_id oid } { $set { :height 17.2 } })
(is (= 17.2 (:height (mc/find-map-by-id db coll oid [:height]))))))
(deftest update-multiple-existing-fields-using-$set-modifier
(deftest update-multiple-existing-fields-using-$set-modifier
(let [coll "things"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 :height 15.2 })
(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 :height])))))
(mc/insert db coll { :_id oid :weight 10.0 :height 15.2 })
(mc/update db coll { :_id oid } { $set { :weight 20.5 :height 25.6 } })
(is (= { :_id oid :weight 20.5 :height 25.6 }
(mc/find-map-by-id db coll oid [:weight :height])))))
(deftest update-and-set-multiple-fields-using-$set-modifier
(deftest update-and-set-multiple-fields-using-$set-modifier
(let [coll "things"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :weight 10.0 })
(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 :height])))))
(mc/insert db coll { :_id oid :weight 10.0 })
(mc/update db coll { :_id oid } {$set { :weight 20.5 :height 25.6 } })
(is (= { :_id oid :weight 20.5 :height 25.6 }
(mc/find-map-by-id db coll oid [:weight :height])))))
;;
;; $unset
;;
;;
;; $unset
;;
(deftest unset-a-single-existing-field-using-$unset-modifier
(deftest unset-a-single-existing-field-using-$unset-modifier
(let [coll "docs"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :title "Document 1" :published true })
(mgcol/update coll { :_id oid } { $unset { :published 1 } })
(is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title "Document 1" :published true })
(mc/update db coll { :_id oid } { $unset { :published 1 } })
(is (= { :_id oid :title "Document 1" }
(mc/find-map-by-id db coll oid)))))
(deftest unset-multiple-existing-fields-using-$unset-modifier
(deftest unset-multiple-existing-fields-using-$unset-modifier
(let [coll "docs"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :title "Document 1" :published true :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)))))
(mc/insert db coll { :_id oid :title "Document 1" :published true :featured true })
(mc/update db coll { :_id oid } { $unset { :published 1 :featured true } })
(is (= { :_id oid :title "Document 1" }
(mc/find-map-by-id db coll oid)))))
(deftest unsetting-an-unexisting-field-using-$unset-modifier-is-not-considered-an-issue
(deftest unsetting-an-unexisting-field-using-$unset-modifier-is-not-considered-an-issue
(let [coll "docs"
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :title "Document 1" :published 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)))))
(mc/insert db coll { :_id oid :title "Document 1" :published true })
(is (mgres/ok? (mc/update db coll { :_id oid } { $unset { :published 1 :featured true } })))
(is (= { :_id oid :title "Document 1" }
(mc/find-map-by-id db coll oid)))))
;;
;; $setOnInsert
;;
;;
;; $setOnInsert
;;
(deftest setOnInsert-in-upsert-for-non-existing-document
(deftest setOnInsert-in-upsert-for-non-existing-document
(let [coll "docs"
now 456
oid (ObjectId.)]
(mgcol/find-and-modify coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true)
(is (= { :_id oid :lastseen now :firstseen now} (mgcol/find-map-by-id coll oid)))))
(mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} {:upsert true})
(is (= { :_id oid :lastseen now :firstseen now}
(mc/find-map-by-id db coll oid)))))
(deftest setOnInsert-in-upsert-for-existing-document
(deftest setOnInsert-in-upsert-for-existing-document
(let [coll "docs"
before 123
now 456
oid (ObjectId.)]
(mgcol/insert coll { :_id oid :firstseen before :lastseen before})
(mgcol/find-and-modify coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true)
(is (= { :_id oid :lastseen now :firstseen before} (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :firstseen before :lastseen before})
(mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} {:upsert true})
(is (= { :_id oid :lastseen now :firstseen before}
(mc/find-map-by-id db coll oid)))))
;;
;; $push
;;
;;
;; $push
;;
(deftest initialize-an-array-using-$push-modifier
(deftest initialize-an-array-using-$push-modifier
(let [coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mgcol/insert coll { :_id oid :title title })
(mgcol/update coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["modifiers"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["modifiers"] }
(mc/find-map-by-id db coll oid)))))
(deftest add-value-to-an-existing-array-using-$push-modifier
(deftest add-value-to-an-existing-array-using-$push-modifier
(let [coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mgcol/insert coll { :_id oid :title title :tags ["mongodb"] })
(mgcol/update coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] }
(mc/find-map-by-id db coll oid)))))
;; this is a common mistake, I leave it here to demonstrate it. You almost never
;; actually want to do this! What you really want is to use $pushAll instead of $push. MK.
(deftest add-array-value-to-an-existing-array-using-$push-modifier
;; this is a common mistake, I leave it here to demonstrate it. You almost never
;; actually want to do this! What you really want is to use $pushAll instead of $push. MK.
(deftest add-array-value-to-an-existing-array-using-$push-modifier
(let [coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mgcol/insert coll { :_id oid :title title :tags ["mongodb"] })
(mgcol/update coll { :_id oid } { $push { :tags ["modifiers" "operators"] } })
(is (= { :_id oid :title title :tags ["mongodb" ["modifiers" "operators"]] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $push { :tags ["modifiers" "operators"] } })
(is (= { :_id oid :title title :tags ["mongodb" ["modifiers" "operators"]] }
(mc/find-map-by-id db coll oid)))))
(deftest double-add-value-to-an-existing-array-using-$push-modifier
(deftest double-add-value-to-an-existing-array-using-$push-modifier
(let [coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mgcol/insert coll { :_id oid :title title :tags ["mongodb"] })
(mgcol/update coll { :_id oid } { $push { :tags "modifiers" } })
(mgcol/update coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers" "modifiers"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers" "modifiers"] }
(mc/find-map-by-id db coll oid)))))
;;
;; $pushAll
;;
;;
;; $pushAll
;;
(deftest initialize-an-array-using-$pushAll-modifier
(deftest initialize-an-array-using-$pushAll-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"]
(mgcol/insert coll { :_id oid :title title })
(mgcol/update coll { :_id oid } { $pushAll { :tags ["mongodb" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "docs"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title })
(mc/update db coll { :_id oid } { $pushAll { :tags ["mongodb" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "docs"] }
(mc/find-map-by-id db coll oid)))))
(deftest add-value-to-an-existing-array-using-$pushAll-modifier
(deftest add-value-to-an-existing-array-using-$pushAll-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"]
(mgcol/insert coll { :_id oid :title title :tags ["mongodb"] })
(mgcol/update coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers" "docs"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers" "docs"] }
(mc/find-map-by-id db coll oid)))))
(deftest double-add-value-to-an-existing-array-using-$pushAll-modifier
(deftest double-add-value-to-an-existing-array-using-$pushAll-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"]
(mgcol/insert coll { :_id oid :title title :tags ["mongodb" "docs"] })
(mgcol/update coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["mongodb" "docs"] })
(mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"] }
(mc/find-map-by-id db coll oid)))))
;;
;; $addToSet
;;
;;
;; $addToSet
;;
(deftest initialize-an-array-using-$addToSet-modifier
(deftest initialize-an-array-using-$addToSet-modifier
(let [coll "docs"
oid (ObjectId.)
title "$addToSet modifier appends value to field unless it is already there"]
(mgcol/insert coll { :_id oid :title title })
(mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["modifiers"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["modifiers"] }
(mc/find-map-by-id db coll oid)))))
(deftest add-value-to-an-existing-array-using-$addToSet-modifier
(deftest add-value-to-an-existing-array-using-$addToSet-modifier
(let [coll "docs"
oid (ObjectId.)
title "$addToSet modifier appends value to field unless it is already there"]
(mgcol/insert coll { :_id oid :title title :tags ["mongodb"] })
(mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] }
(mc/find-map-by-id db coll oid)))))
(deftest double-add-value-to-an-existing-array-using-$addToSet-modifier
(deftest double-add-value-to-an-existing-array-using-$addToSet-modifier
(let [coll "docs"
oid (ObjectId.)
title "$addToSet modifier appends value to field unless it is already there"]
(mgcol/insert coll { :_id oid :title title :tags ["mongodb"] })
(mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } })
(mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] }
(mc/find-map-by-id db coll oid)))))
;;
;; $pop
;;
;;
;; $pop
;;
(deftest pop-last-value-in-the-array-using-$pop-modifier
(deftest pop-last-value-in-the-array-using-$pop-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pop modifier removes last or first value in the array"]
(mgcol/insert coll { :_id oid :title title :tags ["products" "apple" "reviews"] })
(mgcol/update coll { :_id oid } { $pop { :tags 1 } })
(is (= { :_id oid :title title :tags ["products" "apple"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] })
(mc/update db coll { :_id oid } { $pop { :tags 1 } })
(is (= { :_id oid :title title :tags ["products" "apple"] }
(mc/find-map-by-id db coll oid)))))
(deftest unshift-first-value-in-the-array-using-$pop-modifier
(deftest unshift-first-value-in-the-array-using-$pop-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pop modifier removes last or first value in the array"]
(mgcol/insert coll { :_id oid :title title :tags ["products" "apple" "reviews"] })
(mgcol/update coll { :_id oid } { $pop { :tags -1 } })
(is (= { :_id oid :title title :tags ["apple" "reviews"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] })
(mc/update db coll { :_id oid } { $pop { :tags -1 } })
(is (= { :_id oid :title title :tags ["apple" "reviews"] }
(mc/find-map-by-id db coll oid)))))
(deftest pop-last-values-from-multiple-arrays-using-$pop-modifier
(deftest pop-last-values-from-multiple-arrays-using-$pop-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pop modifier removes last or first value in the array"]
(mgcol/insert coll { :_id oid :title title :tags ["products" "apple" "reviews"] :categories ["apple" "reviews" "drafts"] })
(mgcol/update coll { :_id oid } { $pop { :tags 1 :categories 1 } })
(is (= { :_id oid :title title :tags ["products" "apple"] :categories ["apple" "reviews"] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] :categories ["apple" "reviews" "drafts"] })
(mc/update db coll { :_id oid } { $pop { :tags 1 :categories 1 } })
(is (= { :_id oid :title title :tags ["products" "apple"] :categories ["apple" "reviews"] }
(mc/find-map-by-id db coll oid)))))
;;
;; $pull
;;
;;
;; $pull
;;
(deftest remove-all-value-entries-from-array-using-$pull-modifier
(deftest remove-all-value-entries-from-array-using-$pull-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pull modifier removes all value entries in the array"]
(mgcol/insert coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mgcol/update coll { :_id oid } { $pull { :measurements 1.2 } })
(is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.3 1.0] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mc/update db coll { :_id oid } { $pull { :measurements 1.2 } })
(is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.3 1.0] }
(mc/find-map-by-id db coll oid)))))
(deftest remove-all-value-entries-from-array-using-$pull-modifier-based-on-a-condition
(deftest remove-all-value-entries-from-array-using-$pull-modifier-based-on-a-condition
(let [coll "docs"
oid (ObjectId.)
title "$pull modifier removes all value entries in the array"]
(mgcol/insert coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mgcol/update coll { :_id oid } { $pull { :measurements { $gte 1.2 } } })
(is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.0] } (mgcol/find-map-by-id coll oid)))))
;;
;; $pullAll
;;
(mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mc/update db coll { :_id oid } { $pull { :measurements { $gte 1.2 } } })
(is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.0] }
(mc/find-map-by-id db coll oid)))))
;;
;; $pullAll
;;
(deftest remove-all-value-entries-from-array-using-$pullAll-modifier
(deftest remove-all-value-entries-from-array-using-$pullAll-modifier
(let [coll "docs"
oid (ObjectId.)
title "$pullAll modifier removes entries of multiple values in the array"]
(mgcol/insert coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mgcol/update coll { :_id oid } { $pullAll { :measurements [1.0 1.1 1.2] } })
(is (= { :_id oid :title title :measurements [1.3] } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mc/update db coll { :_id oid } { $pullAll { :measurements [1.0 1.1 1.2] } })
(is (= { :_id oid :title title :measurements [1.3] }
(mc/find-map-by-id db coll oid)))))
;;
;; $rename
;;
;;
;; $rename
;;
(deftest rename-a-single-field-using-$rename-modifier
(deftest rename-a-single-field-using-$rename-modifier
(let [coll "docs"
oid (ObjectId.)
title "$rename renames fields"
v [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0]]
(mgcol/insert coll { :_id oid :title title :measurements v })
(mgcol/update coll { :_id oid } { $rename { :measurements "results" } })
(is (= { :_id oid :title title :results v } (mgcol/find-map-by-id coll oid)))))
(mc/insert db coll { :_id oid :title title :measurements v })
(mc/update db coll { :_id oid } { $rename { :measurements "results" } })
(is (= { :_id oid :title title :results v }
(mc/find-map-by-id db coll oid)))))
;;
;; find-and-modify
;;
;;
;; find-and-modify
;;
(deftest find-and-modify-a-single-document
(deftest find-and-modify-a-single-document
(let [coll "docs"
oid (ObjectId.)
doc {:_id oid :name "Sophie Bangs" :level 42}
conditions {:name "Sophie Bangs"}
update {$inc {:level 1}}]
(mgcol/insert coll doc)
(let [res (mgcol/find-and-modify coll conditions update :return-new true)]
(mc/insert db coll doc)
(let [res (mc/find-and-modify db coll conditions update {:return-new true})]
(is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 43})))))
(deftest find-and-modify-remove-a-document
(deftest find-and-modify-remove-a-document
(let [coll "docs"
oid (ObjectId.)
doc {:_id oid :name "Sophie Bangs" :level 42}
conditions {:name "Sophie Bangs"}]
(mgcol/insert coll doc)
(let [res (mgcol/find-and-modify coll conditions {} :remove true)]
(mc/insert db coll doc)
(let [res (mc/find-and-modify db coll conditions {} {:remove true})]
(is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42}))
(is (empty? (mgcol/find-maps coll conditions))))))
(is (empty? (mc/find-maps db coll conditions))))))
(deftest find-and-modify-upsert-a-document
(deftest find-and-modify-upsert-a-document
(testing "case 1"
(let [coll "docs"
oid (ObjectId.)
doc {:_id oid :name "Sophie Bangs" :level 42}]
(let [res (mgcol/find-and-modify coll doc doc :upsert true)]
(let [res (mc/find-and-modify db coll doc doc {:upsert true})]
(is (empty? res))
(is (select-keys (mgcol/find-map-by-id coll oid) [:name :level]) (dissoc doc :_id)))))
(is (select-keys (mc/find-map-by-id db coll oid) [:name :level]) (dissoc doc :_id)))))
(testing "case 2"
(let [coll "docs"
query {:name "Sophie Bangs"}
doc (merge query {:level 42})]
(let [res (mgcol/find-and-modify coll query doc :upsert true :return-new true)]
(let [res (mc/find-and-modify db coll query doc {:upsert true :return-new true})]
(is (:_id res))
(is (select-keys (mgcol/find-map-by-id coll (:_id res)) [:name :level]) doc)))))
(is (select-keys (mc/find-map-by-id db coll (:_id res)) [:name :level]) doc)))))
(deftest find-and-modify-after-sort
(deftest find-and-modify-after-sort
(let [coll "docs"
oid (ObjectId.)
oid2 (ObjectId.)
doc {:name "Sophie Bangs"}
doc1 (assoc doc :_id oid :level 42)
doc2 (assoc doc :_id oid2 :level 0)]
(mgcol/insert-batch coll [doc1 doc2])
(let [res (mgcol/find-and-modify coll doc {$inc {:level 1}} :sort {:level -1})]
(is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42})))))
(mc/insert-batch db coll [doc1 doc2])
(let [res (mc/find-and-modify db coll doc {$inc {:level 1}} {:sort {:level -1}})]
(is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42}))))))

View file

@ -1,52 +1,53 @@
(ns monger.test.authentication-test
(:require [monger core util db]
[monger.test.helper :as helper]
(:require [monger util db]
[monger.core :as mg]
[monger.collection :as mc]
[clojure.test :refer :all]))
(helper/connect!)
;;
;; Connection via URI
;;
(when-not (System/getenv "CI")
(deftest ^{:authentication true} connect-to-mongo-via-uri-without-credentials
(let [connection (monger.core/connect-via-uri! "mongodb://127.0.0.1/monger-test4")]
(is (= (-> connection .getAddress ^InetAddress (.sameHost "127.0.0.1")))))
;; reconnect using regular host
(helper/connect!))
(let [{:keys [conn db]} (mg/connect-via-uri "mongodb://127.0.0.1/monger-test4")]
(is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1"))))))
(deftest ^{:authentication true} connect-to-mongo-via-uri-with-valid-credentials
(let [connection (monger.core/connect-via-uri! "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")]
(is (= "monger-test4" (.getName (monger.core/current-db))))
(is (= (-> connection .getAddress ^InetAddress (.sameHost "127.0.0.1"))))
(mc/remove "documents")
(let [{:keys [conn db]} (mg/connect-via-uri "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")]
(is (= "monger-test4" (.getName db)))
(is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1"))))
(mc/remove db "documents")
;; make sure that the database is selected
;; and operations get through.
(mc/insert "documents" {:field "value"})
(is (= 1 (mc/count "documents" {}))))
;; reconnect using regular host
(helper/connect!)))
(mc/insert db "documents" {:field "value"})
(is (= 1 (mc/count db "documents" {}))))))
(if-let [uri (System/getenv "MONGOHQ_URL")]
(deftest ^{:external true :authentication true} connect-to-mongo-via-uri-with-valid-credentials
(let [connection (monger.core/connect-via-uri! uri)]
(is (= (-> connection .getAddress ^InetAddress (.sameHost "127.0.0.1")))))
;; reconnect using regular host
(helper/connect!)))
(let [{:keys [conn db]} (mg/connect-via-uri uri)]
(is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1")))))))
(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-the-default-db
;;
;; Regular connecton
;;
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-the-default-db
;; see ./bin/ci/before_script.sh. MK.
(let [username "clojurewerkz/monger"
pwd "monger"]
(is (monger.core/authenticate username (.toCharArray pwd)))))
(is (mg/authenticate db username (.toCharArray pwd)))))
(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-an-arbitrary-db
(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-an-arbitrary-db
;; see ./bin/ci/before_script.sh. MK.
(let [username "clojurewerkz/monger"
pwd "monger"]
(is (monger.core/authenticate (monger.core/get-db "monger-test") username (.toCharArray pwd)))))
(is (mg/authenticate (mg/get-db conn "monger-test") username (.toCharArray pwd)))))
(deftest ^{:authentication true} test-authentication-with-invalid-credentials
(deftest ^{:authentication true} test-authentication-with-invalid-credentials
(let [username "monger"
^String pwd (monger.util/random-str 128 32)]
(is (not (monger.core/authenticate (monger.core/get-db "monger-test2") username (.toCharArray pwd))))))
(is (not (mg/authenticate (mg/get-db conn "monger-test2") username (.toCharArray pwd)))))))

View file

@ -1,6 +1,5 @@
(ns monger.test.cache-test
(:require [monger.test.helper :as helper]
[monger.core :as mg]
(:require [monger.core :as mg]
[monger.collection :as mc]
[clojure.core.cache :refer :all]
[clojure.test :refer :all]
@ -83,39 +82,35 @@
;; Tests
;;
(helper/connect!)
(use-fixtures :each (fn [f]
(mc/remove "basic_monger_cache_entries")
(let [db (mg/get-db "altcache")]
(mc/remove db "db_aware_monger_cache_entries" {}))
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(use-fixtures :each (fn [f]
(mc/remove db "basic_monger_cache_entries")
(f)
(mc/remove "basic_monger_cache_entries")
(let [db (mg/get-db "altcache")]
(mc/remove db "db_aware_monger_cache_entries" {}))))
(mc/remove db "basic_monger_cache_entries")))
(deftest ^{:cache true}
(deftest ^{:cache true}
test-has?-with-basic-monger-cache
(testing "that has? returns false for misses"
(let [coll "basic_monger_cache_entries"
c (basic-monger-cache-factory coll)]
c (basic-monger-cache-factory db coll)]
(is (not (has? c (str (UUID/randomUUID)))))
(is (not (has? c (str (UUID/randomUUID)))))))
(testing "that has? returns true for hits"
(let [coll "basic_monger_cache_entries"
c (basic-monger-cache-factory coll {"a" 1 "b" "cache" "c" 3/4})]
c (basic-monger-cache-factory db coll {"a" 1 "b" "cache" "c" 3/4})]
(is (has? c "a"))
(is (has? c "b"))
(is (has? c "c"))
(is (not (has? c "d"))))))
(deftest ^{:cache true}
test-lookup-with-basic-moger-cache
(deftest ^{:cache true}
test-lookup-with-basic-monger-cache
(testing "that lookup returns nil for misses"
(let [coll "basic_monger_cache_entries"
c (basic-monger-cache-factory coll)]
c (basic-monger-cache-factory db coll)]
(are [v] (is (nil? (lookup c v)))
:missing-key
"missing-key"
@ -123,47 +118,9 @@
(testing "that lookup returns cached values for hits"
(let [l (Long/valueOf 10000)
coll "basic_monger_cache_entries"
c (basic-monger-cache-factory coll {:skey "Value" :lkey l "kkey" :keyword})]
c (basic-monger-cache-factory db coll {:skey "Value" :lkey l "kkey" :keyword})]
(are [v k] (is (= v (lookup c k)))
"Value" :skey
l :lkey
"keyword" "kkey"))))
"keyword" "kkey")))))
(deftest ^{:cache true}
test-has?-with-db-aware-monger-cache
(testing "that has? returns false for misses"
(let [db (mg/get-db "altcache")
coll "db_aware_monger_cache_entries"
c (db-aware-monger-cache-factory db coll)]
(is (not (has? c (str (UUID/randomUUID)))))
(is (not (has? c (str (UUID/randomUUID)))))))
(testing "that has? returns true for hits"
(let [db (mg/get-db "altcache")
coll "db_aware_monger_cache_entries"
c (db-aware-monger-cache-factory db coll {"a" 1 "b" "cache" "c" 3/4})]
(is (has? c "a"))
(is (has? c "b"))
(is (has? c "c"))
(is (not (has? c "d"))))))
(deftest ^{:cache true}
test-lookup-with-db-aware-moger-cache
(testing "that lookup returns nil for misses"
(let [db (mg/get-db "altcache")
coll "db_aware_monger_cache_entries"
c (db-aware-monger-cache-factory db coll)]
(are [v] (is (nil? (lookup c v)))
:missing-key
"missing-key"
(gensym "missing-key"))))
(testing "that lookup returns cached values for hits"
(let [l (Long/valueOf 10000)
db (mg/get-db "altcache")
coll "db_aware_monger_cache_entries"
c (db-aware-monger-cache-factory db coll {:skey "Value" :lkey l "kkey" :keyword})]
(are [v k] (is (= v (lookup c k)))
"Value" :skey
l :lkey
"keyword" "kkey"))))

View file

@ -1,33 +1,25 @@
(ns monger.test.capped-collections-test
(:require [monger core util]
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.result :as mres]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
(helper/connect!)
[monger.operators :refer :all]))
(defn- megabytes
[^long n]
(* n 1024 1024))
;;
;; Tests
;;
(deftest test-inserting-into-capped-collection
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(deftest test-inserting-into-capped-collection
(let [n 1000
cname "cached"
_ (mc/drop cname)
coll (mc/create cname {:capped true :size (-> 16 megabytes) :max n})]
_ (mc/drop db cname)
coll (mc/create db cname {:capped true :size (-> 16 megabytes) :max n})]
(is (= cname (.getName coll)))
(mc/insert-batch cname (for [i (range 0 (+ n 100))] {:i i}))
(is (= n (mc/count cname)))
(mc/insert-batch db cname (for [i (range 0 (+ n 100))] {:i i}))
(is (= n (mc/count db cname)))
;; older elements get replaced by newer ones
(is (not (mc/any? cname {:i 1})))
(is (not (mc/any? cname {:i 5})))
(is (not (mc/any? cname {:i 9})))
(is (mc/any? cname {:i (+ n 80)}))))
(is (not (mc/any? db cname {:i 1})))
(is (not (mc/any? db cname {:i 5})))
(is (not (mc/any? db cname {:i 9})))
(is (mc/any? db cname {:i (+ n 80)})))))

View file

@ -1,125 +1,131 @@
(ns monger.test.collection-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType]
org.bson.types.ObjectId
(:import org.bson.types.ObjectId
java.util.Date)
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.result :as mgres]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
[monger.operators :refer :all]))
(helper/connect!)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(use-fixtures :each purge-people purge-docs purge-things purge-libraries)
(defn purge-collections
[f]
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "libraries")
(f)
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "libraries"))
(use-fixtures :each purge-collections)
;;
;; count, remove
;;
;;
;; count, remove
;;
(deftest get-collection-size
(deftest get-collection-size
(let [collection "things"]
(is (= 0 (mc/count collection)))
(mc/insert-batch collection [{:language "Clojure" :name "langohr"}
(is (= 0 (mc/count db collection)))
(mc/insert-batch db collection [{:language "Clojure" :name "langohr"}
{:language "Clojure" :name "monger"}
{:language "Clojure" :name "incanter"}
{:language "Scala" :name "akka"}])
(is (= 4 (mc/count collection)))
(is (mc/any? collection))
(is (= 3 (mc/count mg/*mongodb-database* collection {:language "Clojure"})))
(is (mc/any? mg/*mongodb-database* collection {:language "Clojure"}))
(is (= 1 (mc/count collection {:language "Scala" })))
(is (mc/any? collection {:language "Scala"}))
(is (= 0 (mc/count mg/*mongodb-database* collection {:language "Python" })))
(is (not (mc/any? mg/*mongodb-database* collection {:language "Python"})))))
(is (= 4 (mc/count db collection)))
(is (mc/any? db collection))
(is (= 3 (mc/count db collection {:language "Clojure"})))
(is (mc/any? db collection {:language "Clojure"}))
(is (= 1 (mc/count db collection {:language "Scala" })))
(is (mc/any? db collection {:language "Scala"}))
(is (= 0 (mc/count db collection {:language "Python" })))
(is (not (mc/any? db collection {:language "Python"})))))
(deftest remove-all-documents-from-collection
(deftest remove-all-documents-from-collection
(let [collection "libraries"]
(mc/insert-batch collection [{:language "Clojure" :name "monger"}
(mc/insert-batch db collection [{:language "Clojure" :name "monger"}
{:language "Clojure" :name "langohr"}
{:language "Clojure" :name "incanter"}
{:language "Scala" :name "akka"}])
(is (= 4 (mc/count collection)))
(mc/remove collection)
(is (= 0 (mc/count collection)))))
(is (= 4 (mc/count db collection)))
(mc/remove db collection)
(is (= 0 (mc/count db collection)))))
(deftest remove-some-documents-from-collection
(deftest remove-some-documents-from-collection
(let [collection "libraries"]
(mc/insert-batch collection [{:language "Clojure" :name "monger"}
(mc/insert-batch db collection [{:language "Clojure" :name "monger"}
{:language "Clojure" :name "langohr"}
{:language "Clojure" :name "incanter"}
{:language "Scala" :name "akka"}])
(is (= 4 (mc/count collection)))
(mc/remove collection {:language "Clojure"})
(is (= 1 (mc/count collection)))))
(is (= 4 (mc/count db collection)))
(mc/remove db collection {:language "Clojure"})
(is (= 1 (mc/count db collection)))))
(deftest remove-a-single-document-from-collection
(deftest remove-a-single-document-from-collection
(let [collection "libraries"
oid (ObjectId.)]
(mc/insert-batch collection [{:language "Clojure" :name "monger" :_id oid}])
(mc/remove-by-id collection oid)
(is (= 0 (mc/count collection)))
(is (nil? (mc/find-by-id collection oid)))))
(mc/insert-batch db collection [{:language "Clojure" :name "monger" :_id oid}])
(mc/remove-by-id db collection oid)
(is (= 0 (mc/count db collection)))
(is (nil? (mc/find-by-id db collection oid)))))
;;
;; exists?, drop, create
;;
;;
;; exists?, drop, create
;;
(deftest checking-for-collection-existence-when-it-does-not-exist
(deftest checking-for-collection-existence-when-it-does-not-exist
(let [collection "widgets"]
(mc/drop collection)
(is (false? (mc/exists? collection)))))
(mc/drop db collection)
(is (false? (mc/exists? db collection)))))
(deftest checking-for-collection-existence-when-it-does-exist
(deftest checking-for-collection-existence-when-it-does-exist
(let [collection "widgets"]
(mc/drop collection)
(mc/insert-batch collection [{:name "widget1"}
(mc/drop db collection)
(mc/insert-batch db collection [{:name "widget1"}
{:name "widget2"}])
(is (mc/exists? collection))
(mc/drop collection)
(is (false? (mc/exists? collection)))
(mc/create "widgets" {:capped true :size 100000 :max 10})
(is (mc/exists? collection))
(mc/rename collection "gadgets")
(is (not (mc/exists? collection)))
(is (mc/exists? "gadgets"))
(mc/drop "gadgets")))
(is (mc/exists? db collection))
(mc/drop db collection)
(is (false? (mc/exists? db collection)))
(mc/create db "widgets" {:capped true :size 100000 :max 10})
(is (mc/exists? db collection))
(mc/rename db collection "gadgets")
(is (not (mc/exists? db collection)))
(is (mc/exists? db "gadgets"))
(mc/drop db "gadgets")))
;;
;; any?, empty?
;;
;;
;; any?, empty?
;;
(deftest test-any-on-empty-collection
(deftest test-any-on-empty-collection
(let [collection "things"]
(is (not (mc/any? collection)))))
(is (not (mc/any? db collection)))))
(deftest test-any-on-non-empty-collection
(deftest test-any-on-non-empty-collection
(let [collection "things"
_ (mc/insert collection {:language "Clojure" :name "langohr"})]
(is (mc/any? "things"))
(is (mc/any? mg/*mongodb-database* "things" {:language "Clojure"}))))
_ (mc/insert db collection {:language "Clojure" :name "langohr"})]
(is (mc/any? db "things" {:language "Clojure"}))))
(deftest test-empty-on-empty-collection
(deftest test-empty-on-empty-collection
(let [collection "things"]
(is (mc/empty? collection))
(is (mc/empty? mg/*mongodb-database* collection))))
(is (mc/empty? db collection))))
(deftest test-empty-on-non-empty-collection
(deftest test-empty-on-non-empty-collection
(let [collection "things"
_ (mc/insert collection {:language "Clojure" :name "langohr"})]
(is (not (mc/empty? "things")))))
_ (mc/insert db collection {:language "Clojure" :name "langohr"})]
(is (not (mc/empty? db "things")))))
;;
;; distinct
;;
;;
;; distinct
;;
(deftest test-distinct-values
(deftest test-distinct-values
(let [collection "widgets"
batch [{:state "CA" :quantity 1 :price 199.00}
{:state "NY" :quantity 2 :price 199.00}
@ -127,16 +133,16 @@
{:state "IL" :quantity 2 :price 11.50 }
{:state "CA" :quantity 2 :price 2.95 }
{:state "IL" :quantity 3 :price 5.50 }]]
(mc/insert-batch collection batch)
(is (= ["CA" "IL" "NY"] (sort (mc/distinct mg/*mongodb-database* collection :state {}))))
(is (= ["CA" "NY"] (sort (mc/distinct collection :state {:price {$gt 100.00}}))))))
(mc/insert-batch db collection batch)
(is (= ["CA" "IL" "NY"] (sort (mc/distinct db collection :state {}))))
(is (= ["CA" "NY"] (sort (mc/distinct db collection :state {:price {$gt 100.00}}))))))
;;
;; miscellenous
;;
;;
;; miscellenous
;;
(deftest test-system-collection-predicate
(deftest test-system-collection-predicate
(are [name] (is (mc/system-collection? name))
"system.indexes"
"system"
@ -148,4 +154,4 @@
"events"
"accounts"
"megacorp_account"
"myapp_development"))
"myapp_development")))

View file

@ -1,36 +1,34 @@
(ns monger.test.command-test
(:require [monger.core :as mg]
[monger.command :as mcom]
[monger.test.helper :as helper]
[monger.collection :as mc]
[clojure.test :refer :all]
[monger.result :refer [ok?]]
[monger.conversion :refer [from-db-object]]))
(helper/connect!)
(deftest ^{:command true} test-reindex-collection
(let [_ (mc/insert "test" {:name "Clojure"})
result (mcom/reindex-collection "test")]
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(deftest ^{:command true} test-reindex-collection
(let [_ (mc/insert db "test" {:name "Clojure"})
result (mcom/reindex-collection db "test")]
(is (ok? result))
(is (get result "indexes"))))
(deftest ^{:command true} test-server-status
(let [status (mcom/server-status)]
(deftest ^{:command true} test-server-status
(let [status (mcom/server-status db)]
(is (ok? status))
(is (not-empty status))
(is (get status "serverUsed"))))
(deftest ^{:command true} test-top
(let [result (mcom/top)]
(deftest ^{:command true} test-top
(let [result (mcom/top conn)]
(is (ok? result))
(is (not-empty result))
(is (get result "serverUsed"))))
(deftest ^{:command true} test-running-is-master-as-an-arbitrary-command
(let [raw (mg/command {:isMaster 1})
(deftest ^{:command true} test-running-is-master-as-an-arbitrary-command
(let [raw (mg/command db {:isMaster 1})
result (from-db-object raw true)]
(is (ok? result))
(is (ok? raw))
(is (:ismaster result))))
(is (:ismaster result)))))

View file

@ -1,30 +1,27 @@
(ns monger.test.core-test
(:require [monger core collection util result]
[monger.test.helper :as helper]
(:require [monger util result]
[monger.core :as mg :refer [server-address mongo-options]]
[monger.collection :as mc]
[clojure.test :refer :all]
[monger.core :refer [server-address mongo-options]])
[clojure.test :refer :all])
(:import [com.mongodb MongoClient DB WriteConcern MongoClientOptions ServerAddress]))
(println (str "Using Clojure version " *clojure-version*))
(helper/connect!)
(deftest connect-to-mongo-with-default-host-and-port
(let [connection (monger.core/connect)]
(let [connection (mg/connect)]
(is (instance? com.mongodb.MongoClient connection))))
(deftest connect-and-disconnect
(monger.core/connect!)
(monger.core/disconnect!)
(monger.core/connect!))
(let [conn (mg/connect)]
(mg/disconnect conn)))
(deftest connect-to-mongo-with-default-host-and-explicit-port
(let [connection (monger.core/connect { :port 27017 })]
(let [connection (mg/connect { :port 27017 })]
(is (instance? com.mongodb.MongoClient connection))))
(deftest connect-to-mongo-with-default-port-and-explicit-host
(let [connection (monger.core/connect { :host "127.0.0.1" })]
(let [connection (mg/connect { :host "127.0.0.1" })]
(is (instance? com.mongodb.MongoClient connection))))
(deftest test-server-address
@ -36,31 +33,32 @@
(deftest use-existing-mongo-connection
(let [^MongoClientOptions opts (mongo-options :threads-allowed-to-block-for-connection-multiplier 300)
connection (MongoClient. "127.0.0.1" opts)]
(monger.core/set-connection! connection)
(is (= monger.core/*mongodb-connection* connection))))
connection (MongoClient. "127.0.0.1" opts)
db (mg/get-db connection "monger-test")]
(mg/disconnect connection)))
(deftest connect-to-mongo-with-extra-options
(let [^MongoClientOptions opts (mongo-options :threads-allowed-to-block-for-connection-multiplier 300)
^ServerAddress sa (server-address "127.0.0.1" 27017)]
(monger.core/connect! sa opts)))
^ServerAddress sa (server-address "127.0.0.1" 27017)
conn (mg/connect sa opts)]
(mg/disconnect conn)))
(deftest get-database
(let [connection (monger.core/connect)
db (monger.core/get-db connection "monger-test")]
(let [connection (mg/connect)
db (mg/get-db connection "monger-test")]
(is (instance? com.mongodb.DB db))))
(deftest test-get-db-names
(let [dbs (monger.core/get-db-names)]
(let [conn (mg/connect)
dbs (mg/get-db-names conn)]
(is (not (empty? dbs)))
(is (dbs "monger-test"))))
(deftest get-last-error
(let [connection (monger.core/connect)
db (monger.core/get-db connection "monger-test")]
(is (monger.result/ok? (monger.core/get-last-error)))
(is (monger.result/ok? (monger.core/get-last-error db)))
(is (monger.result/ok? (monger.core/get-last-error db WriteConcern/NORMAL)))
(is (monger.result/ok? (monger.core/get-last-error db 1 100 true)))))
(let [connection (mg/connect)
db (mg/get-db connection "monger-test")]
(is (monger.result/ok? (mg/get-last-error db)))
(is (monger.result/ok? (mg/get-last-error db WriteConcern/NORMAL)))
(is (monger.result/ok? (mg/get-last-error db 1 100 true)))))

View file

@ -1,19 +1,18 @@
(ns monger.test.cursor-test
(:import [com.mongodb DBCursor DBObject Bytes]
[java.util List Map])
(:require [monger.test.helper :as helper]
(:require [monger.core :as mg]
[clojure.test :refer :all]
[monger.cursor :refer :all]
[monger.test.fixtures :refer :all]))
[monger.cursor :refer :all]))
(helper/connect!)
(deftest make-db-cursor-for-collection
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(deftest make-db-cursor-for-collection
(is (= DBCursor
(class (make-db-cursor :docs)))))
(class (make-db-cursor db :docs)))))
(deftest getting-cursor-options-value
(let [db-cur (make-db-cursor :docs)
(deftest getting-cursor-options-value
(let [db-cur (make-db-cursor db :docs)
opts (get-options db-cur)]
(is (= true (isa? (class opts) Map)))
(is (= 0 (.getOptions db-cur))) ;;test default value
@ -24,8 +23,8 @@
(is (= false (:slaveok opts)))
(is (= false (:tailable opts)))))
(deftest adding-option-to-cursor
(let [db-cur (make-db-cursor :docs)]
(deftest adding-option-to-cursor
(let [db-cur (make-db-cursor db :docs)]
(add-option! db-cur :notimeout)
(is (= (:notimeout cursor-options)
(.getOptions db-cur)))
@ -36,8 +35,8 @@
(:tailable cursor-options)
(:awaitdata cursor-options))))))
(deftest remove-option-from-cursor
(let [db-cur (make-db-cursor :docs)]
(deftest remove-option-from-cursor
(let [db-cur (make-db-cursor db :docs)]
(add-option! db-cur :partial)
(add-option! db-cur :awaitdata)
;; removing not-set option should not affect result
@ -51,16 +50,16 @@
(:partial cursor-options)))))
(deftest test-reset-options
(let [db-cur (make-db-cursor :docs)]
(deftest test-reset-options
(let [db-cur (make-db-cursor db :docs)]
(add-option! db-cur :partial)
(is (= (.getOptions db-cur)
(:partial cursor-options)))
(is (= 0
(int (.getOptions (reset-options db-cur)))))))
(deftest add-options-with-hashmap
(let [db-cur (make-db-cursor :docs)
(deftest add-options-with-hashmap
(let [db-cur (make-db-cursor db :docs)
_ (add-options db-cur {:notimeout true :slaveok true})
opts (get-options db-cur)]
(is (= true (:notimeout opts)))
@ -68,8 +67,8 @@
(is (= false (:tailable opts)))
(is (= false (:oplogreplay opts)))))
(deftest add-options-with-hashmap-and-remove-option
(let [db-cur (make-db-cursor :docs)
(deftest add-options-with-hashmap-and-remove-option
(let [db-cur (make-db-cursor db :docs)
_ (add-options db-cur {:notimeout true :slaveok true})
opts (get-options db-cur)]
(is (= true (:notimeout opts)))
@ -82,8 +81,8 @@
(is (= false (:slaveok opts)))
(is (= false (:tailable opts))))))
(deftest add-options-with-list
(let [db-cur (make-db-cursor :docs)
(deftest add-options-with-list
(let [db-cur (make-db-cursor db :docs)
_ (add-options db-cur [:notimeout :slaveok])
opts (get-options db-cur)]
(is (= true (:notimeout opts)))
@ -91,8 +90,8 @@
(is (= false (:tailable opts)))
(is (= false (:oplogreplay opts)))))
(deftest add-options-with-Bytes
(let [db-cur (make-db-cursor :docs)
(deftest add-options-with-Bytes
(let [db-cur (make-db-cursor db :docs)
_ (add-options db-cur Bytes/QUERYOPTION_NOTIMEOUT)
opts (get-options db-cur)]
(is (= true (:notimeout opts)))
@ -100,11 +99,11 @@
(is (= false (:tailable opts)))
(is (= false (:oplogreplay opts)))))
(deftest add-options-with-one-keyword
(let [db-cur (make-db-cursor :docs)
(deftest add-options-with-one-keyword
(let [db-cur (make-db-cursor db :docs)
_ (add-options db-cur :notimeout)
opts (get-options db-cur)]
(is (= true (:notimeout opts)))
(is (= false (:slaveok opts)))
(is (= false (:tailable opts)))
(is (= false (:oplogreplay opts)))))
(is (= false (:oplogreplay opts))))))

View file

@ -1,44 +1,31 @@
(ns monger.test.db-test
(:require [monger core db]
[monger.test.helper :as helper]
(:require [monger.db :as mdb]
[monger.core :as mg]
[monger.collection :as mc]
[clojure.test :refer :all])
(:import [com.mongodb Mongo DB]
java.util.Set))
(helper/connect!)
;; do not run this test for CI, it complicates matters by messing up
;; authentication for some other tests :( MK.
(when-not (System/getenv "CI")
(let [conn (mg/connect)]
(when-not (System/getenv "CI")
(deftest test-drop-database
;; drop a secondary database here. MK.
(monger.core/with-db (monger.core/get-db "monger-test3")
(let [collection "test"
_ (mc/insert collection {:name "Clojure"})
check (mc/count collection)
_ (monger.db/drop-db)]
(let [db (mg/get-db conn "monger-test3")
collection "test"
_ (mc/insert db collection {:name "Clojure"})
check (mc/count db collection)
_ (mdb/drop-db db)]
(is (= 1 check))
(is (not (mc/exists? collection)))
(is (= 0 (mc/count collection))))))
(is (not (mc/exists? db collection)))
(is (= 0 (mc/count db collection))))))
(deftest test-use-database
(monger.core/use-db! "monger-test5")
(is (= "monger-test5" (.getName (monger.core/current-db))))
(let [collection "test"
_ (mc/insert collection {:name "Clojure"})
check (mc/count collection)
_ (monger.db/drop-db)]
(is (= 1 check))
(is (not (mc/exists? collection)))
(is (= 0 (mc/count collection))))))
(deftest test-get-collection-names
(mc/insert "test-1" {:name "Clojure"})
(mc/insert "test-2" {:name "Clojure"})
(let [^Set collections (monger.db/get-collection-names)]
(is (.contains collections "test-1"))
(is (.contains collections "test-2"))))
(deftest test-get-collection-names
(let [db (mg/get-db conn "monger-test")]
(mc/insert db "test-1" {:name "Clojure"})
(mc/insert db "test-2" {:name "Clojure"})
(let [^Set xs (mdb/get-collection-names db)]
(is (.contains xs "test-1"))
(is (.contains xs "test-2"))))))

View file

@ -1,21 +0,0 @@
(ns monger.test.fixtures
(:require [monger.testkit :refer [defcleaner]]))
;;
;; fixture functions
;;
(defcleaner people "people")
(defcleaner docs "docs")
(defcleaner finder-docs "regular_finders_docs")
(defcleaner querying-docs "querying_docs")
(defcleaner things "things")
(defcleaner libraries "libraries")
(defcleaner scores "scores")
(defcleaner locations "locations")
(defcleaner domains "domains")
(defcleaner pages "pages")
(defcleaner cached "cached")
(defcleaner migrations "meta.migrations")

View file

@ -3,33 +3,38 @@
[monger.collection :as mc]
[monger.search :as ms]
[monger.command :as cmd]
[monger.test.helper :as helper]
[clojure.test :refer [deftest is use-fixtures]]
[monger.test.fixtures :refer :all]
[monger.result :refer [ok?]])
(:import com.mongodb.BasicDBObjectBuilder))
(helper/connect!)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")
coll "search-docs"]
(defn enable-search
(defn enable-search
[f]
;; {:textSearchEnabled true :setParameter 1}
(let [bldr (doto (BasicDBObjectBuilder.)
(.append "setParameter" 1)
(.append "textSearchEnabled" true))
cmd (.get bldr)]
(is (ok? (cmd/raw-admin-command cmd))))
(is (ok? (cmd/raw-admin-command conn cmd))))
(f))
(use-fixtures :each purge-docs)
(use-fixtures :once enable-search)
(defn purge-collections
[f]
(mc/purge-many db [coll])
(f)
(mc/purge-many db [coll]))
(deftest ^{:search true} test-basic-full-text-search-query
(let [coll "docs"]
(mc/ensure-index coll (array-map :subject "text" :content "text"))
(mc/insert coll {:subject "hello there" :content "this should be searchable"})
(mc/insert coll {:subject "untitled" :content "this is just noize"})
(let [res (ms/search coll "hello")
(use-fixtures :each purge-collections)
(use-fixtures :once enable-search)
(deftest ^{:search true} test-basic-full-text-search-query
(mc/ensure-index db coll (array-map :subject "text" :content "text"))
(mc/insert db coll {:subject "hello there" :content "this should be searchable"})
(mc/insert db coll {:subject "untitled" :content "this is just noize"})
(let [res (ms/search db coll "hello")
xs (ms/results-from res)]
(is (= "hello there" (-> xs first :obj :subject)))
(is (= 1.0 (-> xs first :score))))))

View file

@ -1,107 +1,104 @@
(ns monger.test.gridfs-test
(:refer-clojure :exclude [count remove find])
(:require [monger.gridfs :as gridfs]
[monger.test.helper :as helper]
[clojure.java.io :as io]
[clojure.test :refer :all]
[monger.core :refer [count]]
[monger.test.fixtures :refer :all]
[monger.core :as mg :refer [count]]
[monger.operators :refer :all]
[monger.conversion :refer :all]
[monger.gridfs :refer [store make-input-file store-file filename content-type metadata]])
(:import [java.io InputStream File FileInputStream]
[com.mongodb.gridfs GridFS GridFSInputFile GridFSDBFile]))
(defn purge-gridfs*
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")
fs (mg/get-gridfs conn "monger-test")]
(defn purge-gridfs*
[]
(gridfs/remove-all))
(gridfs/remove-all fs))
(defn purge-gridfs
(defn purge-gridfs
[f]
(gridfs/remove-all)
(gridfs/remove-all fs)
(f)
(gridfs/remove-all))
(gridfs/remove-all fs))
(use-fixtures :each purge-gridfs)
(use-fixtures :each purge-gridfs)
(helper/connect!)
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-relative-fs-paths
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-relative-fs-paths
(let [input "./test/resources/mongo/js/mapfun1.js"]
(is (= 0 (count (gridfs/all-files))))
(store (make-input-file input)
(is (= 0 (count (gridfs/all-files fs))))
(store (make-input-file fs input)
(.setFilename "monger.test.gridfs.file1")
(.setContentType "application/octet-stream"))
(is (= 1 (count (gridfs/all-files))))))
(is (= 1 (count (gridfs/all-files fs))))))
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-file-instances
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-file-instances
(let [input (io/as-file "./test/resources/mongo/js/mapfun1.js")]
(is (= 0 (count (gridfs/all-files))))
(store-file (make-input-file input)
(is (= 0 (count (gridfs/all-files fs))))
(store-file (make-input-file fs input)
(filename "monger.test.gridfs.file2")
(content-type "application/octet-stream"))
(is (= 1 (count (gridfs/all-files))))))
(is (= 1 (count (gridfs/all-files fs))))))
(deftest ^{:gridfs true} test-storing-bytes-to-gridfs
(deftest ^{:gridfs true} test-storing-bytes-to-gridfs
(let [input (.getBytes "A string")
md {:format "raw" :source "AwesomeCamera D95"}
fname "monger.test.gridfs.file3"
ct "application/octet-stream"]
(is (= 0 (count (gridfs/all-files))))
(store-file (make-input-file input)
(is (= 0 (count (gridfs/all-files fs))))
(store-file (make-input-file fs input)
(filename fname)
(metadata md)
(content-type "application/octet-stream"))
(let [f (first (gridfs/files-as-maps))]
(let [f (first (gridfs/files-as-maps fs))]
(is (= ct (:contentType f)))
(is (= fname (:filename f)))
(is (= md (:metadata f))))
(is (= 1 (count (gridfs/all-files))))))
(is (= 1 (count (gridfs/all-files fs))))))
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-absolute-fs-paths
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-absolute-fs-paths
(let [tmp-file (File/createTempFile "monger.test.gridfs" "test-storing-files-to-gridfs-using-absolute-fs-paths")
_ (spit tmp-file "Some content")
input (.getAbsolutePath tmp-file)]
(is (= 0 (count (gridfs/all-files))))
(store-file (make-input-file input)
(is (= 0 (count (gridfs/all-files fs))))
(store-file (make-input-file fs input)
(filename "monger.test.gridfs.file4")
(content-type "application/octet-stream"))
(is (= 1 (count (gridfs/all-files))))))
(is (= 1 (count (gridfs/all-files fs))))))
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-input-stream
(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-input-stream
(let [tmp-file (File/createTempFile "monger.test.gridfs" "test-storing-files-to-gridfs-using-input-stream")
_ (spit tmp-file "Some other content")]
(is (= 0 (count (gridfs/all-files))))
(store-file (make-input-file (FileInputStream. tmp-file))
(is (= 0 (count (gridfs/all-files fs))))
(store-file fs
(make-input-file (FileInputStream. tmp-file))
(filename "monger.test.gridfs.file4b")
(content-type "application/octet-stream"))
(is (= 1 (count (gridfs/all-files))))))
(is (= 1 (count (gridfs/all-files fs))))))
(deftest ^{:gridfs true} test-finding-individual-files-on-gridfs
(deftest ^{:gridfs true} test-finding-individual-files-on-gridfs
(testing "gridfs/find-one"
(purge-gridfs*)
(let [input "./test/resources/mongo/js/mapfun1.js"
ct "binary/octet-stream"
fname "monger.test.gridfs.file5"
md5 "14a09deabb50925a3381315149017bbd"
stored (store-file (make-input-file input)
stored (store-file (make-input-file fs input)
(filename fname)
(content-type ct))]
(is (= 1 (count (gridfs/all-files))))
(is (= 1 (count (gridfs/all-files fs))))
(is (:_id stored))
(is (:uploadDate stored))
(is (= 62 (:length stored)))
(is (= md5 (:md5 stored)))
(is (= fname (:filename stored)))
(is (= ct (:contentType stored)))
(are [a b] (is (= a (:md5 (from-db-object (gridfs/find-one b) true))))
md5 (:_id stored)
md5 fname
(are [a b] (is (= a (:md5 (from-db-object (gridfs/find-one fs b) true))))
md5 {:_id (:_id stored)}
md5 (to-db-object {:md5 md5}))))
(testing "gridfs/find-one-as-map"
(purge-gridfs*)
@ -109,39 +106,38 @@
ct "binary/octet-stream"
fname "monger.test.gridfs.file6"
md5 "14a09deabb50925a3381315149017bbd"
stored (store-file (make-input-file input)
stored (store-file (make-input-file fs input)
(filename fname)
(metadata (to-db-object {:meta "data"}))
(content-type ct))]
(is (= 1 (count (gridfs/all-files))))
(is (= 1 (count (gridfs/all-files fs))))
(is (:_id stored))
(is (:uploadDate stored))
(is (= 62 (:length stored)))
(is (= md5 (:md5 stored)))
(is (= fname (:filename stored)))
(is (= ct (:contentType stored)))
(let [m (gridfs/find-one-as-map {:filename fname})]
(let [m (gridfs/find-one-as-map fs {:filename fname})]
(is (= {:meta "data"} (:metadata m))))
(are [a query] (is (= a (:md5 (gridfs/find-one-as-map query))))
md5 (:_id stored)
md5 fname
(are [a query] (is (= a (:md5 (gridfs/find-one-as-map fs query))))
md5 {:_id (:_id stored)}
md5 {:md5 md5}))))
(deftest ^{:gridfs true} test-finding-multiple-files-on-gridfs
(deftest ^{:gridfs true} test-finding-multiple-files-on-gridfs
(let [input "./test/resources/mongo/js/mapfun1.js"
ct "binary/octet-stream"
md5 "14a09deabb50925a3381315149017bbd"
stored1 (store-file (make-input-file input)
stored1 (store-file (make-input-file fs input)
(filename "monger.test.gridfs.file6")
(content-type ct))
stored2 (store-file (make-input-file input)
stored2 (store-file (make-input-file fs input)
(filename "monger.test.gridfs.file7")
(content-type ct))
list1 (gridfs/find "monger.test.gridfs.file6")
list2 (gridfs/find "monger.test.gridfs.file7")
list3 (gridfs/find "888000___.monger.test.gridfs.file")
list4 (gridfs/find { :md5 md5 })]
(is (= 2 (count (gridfs/all-files))))
list1 (gridfs/find-by-filename fs "monger.test.gridfs.file6")
list2 (gridfs/find-by-filename fs "monger.test.gridfs.file7")
list3 (gridfs/find-by-filename fs "888000___.monger.test.gridfs.file")
list4 (gridfs/find-by-md5 fs md5)]
(is (= 2 (count (gridfs/all-files fs))))
(are [a b] (is (= (map #(.get ^GridFSDBFile % "_id") a)
(map :_id b)))
list1 [stored1]
@ -150,18 +146,18 @@
list4 [stored1 stored2])))
(deftest ^{:gridfs true} test-removing-multiple-files-from-gridfs
(deftest ^{:gridfs true} test-removing-multiple-files-from-gridfs
(let [input "./test/resources/mongo/js/mapfun1.js"
ct "binary/octet-stream"
md5 "14a09deabb50925a3381315149017bbd"
stored1 (store-file (make-input-file input)
stored1 (store-file (make-input-file fs input)
(filename "monger.test.gridfs.file8")
(content-type ct))
stored2 (store-file (make-input-file input)
stored2 (store-file (make-input-file fs input)
(filename "monger.test.gridfs.file9")
(content-type ct))]
(is (= 2 (count (gridfs/all-files))))
(gridfs/remove { :filename "monger.test.gridfs.file8" })
(is (= 1 (count (gridfs/all-files))))
(gridfs/remove { :md5 md5 })
(is (= 0 (count (gridfs/all-files))))))
(is (= 2 (count (gridfs/all-files fs))))
(gridfs/remove fs { :filename "monger.test.gridfs.file8" })
(is (= 1 (count (gridfs/all-files fs))))
(gridfs/remove fs { :md5 md5 })
(is (= 0 (count (gridfs/all-files fs)))))))

View file

@ -1,17 +0,0 @@
(ns monger.test.helper
(:require [monger core util])
(:import [com.mongodb WriteConcern]))
(def connected (atom false))
(defn connected?
[]
@connected)
(defn connect!
[]
(when-not (connected?)
(do
(monger.core/connect!)
(monger.core/set-db! (monger.core/get-db "monger-test"))
(monger.core/set-default-write-concern! WriteConcern/SAFE)
(reset! connected true))))

View file

@ -1,53 +1,46 @@
(ns monger.test.indexing-test
(:import org.bson.types.ObjectId
java.util.Date)
(:require [monger core util]
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.test.helper :as helper]
monger.joda-time
[clojure.test :refer :all]
[monger.test.fixtures :refer :all]
[clj-time.core :refer [now secs ago from-now]]))
[clj-time.core :refer [now seconds ago from-now]]))
(helper/connect!)
;;
;; indexes
;;
(deftest ^{:indexing true} test-creating-and-dropping-indexes
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(deftest ^{:indexing true} test-creating-and-dropping-indexes
(let [collection "libraries"]
(mc/drop-indexes collection)
(mc/create-index collection { "language" 1 })
(mc/drop-indexes db collection)
(mc/create-index db collection { "language" 1 })
(is (= "language_1"
(:name (second (mc/indexes-on collection)))))
(mc/drop-index collection "language_1")
(mc/create-index collection ["language"])
(mc/drop-index collection "language_1")
(is (nil? (second (mc/indexes-on collection))))
(mc/ensure-index collection (array-map "language" 1) {:unique true})
(:name (second (mc/indexes-on db collection)))))
(mc/drop-index db collection "language_1")
(mc/create-index db collection ["language"])
(mc/drop-index db collection "language_1")
(is (nil? (second (mc/indexes-on db collection))))
(mc/ensure-index db collection (array-map "language" 1) {:unique true})
(is (= "language_1"
(:name (second (mc/indexes-on collection)))))
(mc/ensure-index collection (array-map "language" 1))
(mc/ensure-index collection (array-map "language" 1) { :unique true })
(mc/drop-indexes collection)))
(:name (second (mc/indexes-on db collection)))))
(mc/ensure-index db collection (array-map "language" 1))
(mc/ensure-index db collection (array-map "language" 1) { :unique true })
(mc/drop-indexes db collection)))
(deftest ^{:indexing true :edge-features true :time-consuming true} test-ttl-collections
(deftest ^{:indexing true :time-consuming true} test-ttl-collections
(let [coll "recent_events"
ttl 30
sleep 120]
(mc/remove coll)
(mc/ensure-index coll (array-map :created-at 1) {:expireAfterSeconds ttl})
(mc/remove db coll)
(mc/ensure-index db coll (array-map :created-at 1) {:expireAfterSeconds ttl})
(dotimes [i 100]
(mc/insert coll {:type "signup" :created-at (-> i secs ago) :i i}))
(mc/insert db coll {:type "signup" :created-at (-> i seconds ago) :i i}))
(dotimes [i 100]
(mc/insert coll {:type "signup" :created-at (-> i secs from-now) :i i}))
(is (= 200 (mc/count coll {:type "signup"})))
(mc/insert db coll {:type "signup" :created-at (-> i seconds from-now) :i i}))
(is (= 200 (mc/count db coll {:type "signup"})))
;; sleep for 65 seconds. MongoDB 2.1.2 seems to run TTLMonitor once per minute, according to
;; the log. MK.
(println (format "Now sleeping for %d seconds to test TTL collections!" sleep))
(Thread/sleep (* sleep 1000))
(println (format "Documents in the TTL collection: %d" (mc/count coll {:type "signup"})))
(is (< (mc/count coll {:type "signup"}) 100))
(mc/remove coll)))
(println (format "Documents in the TTL collection: %d" (mc/count db coll {:type "signup"})))
(is (< (mc/count db coll {:type "signup"}) 100))
(mc/remove db coll))))

View file

@ -5,120 +5,129 @@
(:require [monger.core :as mg]
[monger.util :as mu]
[monger.collection :as mc]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.conversion :refer :all]
[monger.test.fixtures :refer :all]))
(helper/connect!)
(use-fixtures :each purge-people purge-docs purge-things purge-libraries)
;;
;; insert
;;
(deftest insert-a-basic-document-without-id-and-with-default-write-concern
(let [collection "people"
doc {:name "Joe" :age 30}]
(is (monger.result/ok? (mc/insert "people" doc)))
(is (= 1 (mc/count collection)))))
(deftest insert-a-basic-document-with-explicitly-passed-database-without-id-and-with-default-write-concern
(let [collection "people"
doc {:name "Joe" :age 30}]
(dotimes [n 5]
(is (monger.result/ok? (mc/insert monger.core/*mongodb-database* "people" doc WriteConcern/SAFE))))
(is (= 5 (mc/count collection)))))
(deftest insert-a-basic-document-without-id-and-with-explicit-write-concern
(let [collection "people"
doc {:name "Joe" :age 30}]
(is (monger.result/ok? (mc/insert "people" doc WriteConcern/SAFE)))
(is (= 1 (mc/count collection)))))
(deftest insert-a-basic-db-object-without-id-and-with-default-write-concern
(let [collection "people"
doc (to-db-object {:name "Joe" :age 30})]
(is (nil? (.get ^DBObject doc "_id")))
(mc/insert "people" doc)
(is (not (nil? (monger.util/get-id doc))))))
(deftest insert-a-map-with-id-and-with-default-write-concern
(let [collection "people"
id (ObjectId.)
doc {:name "Joe" :age 30 "_id" id}
result (mc/insert "people" doc)]
(is (= id (monger.util/get-id doc)))))
(deftest insert-a-document-with-clojure-ratio-in-it
(let [collection "widgets"
id (ObjectId.)
doc {:ratio 11/2 "_id" id}
result (mc/insert "widgets" doc)]
(is (= 5.5 (:ratio (mc/find-map-by-id collection id))))))
(deftest insert-a-document-with-clojure-keyword-in-it
(let [collection "widgets"
id (ObjectId.)
doc {:keyword :kwd "_id" id}
result (mc/insert "widgets" doc)]
(is (= (name :kwd) (:keyword (mc/find-map-by-id collection id))))))
(deftest insert-a-document-with-clojure-keyword-in-a-set-in-it
(let [collection "widgets"
id (ObjectId.)
doc {:keyword1 {:keyword2 #{:kw1 :kw2}} "_id" id}
result (mc/insert "widgets" doc)]
(is (= (sort ["kw1" "kw2"])
(sort (get-in (mc/find-map-by-id collection id) [:keyword1 :keyword2]))))))
[monger.conversion :refer :all]))
(defrecord Metrics
[rps eps])
(deftest insert-a-document-with-clojure-record-in-it
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(defn purge-collections
[f]
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "widgets")
(f)
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "widgets"))
(use-fixtures :each purge-collections)
;;
;; insert
;;
(deftest insert-a-basic-document-without-id-and-with-default-write-concern
(let [collection "people"
doc {:name "Joe" :age 30}]
(is (monger.result/ok? (mc/insert db collection doc)))
(is (= 1 (mc/count db collection)))))
(deftest insert-a-basic-document-with-explicitly-passed-database-without-id-and-with-default-write-concern
(let [collection "people"
doc {:name "Joe" :age 30}]
(dotimes [n 5]
(is (monger.result/ok? (mc/insert db collection doc WriteConcern/SAFE))))
(is (= 5 (mc/count db collection)))))
(deftest insert-a-basic-document-without-id-and-with-explicit-write-concern
(let [collection "people"
doc {:name "Joe" :age 30}]
(is (monger.result/ok? (mc/insert db collection doc WriteConcern/SAFE)))
(is (= 1 (mc/count db collection)))))
(deftest insert-a-basic-db-object-without-id-and-with-default-write-concern
(let [collection "people"
doc (to-db-object {:name "Joe" :age 30})]
(is (nil? (.get ^DBObject doc "_id")))
(mc/insert db collection doc)
(is (not (nil? (monger.util/get-id doc))))))
(deftest insert-a-map-with-id-and-with-default-write-concern
(let [collection "people"
id (ObjectId.)
doc {:name "Joe" :age 30 "_id" id}
result (mc/insert db collection doc)]
(is (= id (monger.util/get-id doc)))))
(deftest insert-a-document-with-clojure-ratio-in-it
(let [collection "widgets"
id (ObjectId.)
doc {:ratio 11/2 "_id" id}
result (mc/insert db collection doc)]
(is (= 5.5 (:ratio (mc/find-map-by-id db collection id))))))
(deftest insert-a-document-with-clojure-keyword-in-it
(let [collection "widgets"
id (ObjectId.)
doc {:keyword :kwd "_id" id}
result (mc/insert db collection doc)]
(is (= (name :kwd) (:keyword (mc/find-map-by-id db collection id))))))
(deftest insert-a-document-with-clojure-keyword-in-a-set-in-it
(let [collection "widgets"
id (ObjectId.)
doc {:keyword1 {:keyword2 #{:kw1 :kw2}} "_id" id}
result (mc/insert db collection doc)]
(is (= (sort ["kw1" "kw2"])
(sort (get-in (mc/find-map-by-id db collection id) [:keyword1 :keyword2]))))))
(deftest insert-a-document-with-clojure-record-in-it
(let [collection "widgets"
id (ObjectId.)
doc {:record (Metrics. 10 20) "_id" id}
result (mc/insert "widgets" doc)]
(is (= {:rps 10 :eps 20} (:record (mc/find-map-by-id collection id))))))
result (mc/insert db collection doc)]
(is (= {:rps 10 :eps 20} (:record (mc/find-map-by-id db collection id))))))
(deftest test-insert-a-document-with-dbref
(mc/remove "widgets")
(mc/remove "owners")
(deftest test-insert-a-document-with-dbref
(mc/remove db "widgets")
(mc/remove db "owners")
(let [coll1 "widgets"
coll2 "owners"
oid (ObjectId.)
joe (mc/insert "owners" {:name "Joe" :_id oid})
dbref (DBRef. (mg/current-db) coll2 oid)]
(mc/insert coll1 {:type "pentagon" :owner dbref})
(let [fetched (mc/find-one-as-map coll1 {:type "pentagon"})
joe (mc/insert db coll2 {:name "Joe" :_id oid})
dbref (DBRef. db coll2 oid)]
(mc/insert db coll1 {:type "pentagon" :owner dbref})
(let [fetched (mc/find-one-as-map db coll1 {:type "pentagon"})
fo (:owner fetched)]
(is (= {:_id oid :name "Joe"} (from-db-object @fo true))))))
;;
;; insert-and-return
;;
;;
;; insert-and-return
;;
(deftest insert-and-return-a-basic-document-without-id-and-with-default-write-concern
(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)]
result (mc/insert-and-return db collection doc)]
(is (= (:name doc)
(:name result)))
(is (= (:age doc)
(:age result)))
(is (:_id result))
(is (= 1 (mc/count collection)))))
(is (= 1 (mc/count db collection)))))
(deftest insert-and-return-a-basic-document-without-id-but-with-a-write-concern
(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)]
result (mc/insert-and-return db collection doc WriteConcern/FSYNC_SAFE)]
(is (= (:name doc)
(:name result)))
(is (= (:age doc)
@ -126,44 +135,44 @@
(is (= (:ratio doc)
(:ratio result)))
(is (:_id result))
(is (= 1 (mc/count collection)))))
(is (= 1 (mc/count db collection)))))
(deftest insert-and-return-with-a-provided-id
(deftest insert-and-return-with-a-provided-id
(let [collection "people"
oid (ObjectId.)
doc {:name "Joe" :age 30 :_id oid}
result (mc/insert-and-return :people doc)]
result (mc/insert-and-return db collection doc)]
(is (= (:_id result) (:_id doc) oid))
(is (= 1 (mc/count collection)))))
(is (= 1 (mc/count db collection)))))
;;
;; insert-batch
;;
;;
;; insert-batch
;;
(deftest insert-a-batch-of-basic-documents-without-ids-and-with-default-write-concern
(deftest insert-a-batch-of-basic-documents-without-ids-and-with-default-write-concern
(let [collection "people"
docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]]
(is (monger.result/ok? (mc/insert-batch "people" docs)))
(is (= 2 (mc/count collection)))))
(is (monger.result/ok? (mc/insert-batch db collection docs)))
(is (= 2 (mc/count db collection)))))
(deftest insert-a-batch-of-basic-documents-without-ids-and-with-explicit-write-concern
(deftest insert-a-batch-of-basic-documents-without-ids-and-with-explicit-write-concern
(let [collection "people"
docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]]
(is (monger.result/ok? (mc/insert-batch "people" docs WriteConcern/NORMAL)))
(is (= 2 (mc/count collection)))))
(is (monger.result/ok? (mc/insert-batch db collection docs WriteConcern/NORMAL)))
(is (= 2 (mc/count db collection)))))
(deftest insert-a-batch-of-basic-documents-with-explicit-database-without-ids-and-with-explicit-write-concern
(deftest insert-a-batch-of-basic-documents-with-explicit-database-without-ids-and-with-explicit-write-concern
(let [collection "people"
docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]]
(dotimes [n 44]
(is (monger.result/ok? (mc/insert-batch monger.core/*mongodb-database* "people" docs WriteConcern/NORMAL))))
(is (= 88 (mc/count collection)))))
(is (monger.result/ok? (mc/insert-batch db collection docs WriteConcern/NORMAL))))
(is (= 88 (mc/count db collection)))))
(deftest insert-a-batch-of-basic-documents-from-a-lazy-sequence
(deftest insert-a-batch-of-basic-documents-from-a-lazy-sequence
(let [collection "people"
numbers (range 0 1000)]
(is (monger.result/ok? (mc/insert-batch "people" (map (fn [^long l]
(is (monger.result/ok? (mc/insert-batch db collection (map (fn [^long l]
{:n l})
numbers))))
(is (= (count numbers) (mc/count collection)))))
(is (= (count numbers) (mc/count db collection))))))

View file

@ -1,45 +0,0 @@
(ns monger.test.internal.fn-test
(:require [clojure.test :refer :all]
[monger.internal.fn :refer :all]))
(deftest test-expand-all
(are [i o] (is (= (expand-all i) o))
{ :int (fn [] 1) :str "Clojure" :float (Float/valueOf 11.0) } { :int 1 :str "Clojure" :float (Float/valueOf 11.0 )}
{ :long (fn [] (Long/valueOf 11)) } { :long (Long/valueOf 11) }
{
:i 1
:l (Long/valueOf 1111)
:s "Clojure"
:d (Double/valueOf 11.1)
:f (Float/valueOf 2.5)
:v [1 2 3]
:dyn-v [(fn [] 10) (fn [] 20) (fn [] 30)]
:dyn-i (fn [] 1)
:dyn-s (fn [] "Clojure (expanded)")
:m { :nested "String" }
:dyn-m { :abc (fn [] :abc) :nested { :a { :b { :c (fn [] "d") } } } }
}
{
:i 1
:l (Long/valueOf 1111)
:s "Clojure"
:d (Double/valueOf 11.1)
:f (Float/valueOf 2.5)
:v [1 2 3]
:dyn-v [10 20 30]
:dyn-i 1
:dyn-s "Clojure (expanded)"
:m { :nested "String" }
:dyn-m {
:abc :abc
:nested { :a { :b { :c "d" } } }
}
}))
(deftest test-expand-all-with
(let [expander-fn (fn [f]
(* 3 (f)))]
(are [i o] (is (= (expand-all-with i expander-fn) o))
{ :a 1 :int (fn [] 3) } { :a 1 :int 9 }
{ :v [(fn [] 1) (fn [] 11)] :m { :inner (fn [] 3) } :s "Clojure" } { :v [3 33] :m { :inner 9 } :s "Clojure" })))

View file

@ -1,10 +1,7 @@
(ns monger.test.js-test
(:require monger.js
[monger.test.helper :as helper]
[clojure.test :refer :all]))
(helper/connect!)
(deftest load-js-resource-using-path-on-the-classpath
(are [c path] (= c (count (monger.js/load-resource path)))
62 "resources/mongo/js/mapfun1.js"

View file

@ -2,26 +2,22 @@
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType]
org.bson.types.ObjectId
java.util.Date)
(:require [monger core util]
[monger.collection :as mc]
(:require [monger.collection :as mc]
[monger.core :as mg]
[monger.result :as mgres]
[clojurewerkz.support.js :as js]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.conversion :refer :all]
[monger.test.fixtures :refer :all]))
[monger.conversion :refer :all]))
(helper/connect!)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(use-fixtures :each (fn [f]
(mc/remove db "widgets")
(f)
(mc/remove db "widgets")))
(use-fixtures :each purge-people purge-docs purge-things purge-libraries)
;;
;; Map/Reduce
;;
(let [collection "widgets"
(let [collection "widgets"
mapper (js/load-resource "resources/mongo/js/mapfun1.js")
reducer "function(key, values) {
var result = 0;
@ -37,34 +33,34 @@
{ :state "IL" :quantity 3 :price 5.50 }]
expected [{:_id "CA", :value 204.9} {:_id "IL", :value 39.5} {:_id "NY", :value 697.0}]]
(deftest test-basic-inline-map-reduce-example
(mc/remove monger.core/*mongodb-database* collection {})
(is (mgres/ok? (mc/insert-batch collection batch)))
(let [output (mc/map-reduce collection mapper reducer nil MapReduceCommand$OutputType/INLINE {})
(mc/remove db collection)
(is (mgres/ok? (mc/insert-batch db collection batch)))
(let [output (mc/map-reduce db collection mapper reducer nil MapReduceCommand$OutputType/INLINE {})
results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)]
(mgres/ok? output)
(is (= expected results))))
(deftest test-basic-map-reduce-example-that-replaces-named-collection
(mc/remove monger.core/*mongodb-database* collection {})
(is (mgres/ok? (mc/insert-batch collection batch)))
(let [output (mc/map-reduce collection mapper reducer "mr_outputs" {})
(mc/remove db collection)
(is (mgres/ok? (mc/insert-batch db collection batch)))
(let [output (mc/map-reduce db collection mapper reducer "mr_outputs" {})
results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)]
(mgres/ok? output)
(is (= 3 (monger.core/count results)))
(is (= 3 (mg/count results)))
(is (= expected
(map #(from-db-object % true) (seq results))))
(is (= expected
(map #(from-db-object % true) (mc/find "mr_outputs"))))
(map #(from-db-object % true) (mc/find db "mr_outputs"))))
(.drop ^MapReduceOutput output)))
(deftest test-basic-map-reduce-example-that-merged-results-into-named-collection
(mc/remove monger.core/*mongodb-database* collection {})
(is (mgres/ok? (mc/insert-batch collection batch)))
(mc/map-reduce collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})
(is (mgres/ok? (mc/insert collection { :state "OR" :price 17.95 :quantity 4 })))
(let [^MapReduceOutput output (mc/map-reduce collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})]
(mc/remove db collection)
(is (mgres/ok? (mc/insert-batch db collection batch)))
(mc/map-reduce db collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})
(is (mgres/ok? (mc/insert db collection { :state "OR" :price 17.95 :quantity 4 })))
(let [^MapReduceOutput output (mc/map-reduce db collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})]
(mgres/ok? output)
(is (= 4 (monger.core/count output)))
(is (= 4 (mg/count output)))
(is (= ["CA" "IL" "NY" "OR"]
(map :_id (mc/find-maps "merged_mr_outputs"))))
(.drop ^MapReduceOutput output))))
(map :_id (mc/find-maps db "merged_mr_outputs"))))
(.drop ^MapReduceOutput output)))))

View file

@ -1,409 +0,0 @@
(ns monger.test.multi.atomic-modifiers-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject]
[org.bson.types ObjectId]
[java.util Date])
(:require [monger.core :as mg]
[monger core util]
[monger.multi.collection :as mc]
[monger.result :as mgres]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
(helper/connect!)
(def db (mg/get-db "altdb"))
(defn purge-altdb
[f]
(mc/remove db "scores")
(mc/remove db "things")
(mc/remove db "docs")
(f))
(use-fixtures :each purge-altdb)
;;
;; $inc
;;
(deftest increment-a-single-existing-field-using-$inc-modifier
(let [db (mg/get-db "altdb")
coll "scores"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :username "l33r0y" :score 100 })
(mc/update db coll { :_id oid } { $inc { :score 20 } })
(is (= 120 (:score (mc/find-map-by-id db coll oid))))))
(deftest set-a-single-non-existing-field-using-$inc-modifier
(let [db (mg/get-db "altdb")
coll "scores"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :username "l33r0y" })
(mc/update db coll { :_id oid } { $inc { :score 30 } })
(is (= 30 (:score (mc/find-map-by-id db coll oid))))))
(deftest increment-multiple-existing-fields-using-$inc-modifier
(let [db (mg/get-db "altdb")
coll "scores"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :username "l33r0y" :score 100 :bonus 0 })
(mc/update db coll { :_id oid } {$inc { :score 20 :bonus 10 } })
(is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mc/find-map-by-id db coll oid)))))
(deftest increment-and-set-multiple-existing-fields-using-$inc-modifier
(let [db (mg/get-db "altdb")
coll "scores"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :username "l33r0y" :score 100 })
(mc/update db coll { :_id oid } { $inc { :score 20 :bonus 10 } })
(is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mc/find-map-by-id db coll oid)))))
;;
;; $set
;;
(deftest update-a-single-existing-field-using-$set-modifier
(let [db (mg/get-db "altdb")
coll "things"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :weight 10.0 })
(mc/update db coll { :_id oid } { $set { :weight 20.5 } })
(is (= 20.5 (:weight (mc/find-map-by-id db coll oid [:weight]))))))
(deftest set-a-single-non-existing-field-using-$set-modifier
(let [db (mg/get-db "altdb")
coll "things"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :weight 10.0 })
(mc/update db coll { :_id oid } { $set { :height 17.2 } })
(is (= 17.2 (:height (mc/find-map-by-id db coll oid [:height]))))))
(deftest update-multiple-existing-fields-using-$set-modifier
(let [db (mg/get-db "altdb")
coll "things"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :weight 10.0 :height 15.2 })
(mc/update db coll { :_id oid } { $set { :weight 20.5 :height 25.6 } })
(is (= { :_id oid :weight 20.5 :height 25.6 } (mc/find-map-by-id db coll oid [:weight :height])))))
(deftest update-and-set-multiple-fields-using-$set-modifier
(let [db (mg/get-db "altdb")
coll "things"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :weight 10.0 })
(mc/update db coll { :_id oid } {$set { :weight 20.5 :height 25.6 } })
(is (= { :_id oid :weight 20.5 :height 25.6 } (mc/find-map-by-id db coll oid [:weight :height])))))
;;
;; $unset
;;
(deftest unset-a-single-existing-field-using-$unset-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :title "Document 1" :published true })
(mc/update db coll { :_id oid } { $unset { :published 1 } })
(is (= { :_id oid :title "Document 1" } (mc/find-map-by-id db coll oid)))))
(deftest unset-multiple-existing-fields-using-$unset-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :title "Document 1" :published true :featured true })
(mc/update db coll { :_id oid } { $unset { :published 1 :featured true } })
(is (= { :_id oid :title "Document 1" } (mc/find-map-by-id db coll oid)))))
(deftest unsetting-an-unexisting-field-using-$unset-modifier-is-not-considered-an-issue
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)]
(mc/insert db coll { :_id oid :title "Document 1" :published true })
(is (mgres/ok? (mc/update db coll { :_id oid } { $unset { :published 1 :featured true } })))
(is (= { :_id oid :title "Document 1" } (mc/find-map-by-id db coll oid)))))
;;
;; $setOnInsert
;;
(deftest setOnInsert-in-upsert-for-non-existing-document
(let [db (mg/get-db "altdb")
coll "docs"
now 456
oid (ObjectId.)]
(mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true)
(is (= { :_id oid :lastseen now :firstseen now} (mc/find-map-by-id db coll oid)))))
(deftest setOnInsert-in-upsert-for-existing-document
(let [db (mg/get-db "altdb")
coll "docs"
before 123
now 456
oid (ObjectId.)]
(mc/insert db coll { :_id oid :firstseen before :lastseen before})
(mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true)
(is (= { :_id oid :lastseen now :firstseen before} (mc/find-map-by-id db coll oid)))))
;;
;; $push
;;
(deftest initialize-an-array-using-$push-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mc/insert db coll { :_id oid :title title })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["modifiers"] } (mc/find-map-by-id db coll oid)))))
(deftest add-value-to-an-existing-array-using-$push-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mc/find-map-by-id db coll oid)))))
;; this is a common mistake, I leave it here to demonstrate it. You almost never
;; actually want to do this! What you really want is to use $pushAll instead of $push. MK.
(deftest add-array-value-to-an-existing-array-using-$push-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $push { :tags ["modifiers" "operators"] } })
(is (= { :_id oid :title title :tags ["mongodb" ["modifiers" "operators"]] } (mc/find-map-by-id db coll oid)))))
(deftest double-add-value-to-an-existing-array-using-$push-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$push modifier appends value to field"]
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(mc/update db coll { :_id oid } { $push { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers" "modifiers"] } (mc/find-map-by-id db coll oid)))))
;;
;; $pushAll
;;
(deftest initialize-an-array-using-$pushAll-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"]
(mc/insert db coll { :_id oid :title title })
(mc/update db coll { :_id oid } { $pushAll { :tags ["mongodb" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "docs"] } (mc/find-map-by-id db coll oid)))))
(deftest add-value-to-an-existing-array-using-$pushAll-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"]
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers" "docs"] } (mc/find-map-by-id db coll oid)))))
(deftest double-add-value-to-an-existing-array-using-$pushAll-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pushAll modifier appends multiple values to field"]
(mc/insert db coll { :_id oid :title title :tags ["mongodb" "docs"] })
(mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } })
(is (= { :_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"] } (mc/find-map-by-id db coll oid)))))
;;
;; $addToSet
;;
(deftest initialize-an-array-using-$addToSet-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$addToSet modifier appends value to field unless it is already there"]
(mc/insert db coll { :_id oid :title title })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["modifiers"] } (mc/find-map-by-id db coll oid)))))
(deftest add-value-to-an-existing-array-using-$addToSet-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$addToSet modifier appends value to field unless it is already there"]
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mc/find-map-by-id db coll oid)))))
(deftest double-add-value-to-an-existing-array-using-$addToSet-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$addToSet modifier appends value to field unless it is already there"]
(mc/insert db coll { :_id oid :title title :tags ["mongodb"] })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } })
(is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mc/find-map-by-id db coll oid)))))
;;
;; $pop
;;
(deftest pop-last-value-in-the-array-using-$pop-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pop modifier removes last or first value in the array"]
(mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] })
(mc/update db coll { :_id oid } { $pop { :tags 1 } })
(is (= { :_id oid :title title :tags ["products" "apple"] } (mc/find-map-by-id db coll oid)))))
(deftest unshift-first-value-in-the-array-using-$pop-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pop modifier removes last or first value in the array"]
(mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] })
(mc/update db coll { :_id oid } { $pop { :tags -1 } })
(is (= { :_id oid :title title :tags ["apple" "reviews"] } (mc/find-map-by-id db coll oid)))))
(deftest pop-last-values-from-multiple-arrays-using-$pop-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pop modifier removes last or first value in the array"]
(mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] :categories ["apple" "reviews" "drafts"] })
(mc/update db coll { :_id oid } { $pop { :tags 1 :categories 1 } })
(is (= { :_id oid :title title :tags ["products" "apple"] :categories ["apple" "reviews"] } (mc/find-map-by-id db coll oid)))))
;;
;; $pull
;;
(deftest remove-all-value-entries-from-array-using-$pull-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pull modifier removes all value entries in the array"]
(mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mc/update db coll { :_id oid } { $pull { :measurements 1.2 } })
(is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.3 1.0] } (mc/find-map-by-id db coll oid)))))
(deftest remove-all-value-entries-from-array-using-$pull-modifier-based-on-a-condition
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pull modifier removes all value entries in the array"]
(mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mc/update db coll { :_id oid } { $pull { :measurements { $gte 1.2 } } })
(is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.0] } (mc/find-map-by-id db coll oid)))))
;;
;; $pullAll
;;
(deftest remove-all-value-entries-from-array-using-$pullAll-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$pullAll modifier removes entries of multiple values in the array"]
(mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] })
(mc/update db coll { :_id oid } { $pullAll { :measurements [1.0 1.1 1.2] } })
(is (= { :_id oid :title title :measurements [1.3] } (mc/find-map-by-id db coll oid)))))
;;
;; $rename
;;
(deftest rename-a-single-field-using-$rename-modifier
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
title "$rename renames fields"
v [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0]]
(mc/insert db coll { :_id oid :title title :measurements v })
(mc/update db coll { :_id oid } { $rename { :measurements "results" } })
(is (= { :_id oid :title title :results v } (mc/find-map-by-id db coll oid)))))
;;
;; find-and-modify
;;
(deftest find-and-modify-a-single-document
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
doc {:_id oid :name "Sophie Bangs" :level 42}
conditions {:name "Sophie Bangs"}
update {$inc {:level 1}}]
(mc/insert db coll doc)
(let [res (mc/find-and-modify db coll conditions update :return-new true)]
(is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 43})))))
(deftest find-and-modify-remove-a-document
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
doc {:_id oid :name "Sophie Bangs" :level 42}
conditions {:name "Sophie Bangs"}]
(mc/insert db coll doc)
(let [res (mc/find-and-modify db coll conditions {} :remove true)]
(is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42}))
(is (empty? (mc/find-maps db coll conditions))))))
(deftest find-and-modify-upsert-a-document
(testing "case 1"
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
doc {:_id oid :name "Sophie Bangs" :level 42}]
(let [res (mc/find-and-modify db coll doc doc :upsert true)]
(is (empty? res))
(is (select-keys (mc/find-map-by-id db coll oid) [:name :level]) (dissoc doc :_id)))))
(testing "case 2"
(let [db (mg/get-db "altdb")
coll "docs"
query {:name "Sophie Bangs"}
doc (merge query {:level 42})]
(let [res (mc/find-and-modify db coll query doc :upsert true :return-new true)]
(is (:_id res))
(is (select-keys (mc/find-map-by-id db coll (:_id res)) [:name :level]) doc)))))
(deftest find-and-modify-after-sort
(let [db (mg/get-db "altdb")
coll "docs"
oid (ObjectId.)
oid2 (ObjectId.)
doc {:name "Sophie Bangs"}
doc1 (assoc doc :_id oid :level 42)
doc2 (assoc doc :_id oid2 :level 0)]
(mc/insert-batch db coll [doc1 doc2])
(let [res (mc/find-and-modify db coll doc {$inc {:level 1}} :sort {:level -1})]
(is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42})))))

View file

@ -1,133 +0,0 @@
(ns monger.test.multi.collection-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType]
org.bson.types.ObjectId
java.util.Date)
(:require [monger.core :as mg]
[monger.multi.collection :as mc]
[monger.result :as mgres]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
(helper/connect!)
(def db (mg/get-db "altdb"))
(defn purge-altdb
[f]
(mc/remove db "things")
(mc/remove db "libraries")
(f))
(use-fixtures :each purge-altdb)
(deftest get-collection-size
(let [db (mg/get-db "altdb")
collection "things"]
(is (= 0 (mc/count db collection)))
(mc/insert-batch db collection [{:language "Clojure" :name "langohr"}
{:language "Clojure" :name "monger"}
{:language "Clojure" :name "incanter"}
{:language "Scala" :name "akka"}])
(is (= 4 (mc/count db collection)))
(is (mc/any? db collection))
(is (= 3 (mc/count db collection {:language "Clojure"})))
(is (mc/any? db collection {:language "Clojure"}))
(is (= 1 (mc/count db collection {:language "Scala" })))
(is (mc/any? db collection {:language "Scala"}))
(is (= 0 (mc/count db collection {:language "Python" })))
(is (not (mc/any? db collection {:language "Python"})))))
(deftest remove-all-documents-from-collection
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{:language "Clojure" :name "monger"}
{:language "Clojure" :name "langohr"}
{:language "Clojure" :name "incanter"}
{:language "Scala" :name "akka"}])
(is (= 4 (mc/count db collection)))
(mc/remove db collection)
(is (= 0 (mc/count db collection)))))
(deftest remove-some-documents-from-collection
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{:language "Clojure" :name "monger"}
{:language "Clojure" :name "langohr"}
{:language "Clojure" :name "incanter"}
{:language "Scala" :name "akka"}])
(is (= 4 (mc/count db collection)))
(mc/remove db collection {:language "Clojure"})
(is (= 1 (mc/count db collection)))))
(deftest remove-a-single-document-from-collection
(let [db (mg/get-db "altdb")
collection "libraries"
oid (ObjectId.)]
(mc/insert-batch db collection [{:language "Clojure" :name "monger" :_id oid}])
(mc/remove-by-id db collection oid)
(is (= 0 (mc/count db collection)))
(is (nil? (mc/find-by-id db collection oid)))))
(deftest checking-for-collection-existence-when-it-does-not-exist
(let [db (mg/get-db "altdb")
collection "widgets"]
(mc/drop db collection)
(is (false? (mc/exists? db collection)))))
(deftest checking-for-collection-existence-when-it-does-exist
(let [db (mg/get-db "altdb")
collection "widgets"]
(mc/drop db collection)
(mc/insert-batch db collection [{:name "widget1"}
{:name "widget2"}])
(is (mc/exists? db collection))
(mc/drop db collection)
(is (false? (mc/exists? db collection)))
(mc/create db "widgets" {:capped true :size 100000 :max 10})
(is (mc/exists? db collection))
(mc/rename db collection "gadgets")
(is (not (mc/exists? db collection)))
(is (mc/exists? db "gadgets"))
(mc/drop db "gadgets")))
(deftest test-any-on-empty-collection
(let [db (mg/get-db "altdb")
collection "things"]
(is (not (mc/any? db collection)))))
(deftest test-any-on-non-empty-collection
(let [db (mg/get-db "altdb")
collection "things"
_ (mc/insert db collection {:language "Clojure" :name "langohr"})]
(is (mc/any? db "things"))
(is (mc/any? db "things" {:language "Clojure"}))))
(deftest test-empty-on-empty-collection
(let [db (mg/get-db "altdb")
collection "things"]
(is (mc/empty? db collection))
(is (mc/empty? db collection))))
(deftest test-empty-on-non-empty-collection
(let [db (mg/get-db "altdb")
collection "things"
_ (mc/insert db collection {:language "Clojure" :name "langohr"})]
(is (not (mc/empty? db "things")))))
(deftest test-distinct-values
(let [db (mg/get-db "altdb")
collection "widgets"
batch [{:state "CA" :quantity 1 :price 199.00}
{:state "NY" :quantity 2 :price 199.00}
{:state "NY" :quantity 1 :price 299.00}
{:state "IL" :quantity 2 :price 11.50 }
{:state "CA" :quantity 2 :price 2.95 }
{:state "IL" :quantity 3 :price 5.50 }]]
(mc/insert-batch db collection batch)
(is (= ["CA" "IL" "NY"] (sort (mc/distinct db collection :state {}))))
(is (= ["CA" "NY"] (sort (mc/distinct db collection :state {:price {$gt 100.00}}))))))
(run-tests)

View file

@ -1,149 +0,0 @@
(ns monger.test.multi.find-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject DBRef]
org.bson.types.ObjectId
java.util.Date)
(:require [monger.core :as mg]
[monger.util :as mu]
[monger.multi.collection :as mc]
[monger.test.helper :as helper]
[monger.conversion :as mgcnv]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]
[monger.conversion :refer :all]))
(helper/connect!)
(def db (mg/get-db "altdb"))
(defn purge-altdb
[f]
(mc/remove db "libraries")
(mc/remove db "docs")
(f))
(use-fixtures :each purge-altdb)
;;
;; find
;;
(deftest find-full-document-when-collection-is-empty
(let [db (mg/get-db "altdb")
collection "docs"
cursor (mc/find db collection)]
(is (empty? (iterator-seq cursor)))))
(deftest find-document-seq-when-collection-is-empty
(let [db (mg/get-db "altdb")
collection "docs"]
(is (empty? (mc/find-seq db collection)))))
(deftest find-multiple-documents-when-collection-is-empty
(let [db (mg/get-db "altdb")
collection "libraries"]
(is (empty? (mc/find db collection { :language "Scala" })))))
(deftest find-multiple-maps-when-collection-is-empty
(let [db (mg/get-db "altdb")
collection "libraries"]
(is (empty? (mc/find-maps db collection { :language "Scala" })))))
(deftest find-multiple-documents-by-regex
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Java", :name "nhibernate" }
{ :language "JavaScript", :name "sprout-core" }])
(is (= 2 (monger.core/count (mc/find db collection { :language #"Java*" }))))))
(deftest find-multiple-documents
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(is (= 1 (monger.core/count (mc/find db collection { :language "Scala" }))))
(is (= 3 (.count (mc/find db collection { :language "Clojure" }))))
(is (empty? (mc/find db collection { :language "Java" })))))
(deftest find-document-specify-fields
(let [db (mg/get-db "altdb")
collection "libraries"
_ (mc/insert db collection { :language "Clojure", :name "monger" })
result (mc/find db collection { :language "Clojure"} [:language])]
(is (= (seq [:_id :language]) (keys (mgcnv/from-db-object (.next result) true))))))
(deftest find-and-iterate-over-multiple-documents-the-hard-way
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(doseq [doc (take 3 (map (fn [dbo]
(mgcnv/from-db-object dbo true))
(mc/find-seq db collection { :language "Clojure" })))]
(is (= "Clojure" (:language doc))))))
(deftest find-and-iterate-over-multiple-documents
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(doseq [doc (take 3 (mc/find-maps db collection { :language "Clojure" }))]
(is (= "Clojure" (:language doc))))))
(deftest find-multiple-maps
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(is (= 1 (count (mc/find-maps db collection { :language "Scala" }))))
(is (= 3 (count (mc/find-maps db collection { :language "Clojure" }))))
(is (empty? (mc/find-maps db collection { :language "Java" })))
(is (empty? (mc/find-maps db collection { :language "Java" } [:language :name])))))
(deftest find-multiple-partial-documents
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(let [scala-libs (mc/find db collection { :language "Scala" } [:name])
clojure-libs (mc/find db collection { :language "Clojure"} [:language])]
(is (= 1 (.count scala-libs)))
(is (= 3 (.count clojure-libs)))
(doseq [i clojure-libs]
(let [doc (mgcnv/from-db-object i true)]
(is (= (:language doc) "Clojure"))))
(is (empty? (mc/find db collection { :language "Erlang" } [:name]))))))
(deftest finds-one-as-map
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }])
(let [res (mc/find-one-as-map db collection { :name "langohr" })]
(is (map? res))
(is (= "langohr" (:name res)))
(is (= "Clojure" (:language res))))
(is (= 2 (count (mc/find-one-as-map db collection { :name "langohr" } [:name]))))
(is (= "langohr" (get (mc/find-one-as-map db collection { :name "langohr" } [:name] false) "name")))))
(deftest find-and-modify
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }])))

View file

@ -1,60 +0,0 @@
(ns monger.test.multi.indexing-test
(:import org.bson.types.ObjectId
java.util.Date)
(:require [monger.core :as mg]
[monger.multi.collection :as mc]
[monger.test.helper :as helper]
monger.joda-time
[clojure.test :refer :all]
[monger.test.fixtures :refer :all]
[clj-time.core :refer [now secs ago from-now]]))
(helper/connect!)
(def db (mg/get-db "altdb"))
(defn purge-altdb
[f]
(mc/remove db "libraries")
(mc/remove db "recent_events")
(f))
(use-fixtures :each purge-altdb)
(deftest ^{:indexing true} test-creating-and-dropping-indexes
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/drop-indexes db collection)
(mc/create-index db collection { "language" 1 })
(is (= "language_1"
(:name (second (mc/indexes-on db collection)))))
(mc/drop-index db collection "language_1")
(mc/create-index db collection ["language"])
(mc/drop-index db collection "language_1")
(is (nil? (second (mc/indexes-on db collection))))
(mc/ensure-index db collection (array-map "language" 1) {:unique true})
(is (= "language_1"
(:name (second (mc/indexes-on db collection)))))
(mc/ensure-index db collection (array-map "language" 1))
(mc/ensure-index db collection (array-map "language" 1) { :unique true })
(mc/drop-indexes db collection)))
(deftest ^{:indexing true :edge-features true :time-consuming true} test-ttl-collections
(let [db (mg/get-db "altdb")
coll "recent_events"
ttl 30
sleep 120]
(mc/remove db coll)
(mc/ensure-index db coll (array-map :created-at 1) {:expireAfterSeconds ttl})
(dotimes [i 100]
(mc/insert db coll {:type "signup" :created-at (-> i secs ago) :i i}))
(dotimes [i 100]
(mc/insert db coll {:type "signup" :created-at (-> i secs from-now) :i i}))
(is (= 200 (mc/count db coll {:type "signup"})))
;; sleep for 65 seconds. MongoDB 2.1.2 seems to run TTLMonitor once per minute, according to
;; the log. MK.
(println (format "Now sleeping for %d seconds to test TTL collections!" sleep))
(Thread/sleep (* sleep 1000))
(println (format "Documents in the TTL collection: %d" (mc/count db coll {:type "signup"})))
(is (< (mc/count db coll {:type "signup"}) 100))
(mc/remove db coll)))

View file

@ -1,192 +0,0 @@
(ns monger.test.multi.inserting-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject DBRef]
org.bson.types.ObjectId
java.util.Date)
(:require [monger.core :as mg]
[monger.util :as mu]
[monger.multi.collection :as mc]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.conversion :refer :all]
[monger.test.fixtures :refer :all]))
(helper/connect!)
(def db (mg/get-db "altdb"))
(defn purge-altdb
[f]
(mc/remove db "people")
(mc/remove db "widgets")
(f))
(use-fixtures :each purge-altdb)
;;
;; insert
;;
(deftest insert-a-basic-document-without-id-and-with-default-write-concern
(let [db (mg/get-db "altdb")
collection "people"
doc {:name "Joe" :age 30}]
(is (monger.result/ok? (mc/insert db "people" doc)))
(is (= 1 (mc/count db collection)))))
(deftest insert-a-basic-document-with-explicitly-passed-database-without-id-and-with-default-write-concern
(let [db (mg/get-db "altdb")
collection "people"
doc {:name "Joe" :age 30}]
(dotimes [n 5]
(is (monger.result/ok? (mc/insert db "people" doc WriteConcern/SAFE))))
(is (= 5 (mc/count db collection)))))
(deftest insert-a-basic-document-without-id-and-with-explicit-write-concern
(let [db (mg/get-db "altdb")
collection "people"
doc {:name "Joe" :age 30}]
(is (monger.result/ok? (mc/insert db "people" doc WriteConcern/SAFE)))
(is (= 1 (mc/count db collection)))))
(deftest insert-a-basic-db-object-without-id-and-with-default-write-concern
(let [db (mg/get-db "altdb")
collection "people"
doc (to-db-object {:name "Joe" :age 30})]
(is (nil? (.get ^DBObject doc "_id")))
(mc/insert db "people" doc)
(is (not (nil? (monger.util/get-id doc))))))
(deftest insert-a-map-with-id-and-with-default-write-concern
(let [db (mg/get-db "altdb")
collection "people"
id (ObjectId.)
doc {:name "Joe" :age 30 "_id" id}
result (mc/insert db "people" doc)]
(is (= id (monger.util/get-id doc)))))
(deftest insert-a-document-with-clojure-ratio-in-it
(let [db (mg/get-db "altdb")
collection "widgets"
id (ObjectId.)
doc {:ratio 11/2 "_id" id}
result (mc/insert db "widgets" doc)]
(is (= 5.5 (:ratio (mc/find-map-by-id db collection id))))))
(deftest insert-a-document-with-clojure-keyword-in-it
(let [db (mg/get-db "altdb")
collection "widgets"
id (ObjectId.)
doc {:keyword :kwd "_id" id}
result (mc/insert db "widgets" doc)]
(is (= (name :kwd) (:keyword (mc/find-map-by-id db collection id))))))
(deftest insert-a-document-with-clojure-keyword-in-a-set-in-it
(let [db (mg/get-db "altdb")
collection "widgets"
id (ObjectId.)
doc {:keyword1 {:keyword2 #{:kw1 :kw2}} "_id" id}
result (mc/insert db "widgets" doc)]
(is (= (sort ["kw1" "kw2"])
(sort (get-in (mc/find-map-by-id db collection id) [:keyword1 :keyword2]))))))
(defrecord Metrics
[rps eps])
(deftest insert-a-document-with-clojure-record-in-it
(let [db (mg/get-db "altdb")
collection "widgets"
id (ObjectId.)
doc {:record (Metrics. 10 20) "_id" id}
result (mc/insert db "widgets" doc)]
(is (= {:rps 10 :eps 20} (:record (mc/find-map-by-id db collection id))))))
(deftest test-insert-a-document-with-dbref
(let [db (mg/get-db "altdb")]
(mc/remove db "widgets")
(mc/remove db "owners")
(let [coll1 "widgets"
coll2 "owners"
oid (ObjectId.)
joe (mc/insert db "owners" {:name "Joe" :_id oid})
dbref (DBRef. (mg/current-db) coll2 oid)]
(mc/insert db coll1 {:type "pentagon" :owner dbref})
(let [fetched (mc/find-one-as-map db coll1 {:type "pentagon"})
fo (:owner fetched)]
(is (= {:_id oid :name "Joe"} (from-db-object @fo true)))))))
;;
;; insert-and-return
;;
(deftest insert-and-return-a-basic-document-without-id-and-with-default-write-concern
(let [db (mg/get-db "altdb")
collection "people"
doc {:name "Joe" :age 30}
result (mc/insert-and-return db :people doc)]
(is (= (:name doc)
(:name result)))
(is (= (:age doc)
(:age result)))
(is (:_id result))
(is (= 1 (mc/count db collection)))))
(deftest insert-and-return-a-basic-document-without-id-but-with-a-write-concern
(let [db (mg/get-db "altdb")
collection "people"
doc {:name "Joe" :age 30 :ratio 3/4}
result (mc/insert-and-return db "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 db collection)))))
(deftest insert-and-return-with-a-provided-id
(let [db (mg/get-db "altdb")
collection "people"
oid (ObjectId.)
doc {:name "Joe" :age 30 :_id oid}
result (mc/insert-and-return db :people doc)]
(is (= (:_id result) (:_id doc) oid))
(is (= 1 (mc/count db collection)))))
;;
;; insert-batch
;;
(deftest insert-a-batch-of-basic-documents-without-ids-and-with-default-write-concern
(let [db (mg/get-db "altdb")
collection "people"
docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]]
(is (monger.result/ok? (mc/insert-batch db "people" docs)))
(is (= 2 (mc/count db collection)))))
(deftest insert-a-batch-of-basic-documents-without-ids-and-with-explicit-write-concern
(let [db (mg/get-db "altdb")
collection "people"
docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]]
(is (monger.result/ok? (mc/insert-batch db "people" docs WriteConcern/NORMAL)))
(is (= 2 (mc/count db collection)))))
(deftest insert-a-batch-of-basic-documents-with-explicit-database-without-ids-and-with-explicit-write-concern
(let [db (mg/get-db "altdb")
collection "people"
docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]]
(dotimes [n 44]
(is (monger.result/ok? (mc/insert-batch db "people" docs WriteConcern/NORMAL))))
(is (= 88 (mc/count db collection)))))
(deftest insert-a-batch-of-basic-documents-from-a-lazy-sequence
(let [db (mg/get-db "altdb")
collection "people"
numbers (range 0 1000)]
(is (monger.result/ok? (mc/insert-batch db "people" (map (fn [^long l]
{:n l})
numbers))))
(is (= (count numbers) (mc/count db collection)))))

View file

@ -1,186 +0,0 @@
(ns monger.test.multi.updating-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject]
org.bson.types.ObjectId
java.util.Date)
(:require [monger.core :as mg]
[monger core util]
[monger.multi.collection :as mc]
[monger.result :as mr]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]
[monger.conversion :refer [to-db-object]]))
(helper/connect!)
(def db (mg/get-db "altdb"))
(defn purge-altdb
[f]
(mc/remove db "libraries")
(mc/remove db "people")
(mc/remove db "matches")
(f))
(use-fixtures :each purge-altdb)
;;
;; update, save
;;
(deftest ^{:updating true} update-document-by-id-without-upsert
(let [db (mg/get-db "altdb")
collection "libraries"
doc-id (monger.util/random-uuid)
date (Date.)
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update db collection { :_id doc-id } { :language "Erlang" })
(is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id
(let [db (mg/get-db "altdb")
collection "libraries"
doc-id (monger.util/random-uuid)
date (Date.)
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update-by-id db collection doc-id { :language "Erlang" })
(is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id
(let [db (mg/get-db "altdb")
collection "libraries"
doc-id (ObjectId.)
date (Date.)
doc { :created-at date :data-store "MongoDB" :language { :primary "Clojure" } :_id doc-id }
modified-doc { :created-at date :data-store "MongoDB" :language { :primary "Erlang" } :_id doc-id }]
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update-by-id db collection doc-id { $set { "language.primary" "Erlang" }})
(is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-multiple-documents
(let [db (mg/get-db "altdb")
collection "libraries"]
(mc/insert db collection { :language "Clojure", :name "monger" })
(mc/insert db collection { :language "Clojure", :name "langohr" })
(mc/insert db collection { :language "Clojure", :name "incanter" })
(mc/insert db collection { :language "Scala", :name "akka" })
(is (= 3 (mc/count db collection { :language "Clojure" })))
(is (= 1 (mc/count db collection { :language "Scala" })))
(is (= 0 (mc/count db collection { :language "Python" })))
(mc/update db collection { :language "Clojure" } { $set { :language "Python" } } :multi true)
(is (= 0 (mc/count db collection { :language "Clojure" })))
(is (= 1 (mc/count db collection { :language "Scala" })))
(is (= 3 (mc/count db collection { :language "Python" })))))
(deftest ^{:updating true} save-a-new-document
(let [db (mg/get-db "altdb")
collection "people"
document {:name "Joe" :age 30}]
(is (mr/ok? (mc/save db "people" document)))
(is (= 1 (mc/count db collection)))))
(deftest ^{:updating true} save-and-return-a-new-document
(let [db (mg/get-db "altdb")
collection "people"
document {:name "Joe" :age 30}
returned (mc/save-and-return db "people" document)]
(is (:_id returned))
(is (= document (dissoc returned :_id)))
(is (= 1 (mc/count db collection)))))
(deftest ^{:updating true} save-a-new-basic-db-object
(let [db (mg/get-db "altdb")
collection "people"
doc (to-db-object {:name "Joe" :age 30})]
(is (nil? (monger.util/get-id doc)))
(mc/save db "people" doc WriteConcern/SAFE)
(is (not (nil? (monger.util/get-id doc))))))
(deftest ^{:updating true} update-an-existing-document-using-save
(let [db (mg/get-db "altdb")
collection "people"
doc-id "people-1"
document { :_id doc-id, :name "Joe", :age 30 }]
(is (mr/ok? (mc/insert db "people" document)))
(is (= 1 (mc/count db collection)))
(mc/save db collection { :_id doc-id, :name "Alan", :age 40 })
(is (= 1 (mc/count db collection { :name "Alan", :age 40 })))))
(deftest ^{:updating true} update-an-existing-document-using-save-and-return
(let [db (mg/get-db "altdb")
collection "people"
document (mc/insert-and-return db "people" {:name "Joe" :age 30})
doc-id (:_id document)
updated (mc/save-and-return db collection {:_id doc-id :name "Alan" :age 40})]
(is (= {:_id doc-id :name "Alan" :age 40} updated))
(is (= 1 (mc/count db collection)))
(is (= 1 (mc/count db collection {:name "Alan" :age 40})))))
(deftest ^{:updating true} set-an-attribute-on-existing-document-using-update
(let [db (mg/get-db "altdb")
collection "people"
doc-id (monger.util/object-id)
document { :_id doc-id, :name "Joe", :age 30 }]
(is (mr/ok? (mc/insert db "people" document)))
(is (= 1 (mc/count db collection)))
(is (= 0 (mc/count db collection { :has_kids true })))
(mc/update db collection { :_id doc-id } { $set { :has_kids true } })
(is (= 1 (mc/count db collection { :has_kids true })))))
(deftest ^{:updating true} increment-multiple-fields-using-exists-operator-and-update
(let [db (mg/get-db "altdb")
collection "matches"
doc-id (monger.util/object-id)
document { :_id doc-id :abc 0 :def 10 }]
(mc/remove db collection)
(is (mr/ok? (mc/insert db collection document)))
(is (= 1 (mc/count db collection {:abc {$exists true} :def {$exists true}})))
(mc/update db collection {:abc {$exists true} :def {$exists true}} {$inc {:abc 1 :def 0}})
(is (= 1 (mc/count db collection { :abc 1 })))))
(deftest ^{:updating true} upsert-a-document-using-update
(let [db (mg/get-db "altdb")
collection "libraries"
doc-id (monger.util/random-uuid)
date (Date.)
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(is (not (mr/updated-existing? (mc/update db collection { :language "Clojure" } doc :upsert true))))
(is (= 1 (mc/count db collection)))
(is (mr/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc :multi false :upsert true)))
(is (= 1 (mc/count db collection)))
(is (= (modified-doc (mc/find-by-id db collection doc-id))))
(mc/remove db collection)))
(deftest ^{:updating true} upsert-a-document-using-upsert
(let [db (mg/get-db "altdb")
collection "libraries"
doc-id (monger.util/random-uuid)
date (Date.)
doc {:created-at date :data-store "MongoDB" :language "Clojure" :_id doc-id}
modified-doc {:created-at date :data-store "MongoDB" :language "Erlang" :_id doc-id}]
(mc/remove db collection)
(is (not (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} doc))))
(is (= 1 (mc/count db collection)))
(is (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} modified-doc :multi false)))
(is (= 1 (mc/count db collection)))
(is (= (modified-doc (mc/find-by-id db collection doc-id))))
(mc/remove db collection)))

View file

@ -1,109 +1,110 @@
(ns monger.test.query-operators-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType]
org.bson.types.ObjectId
java.util.Date)
(:require [monger core util]
[clojure stacktrace]
[monger.collection :as mgcol]
[monger.result :as mgres]
[monger.conversion :as mgcnv]
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.js :as js]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
[monger.operators :refer :all]))
(monger.core/connect!)
(monger.core/set-db! (monger.core/get-db "monger-test"))
;; (use-fixtures :each purge-people purge-docs purge-things purge-libraries)
(use-fixtures :each purge-people purge-docs purge-things purge-libraries)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(defn purge-collections
[f]
(mc/remove db "people")
(mc/remove db "libraries")
(f)
(mc/remove db "people")
(mc/remove db "libraries"))
;;
;; $gt, $gte, $lt, lte
;;
(use-fixtures :each purge-collections)
(deftest find-with-conditional-operators-comparison
;;
;; $gt, $gte, $lt, lte
;;
(deftest find-with-conditional-operators-comparison
(let [collection "libraries"]
(mgcol/insert-batch collection [{:language "Clojure" :name "monger" :users 1}
(mc/insert-batch db collection [{:language "Clojure" :name "monger" :users 1}
{:language "Clojure" :name "langohr" :users 5}
{:language "Clojure" :name "incanter" :users 15}
{:language "Scala" :name "akka" :users 150}])
(are [a b] (= a (.count (mgcol/find collection b)))
(are [a b] (= a (.count (mc/find db collection b)))
2 {:users {$gt 10}}
3 {:users {$gte 5}}
2 {:users {$lt 10}}
2 {:users {$lte 5}}
1 {:users {$gt 10 $lt 150}})))
;;
;; $ne
;;
;;
;; $ne
;;
(deftest find-with-and-or-operators
(deftest find-with-and-or-operators
(let [collection "libraries"]
(mgcol/insert-batch collection [{:language "Ruby" :name "mongoid" :users 1}
(mc/insert-batch db collection [{:language "Ruby" :name "mongoid" :users 1}
{:language "Clojure" :name "langohr" :users 5}
{:language "Clojure" :name "incanter" :users 15}
{:language "Scala" :name "akka" :users 150}])
(is (= 2 (.count (mgcol/find collection {$ne {:language "Clojure"}}))))))
(is (= 2 (.count (mc/find db collection {$ne {:language "Clojure"}}))))))
;;
;; $and, $or, $nor
;;
;;
;; $and, $or, $nor
;;
(deftest find-with-and-or-operators
(deftest find-with-and-or-operators
(let [collection "libraries"]
(mgcol/insert-batch collection [{:language "Ruby" :name "mongoid" :users 1}
(mc/insert-batch db collection [{:language "Ruby" :name "mongoid" :users 1}
{:language "Clojure" :name "langohr" :users 5}
{:language "Clojure" :name "incanter" :users 15}
{:language "Scala" :name "akka" :users 150}])
(is (= 1 (.count (mgcol/find collection {$and [{:language "Clojure"}
(is (= 1 (.count (mc/find db collection {$and [{:language "Clojure"}
{:users {$gt 10}}]}))))
(is (= 3 (.count (mgcol/find collection {$or [{:language "Clojure"}
(is (= 3 (.count (mc/find db collection {$or [{:language "Clojure"}
{:users {$gt 10}} ]}))))
(is (= 1 (.count (mgcol/find collection {$nor [{:language "Clojure"}
(is (= 1 (.count (mc/find db collection {$nor [{:language "Clojure"}
{:users {$gt 10}} ]}))))))
;;
;; $all, $in, $nin
;;
;;
;; $all, $in, $nin
;;
(deftest find-on-embedded-arrays
(deftest find-on-embedded-arrays
(let [collection "libraries"]
(mgcol/insert-batch collection [{:language "Clojure" :tags [ "functional" ]}
(mc/insert-batch db collection [{:language "Clojure" :tags [ "functional" ]}
{:language "Scala" :tags [ "functional" "object-oriented" ]}
{:language "Ruby" :tags [ "object-oriented" "dynamic" ]}])
(is (= "Scala" (:language (first (mgcol/find-maps collection {:tags {$all [ "functional" "object-oriented" ]}} )))))
(is (= 3 (.count (mgcol/find-maps collection {:tags {$in [ "functional" "object-oriented" ]}} ))))
(is (= 2 (.count (mgcol/find-maps collection {:language {$in [ "Scala" "Ruby" ]}} ))))
(is (= 1 (.count (mgcol/find-maps collection {:tags {$nin [ "dynamic" "object-oriented" ]}} ))))
(is (= 3 (.count (mgcol/find-maps collection {:language {$nin [ "C#" ]}} ))))))
(is (= "Scala" (:language (first (mc/find-maps db collection {:tags {$all [ "functional" "object-oriented" ]}} )))))
(is (= 3 (.count (mc/find-maps db collection {:tags {$in [ "functional" "object-oriented" ]}} ))))
(is (= 2 (.count (mc/find-maps db collection {:language {$in [ "Scala" "Ruby" ]}} ))))
(is (= 1 (.count (mc/find-maps db collection {:tags {$nin [ "dynamic" "object-oriented" ]}} ))))
(is (= 3 (.count (mc/find-maps db collection {:language {$nin [ "C#" ]}} ))))))
(deftest find-with-conditional-operators-on-embedded-documents
(deftest find-with-conditional-operators-on-embedded-documents
(let [collection "people"]
(mgcol/insert-batch collection [{:name "Bob" :comments [{:text "Nice!" :rating 1}
(mc/insert-batch db collection [{:name "Bob" :comments [{:text "Nice!" :rating 1}
{:text "Love it" :rating 4}
{:text "What?":rating -5} ]}
{:name "Alice" :comments [{:text "Yeah" :rating 2}
{:text "Doh" :rating 1}
{:text "Agreed" :rating 3}]}])
(are [a b] (= a (.count (mgcol/find collection b)))
(are [a b] (= a (.count (mc/find db collection b)))
1 {:comments {$elemMatch {:text "Nice!" :rating {$gte 1}}}}
2 {"comments.rating" 1}
1 {"comments.rating" {$gt 3}})))
(deftest find-with-regex-operator
(deftest find-with-regex-operator
(let [collection "libraries"]
(mgcol/insert-batch collection [{:language "Ruby" :name "Mongoid" :users 1}
(mc/insert-batch db collection [{:language "Ruby" :name "Mongoid" :users 1}
{:language "Clojure" :name "Langohr" :users 5}
{:language "Clojure" :name "Incanter" :users 15}
{:language "Scala" :name "Akka" :users 150}])
(are [query results] (is (= results (.count (mgcol/find collection query))))
(are [query results] (is (= results (.count (mc/find db collection query))))
{:language {$regex "Clo.*"}} 2
{:language {$regex "clo.*" $options "i"}} 2
{:name {$regex "aK.*" $options "i"}} 1
{:language {$regex ".*by"}} 1
{:language {$regex ".*ala.*"}} 1)))
{:language {$regex ".*ala.*"}} 1))))

View file

@ -1,59 +1,69 @@
(ns monger.test.querying-test
(:refer-clojure :exclude [select find sort])
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject ReadPreference]
(:import [com.mongodb WriteResult WriteConcern DBObject ReadPreference]
org.bson.types.ObjectId
java.util.Date)
(:require [monger core util]
[monger.collection :as mgcol]
(:require [monger.core :as mg]
[monger.collection :as mc]
monger.joda-time
[monger.result :as mgres]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.test.fixtures :refer :all]
[monger.conversion :refer :all]
[monger.query :refer :all]
[monger.operators :refer :all]
[clj-time.core :refer [date-time]]))
(helper/connect!)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(use-fixtures :each purge-docs purge-things purge-locations
purge-querying-docs)
(defn purge-collections
[f]
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "locations")
(mc/remove db "querying_docs")
(f)
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "locations")
(mc/remove db "querying_docs"))
(use-fixtures :each purge-collections)
;;
;; monger.collection/* finders ("low-level API")
;;
;;
;; monger.collection/* finders ("low-level API")
;;
;; by ObjectId
;; by ObjectId
(deftest query-full-document-by-object-id
(deftest query-full-document-by-object-id
(let [coll "querying_docs"
oid (ObjectId.)
doc { :_id oid :title "Introducing Monger" }]
(mgcol/insert coll doc)
(is (= doc (mgcol/find-map-by-id coll oid)))
(is (= doc (mgcol/find-one-as-map coll { :_id oid })))))
(mc/insert db coll doc)
(is (= doc (mc/find-map-by-id db coll oid)))
(is (= doc (mc/find-one-as-map db coll { :_id oid })))))
;; exact match over string field
;; exact match over string field
(deftest query-full-document-using-exact-matching-over-string-field
(deftest query-full-document-using-exact-matching-over-string-field
(let [coll "querying_docs"
doc { :title "monger" :language "Clojure" :_id (ObjectId.) }]
(mgcol/insert coll doc)
(is (= [doc] (mgcol/find-maps coll { :title "monger" })))
(is (= doc (from-db-object (first (mgcol/find coll { :title "monger" })) true)))))
(mc/insert db coll doc)
(is (= [doc] (mc/find-maps db coll { :title "monger" })))
(is (= doc (from-db-object (first (mc/find db coll { :title "monger" })) true)))))
;; exact match over string field with limit
;; exact match over string field with limit
(deftest query-full-document-using-exact-matching-over-string-with-field-with-limit
(deftest query-full-document-using-exact-matching-over-string-with-field-with-limit
(let [coll "querying_docs"
doc1 { :title "monger" :language "Clojure" :_id (ObjectId.) }
doc2 { :title "langohr" :language "Clojure" :_id (ObjectId.) }
doc3 { :title "netty" :language "Java" :_id (ObjectId.) }
_ (mgcol/insert-batch coll [doc1 doc2 doc3])
result (with-collection coll
_ (mc/insert-batch db coll [doc1 doc2 doc3])
result (with-collection db coll
(find { :title "monger" })
(fields [:title, :language, :_id])
(skip 0)
@ -62,13 +72,13 @@
(is (= [doc1] result))))
(deftest query-full-document-using-exact-matching-over-string-field-with-limit-and-offset
(deftest query-full-document-using-exact-matching-over-string-field-with-limit-and-offset
(let [coll "querying_docs"
doc1 { :title "lucene" :language "Java" :_id (ObjectId.) }
doc2 { :title "joda-time" :language "Java" :_id (ObjectId.) }
doc3 { :title "netty" :language "Java" :_id (ObjectId.) }
_ (mgcol/insert-batch coll [doc1 doc2 doc3])
result (with-collection coll
_ (mc/insert-batch db coll [doc1 doc2 doc3])
result (with-collection db coll
(find { :language "Java" })
(skip 1)
(limit 2)
@ -76,24 +86,24 @@
(is (= 2 (count result)))
(is (= [doc1 doc3] result))))
(deftest query-with-sorting-on-multiple-fields
(deftest query-with-sorting-on-multiple-fields
(let [coll "querying_docs"
doc1 { :a 1 :b 2 :c 3 :text "Whatever" :_id (ObjectId.) }
doc2 { :a 1 :b 1 :c 4 :text "Blah " :_id (ObjectId.) }
doc3 { :a 10 :b 3 :c 1 :text "Abc" :_id (ObjectId.) }
doc4 { :a 10 :b 3 :c 3 :text "Abc" :_id (ObjectId.) }
_ (mgcol/insert-batch coll [doc1 doc2 doc3 doc4])
result1 (with-collection coll
_ (mc/insert-batch db coll [doc1 doc2 doc3 doc4])
result1 (with-collection db coll
(find {})
(limit 2)
(fields [:a :b :c :text])
(sort (sorted-map :a 1 :b 1 :text -1)))
result2 (with-collection coll
result2 (with-collection db coll
(find {})
(limit 2)
(fields [:a :b :c :text])
(sort (array-map :c 1 :text -1)))
result3 (with-collection coll
result3 (with-collection db coll
(find {})
(limit 2)
(fields [:a :b :c :text])
@ -103,68 +113,68 @@
(is (= [doc2 doc4] result3))))
;; < ($lt), <= ($lte), > ($gt), >= ($gte)
;; < ($lt), <= ($lte), > ($gt), >= ($gte)
(deftest query-using-dsl-and-$lt-operator-with-integers
(deftest query-using-dsl-and-$lt-operator-with-integers
(let [coll "querying_docs"
doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 }
doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 }
doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 }
_ (mgcol/insert-batch coll [doc1 doc2])
lt-result (with-collection "querying_docs"
_ (mc/insert-batch db coll [doc1 doc2])
lt-result (with-collection db coll
(find { :inception_year { $lt 2000 } })
(limit 2))]
(is (= [doc2] (vec lt-result)))))
(deftest query-using-dsl-and-$lt-operator-with-dates
(deftest query-using-dsl-and-$lt-operator-with-dates
(let [coll "querying_docs"
;; these rely on monger.joda-time being loaded. MK.
doc1 { :language "Clojure" :_id (ObjectId.) :inception_year (date-time 2006 1 1) }
doc2 { :language "Java" :_id (ObjectId.) :inception_year (date-time 1992 1 2) }
doc3 { :language "Scala" :_id (ObjectId.) :inception_year (date-time 2003 3 3) }
_ (mgcol/insert-batch coll [doc1 doc2])
lt-result (with-collection "querying_docs"
_ (mc/insert-batch db coll [doc1 doc2])
lt-result (with-collection db coll
(find { :inception_year { $lt (date-time 2000 1 2) } })
(limit 2))]
(is (= (map :_id [doc2])
(map :_id (vec lt-result))))))
(deftest query-using-both-$lte-and-$gte-operators-with-dates
(deftest query-using-both-$lte-and-$gte-operators-with-dates
(let [coll "querying_docs"
;; these rely on monger.joda-time being loaded. MK.
doc1 { :language "Clojure" :_id (ObjectId.) :inception_year (date-time 2006 1 1) }
doc2 { :language "Java" :_id (ObjectId.) :inception_year (date-time 1992 1 2) }
doc3 { :language "Scala" :_id (ObjectId.) :inception_year (date-time 2003 3 3) }
_ (mgcol/insert-batch coll [doc1 doc2 doc3])
lt-result (with-collection "querying_docs"
_ (mc/insert-batch db coll [doc1 doc2 doc3])
lt-result (with-collection db coll
(find { :inception_year { $gt (date-time 2000 1 2) $lte (date-time 2007 2 2) } })
(sort { :inception_year 1 }))]
(is (= (map :_id [doc3 doc1])
(map :_id (vec lt-result))))))
(deftest query-using-$gt-$lt-$gte-$lte-operators-as-strings
(deftest query-using-$gt-$lt-$gte-$lte-operators-as-strings
(let [coll "querying_docs"
doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 }
doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 }
doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 }
_ (mgcol/insert-batch coll [doc1 doc2 doc3])]
_ (mc/insert-batch db coll [doc1 doc2 doc3])]
(are [doc, result]
(= doc, result)
(doc2 (with-collection coll
(doc2 (with-collection db coll
(find { :inception_year { "$lt" 2000 } })))
(doc2 (with-collection coll
(doc2 (with-collection db coll
(find { :inception_year { "$lte" 1992 } })))
(doc1 (with-collection coll
(doc1 (with-collection db coll
(find { :inception_year { "$gt" 2002 } })
(limit 1)
(sort { :inception_year -1 })))
(doc1 (with-collection coll
(doc1 (with-collection db coll
(find { :inception_year { "$gte" 2006 } }))))))
(deftest query-using-$gt-$lt-$gte-$lte-operators-using-dsl-composition
(deftest query-using-$gt-$lt-$gte-$lte-operators-using-dsl-composition
(let [coll "querying_docs"
doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 }
doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 }
@ -172,25 +182,25 @@
srt (-> {}
(limit 1)
(sort { :inception_year -1 }))
_ (mgcol/insert-batch coll [doc1 doc2 doc3])]
(is (= [doc1] (with-collection coll
_ (mc/insert-batch db coll [doc1 doc2 doc3])]
(is (= [doc1] (with-collection db coll
(find { :inception_year { "$gt" 2002 } })
(merge srt))))))
;; $all
;; $all
(deftest query-with-using-$all
(deftest query-with-using-$all
(let [coll "querying_docs"
doc1 { :_id (ObjectId.) :title "Clojure" :tags ["functional" "homoiconic" "syntax-oriented" "dsls" "concurrency features" "jvm"] }
doc2 { :_id (ObjectId.) :title "Java" :tags ["object-oriented" "jvm"] }
doc3 { :_id (ObjectId.) :title "Scala" :tags ["functional" "object-oriented" "dsls" "concurrency features" "jvm"] }
- (mgcol/insert-batch coll [doc1 doc2 doc3])
result1 (with-collection coll
- (mc/insert-batch db coll [doc1 doc2 doc3])
result1 (with-collection db coll
(find { :tags { "$all" ["functional" "jvm" "homoiconic"] } }))
result2 (with-collection coll
result2 (with-collection db coll
(find { :tags { "$all" ["functional" "native" "homoiconic"] } }))
result3 (with-collection coll
result3 (with-collection db coll
(find { :tags { "$all" ["functional" "jvm" "dsls"] } })
(sort { :title 1 }))]
(is (= [doc1] result1))
@ -199,52 +209,52 @@
(is (= doc1 (first result3)))))
;; $exists
;; $exists
(deftest query-with-find-one-as-map-using-$exists
(deftest query-with-find-one-as-map-using-$exists
(let [coll "querying_docs"
doc1 { :_id (ObjectId.) :published-by "Jill The Blogger" :draft false :title "X announces another Y" }
doc2 { :_id (ObjectId.) :draft true :title "Z announces a Y competitor" }
_ (mgcol/insert-batch coll [doc1 doc2])
result1 (mgcol/find-one-as-map coll { :published-by { "$exists" true } })
result2 (mgcol/find-one-as-map coll { :published-by { "$exists" false } })]
_ (mc/insert-batch db coll [doc1 doc2])
result1 (mc/find-one-as-map db coll { :published-by { "$exists" true } })
result2 (mc/find-one-as-map db coll { :published-by { "$exists" false } })]
(is (= doc1 result1))
(is (= doc2 result2))))
;; $mod
;; $mod
(deftest query-with-find-one-as-map-using-$mod
(deftest query-with-find-one-as-map-using-$mod
(let [coll "querying_docs"
doc1 { :_id (ObjectId.) :counter 25 }
doc2 { :_id (ObjectId.) :counter 32 }
doc3 { :_id (ObjectId.) :counter 63 }
_ (mgcol/insert-batch coll [doc1 doc2 doc3])
result1 (mgcol/find-one-as-map coll { :counter { "$mod" [10, 5] } })
result2 (mgcol/find-one-as-map coll { :counter { "$mod" [10, 2] } })
result3 (mgcol/find-one-as-map coll { :counter { "$mod" [11, 1] } })]
_ (mc/insert-batch db coll [doc1 doc2 doc3])
result1 (mc/find-one-as-map db coll { :counter { "$mod" [10, 5] } })
result2 (mc/find-one-as-map db coll { :counter { "$mod" [10, 2] } })
result3 (mc/find-one-as-map db coll { :counter { "$mod" [11, 1] } })]
(is (= doc1 result1))
(is (= doc2 result2))
(is (empty? result3))))
;; $ne
;; $ne
(deftest query-with-find-one-as-map-using-$ne
(deftest query-with-find-one-as-map-using-$ne
(let [coll "querying_docs"
doc1 { :_id (ObjectId.) :counter 25 }
doc2 { :_id (ObjectId.) :counter 32 }
_ (mgcol/insert-batch coll [doc1 doc2])
result1 (mgcol/find-one-as-map coll { :counter { "$ne" 25 } })
result2 (mgcol/find-one-as-map coll { :counter { "$ne" 32 } })]
_ (mc/insert-batch db coll [doc1 doc2])
result1 (mc/find-one-as-map db coll { :counter { "$ne" 25 } })
result2 (mc/find-one-as-map db coll { :counter { "$ne" 32 } })]
(is (= doc2 result1))
(is (= doc1 result2))))
;;
;; monger.query DSL features
;;
;;
;; monger.query DSL features
;;
;; pagination
(deftest query-using-pagination-dsl
;; pagination
(deftest query-using-pagination-dsl
(let [coll "querying_docs"
doc1 { :_id (ObjectId.) :title "Clojure" :tags ["functional" "homoiconic" "syntax-oriented" "dsls" "concurrency features" "jvm"] }
doc2 { :_id (ObjectId.) :title "Java" :tags ["object-oriented" "jvm"] }
@ -253,22 +263,22 @@
doc5 { :_id (ObjectId.) :title "Groovy" :tags ["dynamic" "object-oriented" "dsls" "jvm"] }
doc6 { :_id (ObjectId.) :title "OCaml" :tags ["functional" "static" "dsls"] }
doc7 { :_id (ObjectId.) :title "Haskell" :tags ["functional" "static" "dsls" "concurrency features"] }
- (mgcol/insert-batch coll [doc1 doc2 doc3 doc4 doc5 doc6 doc7])
result1 (with-collection coll
- (mc/insert-batch db coll [doc1 doc2 doc3 doc4 doc5 doc6 doc7])
result1 (with-collection db coll
(find {})
(paginate :page 1 :per-page 3)
(sort { :title 1 })
(read-preference (ReadPreference/primary))
(options com.mongodb.Bytes/QUERYOPTION_NOTIMEOUT))
result2 (with-collection coll
result2 (with-collection db coll
(find {})
(paginate :page 2 :per-page 3)
(sort { :title 1 }))
result3 (with-collection coll
result3 (with-collection db coll
(find {})
(paginate :page 3 :per-page 3)
(sort { :title 1 }))
result4 (with-collection coll
result4 (with-collection db coll
(find {})
(paginate :page 10 :per-page 3)
(sort { :title 1 }))]
@ -278,7 +288,7 @@
(is (empty? result4))))
(deftest combined-querying-dsl-example1
(deftest combined-querying-dsl-example1
(let [coll "querying_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" }
@ -287,14 +297,14 @@
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
_ (mc/insert-batch db coll [ma-doc de-doc ny-doc ca-doc tx-doc])
result (with-collection db coll
(find {})
(merge top3)
(merge by-population-desc))]
(is (= result [ca-doc tx-doc ny-doc]))))
(deftest combined-querying-dsl-example2
(deftest combined-querying-dsl-example2
(let [coll "querying_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" }
@ -303,8 +313,8 @@
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
_ (mc/insert-batch db coll [ma-doc de-doc ny-doc ca-doc tx-doc])
result (with-collection db coll
(find {})
(merge top3)
(merge by-population-desc)
@ -312,4 +322,4 @@
;; documents have fields as strings,
;; not keywords
(is (= (map #(% "name") result)
(map #(% :name) [ca-doc tx-doc ny-doc])))))
(map #(% :name) [ca-doc tx-doc ny-doc]))))))

View file

@ -1,22 +1,24 @@
(ns monger.test.ragtime-test
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.test.helper :as helper]
monger.ragtime
[clojure.test :refer :all]
[monger.test.fixtures :refer [purge-migrations]]
[ragtime.core :refer :all]))
[ragtime.core :refer :all]
[clojure.test :refer :all]))
(helper/connect!)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(defn purge-collections
[f]
(mc/remove db "meta.migrations")
(f)
(mc/remove db "meta.migrations"))
(use-fixtures :each purge-migrations)
(use-fixtures :each purge-collections)
(when-not (get (System/getenv) "CI")
(when-not (get (System/getenv) "CI")
(deftest test-add-migration-id
(let [db (mg/get-db "monger-test")
coll "meta.migrations"
(let [coll "meta.migrations"
key "1"]
(mc/remove db coll {})
(is (not (mc/any? db coll {:_id key})))
@ -27,8 +29,7 @@
(deftest test-remove-migration-id
(let [db (mg/get-db "monger-test")
coll "meta.migrations"
(let [coll "meta.migrations"
key "1"]
(mc/remove db coll {})
(add-migration-id db key)
@ -39,8 +40,7 @@
(deftest test-migrations-ordering
(let [db (mg/get-db "monger-test")
coll "meta.migrations"
(let [coll "meta.migrations"
all-keys [ "9" "4" "7" "1" "5" "3" "6" "2" "8"]]
(mc/remove db coll {})
@ -52,4 +52,4 @@
(is (some #{key} (applied-migration-ids db))))
(testing "Applied migrations must come out in creation order"
(is (= all-keys (applied-migration-ids db)))))))
(is (= all-keys (applied-migration-ids db))))))))

View file

@ -2,276 +2,283 @@
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject]
org.bson.types.ObjectId
java.util.Date)
(:require [monger core util]
[monger.collection :as mgcol]
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.util :as mu]
[monger.result :as mgres]
[monger.conversion :as mgcnv]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]))
[monger.operators :refer :all]))
(helper/connect!)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(use-fixtures :each (fn [f]
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "regular_finders_docs")
(mc/remove db "things")
(mc/remove db "libraries")
(f)
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "regular_finders_docs")
(mc/remove db "things")
(mc/remove db "libraries")))
(use-fixtures :each purge-people purge-docs purge-things purge-libraries
purge-finder-docs)
;;
;; find-one
;;
;;
;; find-one
;;
(deftest find-one-full-document-when-collection-is-empty
(deftest find-one-full-document-when-collection-is-empty
(let [collection "regular_finders_docs"]
(is (nil? (mgcol/find-one collection {})))))
(is (nil? (mc/find-one db collection {})))))
(deftest find-one-full-document-as-map-when-collection-is-empty
(deftest find-one-full-document-as-map-when-collection-is-empty
(let [collection "regular_finders_docs"]
(mgcol/remove collection)
(is (nil? (mgcol/find-one-as-map collection {})))))
(mc/remove db collection)
(is (nil? (mc/find-one-as-map db collection {})))))
(deftest find-one-full-document-when-collection-has-matches
(deftest find-one-full-document-when-collection-has-matches
(let [collection "regular_finders_docs"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }
_ (mgcol/insert collection doc)
found-one (mgcol/find-one collection { :language "Clojure" })]
_ (mc/insert db collection doc)
found-one (mc/find-one db collection { :language "Clojure" })]
(is found-one)
(is (= (:_id doc) (monger.util/get-id found-one)))
(is (= (:_id doc) (mu/get-id found-one)))
(is (= (mgcnv/from-db-object found-one true) doc))
(is (= (mgcnv/to-db-object doc) found-one))))
(deftest find-one-full-document-as-map-when-collection-has-matches
(deftest find-one-full-document-as-map-when-collection-has-matches
(let [collection "regular_finders_docs"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mgcol/insert collection doc)
(is (= doc (mgcol/find-one-as-map collection { :language "Clojure" })))))
(mc/insert db collection doc)
(is (= doc (mc/find-one-as-map db collection { :language "Clojure" })))))
(deftest find-one-partial-document-when-collection-has-matches
(deftest find-one-partial-document-when-collection-has-matches
(let [collection "regular_finders_docs"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }
_ (mgcol/insert collection doc)
loaded (mgcol/find-one collection { :language "Clojure" } [:language])]
_ (mc/insert db collection doc)
loaded (mc/find-one db collection { :language "Clojure" } [:language])]
(is (nil? (.get ^DBObject loaded "data-store")))
(is (= doc-id (monger.util/get-id loaded)))
(is (= doc-id (mu/get-id loaded)))
(is (= "Clojure" (.get ^DBObject loaded "language")))))
(deftest find-one-partial-document-using-field-negation-when-collection-has-matches
(deftest find-one-partial-document-using-field-negation-when-collection-has-matches
(let [collection "regular_finders_docs"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }
_ (mgcol/insert collection doc)
^DBObject loaded (mgcol/find-one collection { :language "Clojure" } {:data-store 0 :_id 0})]
_ (mc/insert db collection doc)
^DBObject loaded (mc/find-one db collection { :language "Clojure" } {:data-store 0 :_id 0})]
(is (nil? (.get loaded "data-store")))
(is (nil? (.get loaded "_id")))
(is (nil? (monger.util/get-id loaded)))
(is (nil? (mu/get-id loaded)))
(is (= "Clojure" (.get loaded "language")))))
(deftest find-one-partial-document-as-map-when-collection-has-matches
(deftest find-one-partial-document-as-map-when-collection-has-matches
(let [collection "regular_finders_docs"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mgcol/insert collection doc)
(is (= { :data-store "MongoDB", :_id doc-id } (mgcol/find-one-as-map collection { :language "Clojure" } [:data-store])))))
(mc/insert db collection doc)
(is (= { :data-store "MongoDB", :_id doc-id }
(mc/find-one-as-map db collection { :language "Clojure" } [:data-store])))))
(deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize
(deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize
(let [collection "regular_finders_docs"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }
fields [:data-store]
_id (mgcol/insert collection doc)
loaded (mgcol/find-one-as-map collection { :language "Clojure" } fields true)
_id (mc/insert db collection doc)
loaded (mc/find-one-as-map db collection { :language "Clojure" } fields true)
]
(is (= { :data-store "MongoDB", :_id doc-id } loaded ))))
(deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize-false
(deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize-false
(let [collection "regular_finders_docs"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }
fields [:data-store]
_id (mgcol/insert collection doc)
loaded (mgcol/find-one-as-map collection { :language "Clojure" } fields false)
]
_id (mc/insert db collection doc)
loaded (mc/find-one-as-map db collection { :language "Clojure" } fields false)]
(is (= { "_id" doc-id, "data-store" "MongoDB" } loaded ))))
;;
;; find-by-id
;;
;;
;; find-by-id
;;
(deftest find-full-document-by-string-id-when-that-document-does-not-exist
(deftest find-full-document-by-string-id-when-that-document-does-not-exist
(let [collection "libraries"
doc-id (monger.util/random-uuid)]
(is (nil? (mgcol/find-by-id collection doc-id)))))
doc-id (mu/random-uuid)]
(is (nil? (mc/find-by-id db collection doc-id)))))
(deftest find-full-document-by-string-id-when-id-is-nil
(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)))))
(is (thrown? IllegalArgumentException (mc/find-by-id db 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"
doc-id (ObjectId.)]
(is (nil? (mgcol/find-by-id collection doc-id)))))
(is (nil? (mc/find-by-id db collection doc-id)))))
(deftest find-full-document-by-id-as-map-when-that-document-does-not-exist
(deftest find-full-document-by-id-as-map-when-that-document-does-not-exist
(let [collection "libraries"
doc-id (monger.util/random-uuid)]
(is (nil? (mgcol/find-map-by-id collection doc-id)))))
doc-id (mu/random-uuid)]
(is (nil? (mc/find-map-by-id db collection doc-id)))))
(deftest find-full-document-by-id-as-map-when-id-is-nil
(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)))))
(mc/find-map-by-id db 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"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mgcol/insert collection doc)
(is (= (doc (mgcol/find-by-id collection doc-id))))))
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))))
(deftest find-full-document-by-object-id-when-document-does-exist
(deftest find-full-document-by-object-id-when-document-does-exist
(let [collection "libraries"
doc-id (ObjectId.)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mgcol/insert collection doc)
(is (= (doc (mgcol/find-by-id collection doc-id))))))
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))))
(deftest find-full-document-map-by-string-id-when-document-does-exist
(deftest find-full-document-map-by-string-id-when-document-does-exist
(let [collection "libraries"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mgcol/insert collection doc)
(is (= (doc (mgcol/find-map-by-id collection doc-id))))))
(mc/insert db collection doc)
(is (= (doc (mc/find-map-by-id db collection doc-id))))))
(deftest find-full-document-map-by-object-id-when-document-does-exist
(deftest find-full-document-map-by-object-id-when-document-does-exist
(let [collection "libraries"
doc-id (ObjectId.)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mgcol/insert collection doc)
(is (= (doc (mgcol/find-map-by-id collection doc-id))))))
(mc/insert db collection doc)
(is (= (doc (mc/find-map-by-id db collection doc-id))))))
(deftest find-partial-document-by-id-when-document-does-exist
(deftest find-partial-document-by-id-when-document-does-exist
(let [collection "libraries"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }]
(mgcol/insert collection doc)
(is (= ({ :language "Clojure" } (mgcol/find-by-id collection doc-id [ :language ]))))))
(mc/insert db collection doc)
(is (= ({ :language "Clojure" }
(mc/find-by-id db collection doc-id [ :language ]))))))
(deftest find-partial-document-as-map-by-id-when-document-does-exist
(deftest find-partial-document-as-map-by-id-when-document-does-exist
(let [collection "libraries"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
fields [:data-store]
doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }
_ (mgcol/insert collection doc)
loaded (mgcol/find-map-by-id collection doc-id [ :language ])]
(is (= { :language "Clojure", :_id doc-id } loaded ))
)
)
_ (mc/insert db collection doc)
loaded (mc/find-map-by-id db collection doc-id [ :language ])]
(is (= { :language "Clojure", :_id doc-id } loaded ))))
;;
;; find
;;
;;
;; find
;;
(deftest find-full-document-when-collection-is-empty
(deftest find-full-document-when-collection-is-empty
(let [collection "regular_finders_docs"
cursor (mgcol/find collection)]
cursor (mc/find db collection)]
(is (empty? (iterator-seq cursor)))))
(deftest find-document-seq-when-collection-is-empty
(deftest find-document-seq-when-collection-is-empty
(let [collection "regular_finders_docs"]
(is (empty? (mgcol/find-seq collection)))))
(is (empty? (mc/find-seq db collection)))))
(deftest find-multiple-documents-when-collection-is-empty
(deftest find-multiple-documents-when-collection-is-empty
(let [collection "libraries"]
(is (empty? (mgcol/find collection { :language "Scala" })))))
(is (empty? (mc/find db collection { :language "Scala" })))))
(deftest find-multiple-maps-when-collection-is-empty
(deftest find-multiple-maps-when-collection-is-empty
(let [collection "libraries"]
(is (empty? (mgcol/find-maps collection { :language "Scala" })))))
(is (empty? (mc/find-maps db collection { :language "Scala" })))))
(deftest find-multiple-documents-by-regex
(deftest find-multiple-documents-by-regex
(let [collection "libraries"]
(mgcol/insert-batch collection [{ :language "Clojure", :name "monger" }
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Java", :name "nhibernate" }
{ :language "JavaScript", :name "sprout-core" }])
(is (= 2 (monger.core/count (mgcol/find collection { :language #"Java*" }))))))
(is (= 2 (monger.core/count (mc/find db collection { :language #"Java*" }))))))
(deftest find-multiple-documents
(deftest find-multiple-documents
(let [collection "libraries"]
(mgcol/insert-batch collection [{ :language "Clojure", :name "monger" }
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(is (= 1 (monger.core/count (mgcol/find collection { :language "Scala" }))))
(is (= 3 (.count (mgcol/find collection { :language "Clojure" }))))
(is (empty? (mgcol/find collection { :language "Java" })))))
(is (= 1 (monger.core/count (mc/find db collection { :language "Scala" }))))
(is (= 3 (.count (mc/find db collection { :language "Clojure" }))))
(is (empty? (mc/find db collection { :language "Java" })))))
(deftest find-document-specify-fields
(deftest find-document-specify-fields
(let [collection "libraries"
_ (mgcol/insert collection { :language "Clojure", :name "monger" })
result (mgcol/find collection { :language "Clojure"} [:language])]
_ (mc/insert db collection { :language "Clojure", :name "monger" })
result (mc/find db collection { :language "Clojure"} [:language])]
(is (= (seq [:_id :language]) (keys (mgcnv/from-db-object (.next result) true))))))
(deftest find-and-iterate-over-multiple-documents-the-hard-way
(deftest find-and-iterate-over-multiple-documents-the-hard-way
(let [collection "libraries"]
(mgcol/insert-batch collection [{ :language "Clojure", :name "monger" }
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(doseq [doc (take 3 (map (fn [dbo]
(mgcnv/from-db-object dbo true))
(mgcol/find-seq collection { :language "Clojure" })))]
(mc/find-seq db collection { :language "Clojure" })))]
(is (= "Clojure" (:language doc))))))
(deftest find-and-iterate-over-multiple-documents
(deftest find-and-iterate-over-multiple-documents
(let [collection "libraries"]
(mgcol/insert-batch collection [{ :language "Clojure", :name "monger" }
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(doseq [doc (take 3 (mgcol/find-maps collection { :language "Clojure" }))]
(doseq [doc (take 3 (mc/find-maps db collection { :language "Clojure" }))]
(is (= "Clojure" (:language doc))))))
(deftest find-multiple-maps
(deftest find-multiple-maps
(let [collection "libraries"]
(mgcol/insert-batch collection [{ :language "Clojure", :name "monger" }
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(is (= 1 (clojure.core/count (mgcol/find-maps collection { :language "Scala" }))))
(is (= 3 (.count (mgcol/find-maps collection { :language "Clojure" }))))
(is (empty? (mgcol/find-maps collection { :language "Java" })))
(is (empty? (mgcol/find-maps monger.core/*mongodb-database* collection { :language "Java" } [:language :name])))))
(is (= 1 (clojure.core/count (mc/find-maps db collection { :language "Scala" }))))
(is (= 3 (.count (mc/find-maps db collection { :language "Clojure" }))))
(is (empty? (mc/find-maps db collection { :language "Java" })))
(is (empty? (mc/find-maps db collection { :language "Java" } [:language :name])))))
(deftest find-multiple-partial-documents
(deftest find-multiple-partial-documents
(let [collection "libraries"]
(mgcol/insert-batch collection [{ :language "Clojure", :name "monger" }
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(let [scala-libs (mgcol/find collection { :language "Scala" } [:name])
clojure-libs (mgcol/find collection { :language "Clojure"} [:language])]
(let [scala-libs (mc/find db collection { :language "Scala" } [:name])
clojure-libs (mc/find db collection { :language "Clojure"} [:language])]
(is (= 1 (.count scala-libs)))
(is (= 3 (.count clojure-libs)))
(doseq [i clojure-libs]
(let [doc (mgcnv/from-db-object i true)]
(is (= (:language doc) "Clojure"))))
(is (empty? (mgcol/find collection { :language "Erlang" } [:name]))))))
(is (empty? (mc/find db collection { :language "Erlang" } [:name])))))))

View file

@ -1,16 +1,11 @@
(ns monger.test.result-test
(:import [com.mongodb BasicDBObject WriteResult WriteConcern] java.util.Date)
(:require [monger core collection conversion]
[monger.test.helper :as helper]
(:require [monger.core :as mg]
[monger.collection :as mc]
monger.result
monger.util
[clojure.test :refer :all]))
(helper/connect!)
;;
;; MongoCommandResult
;;
(deftest test-ok?
(let [result-that-is-not-ok-1 (doto (BasicDBObject.) (.put "ok" 0))
result-that-is-not-ok-2 (doto (BasicDBObject.) (.put "ok" "false"))
@ -41,14 +36,16 @@
(is (not (monger.result/updated-existing? input2)))
(is (not (monger.result/updated-existing? input3)))))
(deftest test-updated-existing?-with-write-result
(monger.collection/remove "libraries")
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(deftest test-updated-existing?-with-write-result
(mc/remove db "libraries")
(let [collection "libraries"
doc-id (monger.util/random-uuid)
date (Date.)
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(is (not (monger.result/updated-existing? (monger.collection/update collection { :language "Clojure" } doc :upsert true))))
(is (monger.result/updated-existing? (monger.collection/update collection { :language "Clojure" } doc :upsert true)))
(monger.result/updated-existing? (monger.collection/update collection { :language "Clojure" } modified-doc :multi false :upsert true))
(monger.collection/remove collection)))
(is (not (monger.result/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true}))))
(is (monger.result/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true})))
(monger.result/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true}))
(mc/remove db collection))))

View file

@ -1,38 +1,29 @@
(ns monger.test.ring.clojure-session-store-test
(:require [monger core util]
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[ring.middleware.session.store :refer :all]
[monger.ring.session-store :refer :all]))
(helper/connect!)
(defn purge-sessions
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(defn purge-sessions
[f]
(mc/remove "web_sessions")
(mc/remove "sessions")
(mc/remove db "sessions")
(f)
(mc/remove "web_sessions")
(mc/remove "sessions"))
(mc/remove db "sessions"))
(use-fixtures :each purge-sessions)
(use-fixtures :each purge-sessions)
(deftest test-reading-a-session-that-does-not-exist
(let [store (session-store)]
(deftest test-reading-a-session-that-does-not-exist
(let [store (session-store db "sessions")]
(is (= {} (read-session store "a-missing-key-1228277")))))
(deftest test-reading-a-session-that-does-not-exist-given-db
(let [db (monger.core/get-db)
store (session-store db "sessions")]
(is (= {} (read-session store "a-missing-key-1228277")))))
(deftest test-reading-a-session-that-does-exist
(let [store (session-store)
(deftest test-reading-a-session-that-does-exist
(let [store (session-store db "sessions")
sk (write-session store nil {:library "Monger"})
m (read-session store sk)]
(is sk)
@ -41,19 +32,8 @@
{:library "Monger"}))))
(deftest test-reading-a-session-that-does-exist-given-db
(let [db (monger.core/get-db)
store (session-store db "sessions")
sk (write-session store nil {:library "Monger"})
m (read-session store sk)]
(is sk)
(is (and (:_id m)))
(is (= (dissoc m :_id)
{:library "Monger"}))))
(deftest test-updating-a-session
(let [store (session-store "sessions")
(deftest test-updating-a-session
(let [store (session-store db "sessions")
sk1 (write-session store nil {:library "Monger"})
sk2 (write-session store sk1 {:library "Ring"})
m (read-session store sk2)]
@ -63,30 +43,8 @@
(is (= (dissoc m :_id)
{:library "Ring"}))))
(deftest test-updating-a-session-given-db
(let [db (monger.core/get-db)
store (session-store db "sessions")
sk1 (write-session store nil {:library "Monger"})
sk2 (write-session store sk1 {:library "Ring"})
m (read-session store sk2)]
(is (and sk1 sk2))
(is (and (:_id m)))
(is (= sk1 sk2))
(is (= (dissoc m :_id)
{:library "Ring"}))))
(deftest test-deleting-a-session
(let [store (session-store "sessions")
(deftest test-deleting-a-session
(let [store (session-store db "sessions")
sk (write-session store nil {:library "Monger"})]
(is (nil? (delete-session store sk)))
(is (= {} (read-session store sk)))))
(deftest test-deleting-a-session
(let [db (monger.core/get-db)
store (session-store db "sessions")
sk (write-session store nil {:library "Monger"})]
(is (nil? (delete-session store sk)))
(is (= {} (read-session store sk)))))
(is (= {} (read-session store sk))))))

View file

@ -1,38 +1,27 @@
(ns monger.test.ring.session-store-test
(:require [monger core util]
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[ring.middleware.session.store :refer :all]
[monger.ring.session-store :refer :all]))
(helper/connect!)
(defn purge-sessions
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(defn purge-sessions
[f]
(mc/remove "web_sessions")
(mc/remove "sessions")
(mc/remove db "sessions")
(f)
(mc/remove "web_sessions")
(mc/remove "sessions"))
(mc/remove db "sessions"))
(use-fixtures :each purge-sessions)
(use-fixtures :each purge-sessions)
(deftest test-reading-a-session-that-does-not-exist
(let [store (monger-store)]
(deftest test-reading-a-session-that-does-not-exist
(let [store (monger-store db "sessions")]
(is (= {} (read-session store "a-missing-key-1228277")))))
(deftest test-reading-a-session-that-does-not-exist-given-db
(let [db (monger.core/get-db)
store (monger-store db "sessions")]
(is (= {} (read-session store "a-missing-key-1228277")))))
(deftest test-reading-a-session-that-does-exist
(let [store (monger-store)
(deftest test-reading-a-session-that-does-exist
(let [store (monger-store db "sessions")
sk (write-session store nil {:library "Monger"})
m (read-session store sk)]
(is sk)
@ -40,20 +29,8 @@
(is (= (dissoc m :_id :date)
{:library "Monger"}))))
(deftest test-reading-a-session-that-does-exist-given-db
(let [db (monger.core/get-db)
store (monger-store db "sessions")
sk (write-session store nil {:library "Monger"})
m (read-session store sk)]
(is sk)
(is (and (:_id m) (:date m)))
(is (= (dissoc m :_id :date)
{:library "Monger"}))))
(deftest test-updating-a-session
(let [store (monger-store "sessions")
(deftest test-updating-a-session
(let [store (monger-store db "sessions")
sk1 (write-session store nil {:library "Monger"})
sk2 (write-session store sk1 {:library "Ring"})
m (read-session store sk2)]
@ -63,38 +40,15 @@
(is (= (dissoc m :_id :date)
{:library "Ring"}))))
(deftest test-updating-a-session-given-db
(let [db (monger.core/get-db)
store (monger-store db "sessions")
sk1 (write-session store nil {:library "Monger"})
sk2 (write-session store sk1 {:library "Ring"})
m (read-session store sk2)]
(is (and sk1 sk2))
(is (and (:_id m) (:date m)))
(is (= sk1 sk2))
(is (= (dissoc m :_id :date)
{:library "Ring"}))))
(deftest test-deleting-a-session
(let [store (monger-store "sessions")
(deftest test-deleting-a-session
(let [store (monger-store db "sessions")
sk (write-session store nil {:library "Monger"})]
(is (nil? (delete-session store sk)))
(is (= {} (read-session store sk)))))
(deftest test-deleting-a-session-given-db
(let [db (monger.core/get-db)
store (monger-store db "sessions")
sk (write-session store nil {:library "Monger"})]
(is (nil? (delete-session store sk)))
(is (= {} (read-session store sk)))))
(deftest test-reader-extensions
(deftest test-reader-extensions
(let [d (java.util.Date.)
oid (org.bson.types.ObjectId.)]
(binding [*print-dup* true]
(pr-str d)
(pr-str oid))))
(pr-str oid)))))

View file

@ -1,42 +1,35 @@
(ns monger.test.stress-test
(:import [com.mongodb Mongo DB DBCollection WriteResult DBObject WriteConcern DBCursor]
java.util.Date)
(:require monger.core
[monger.test.helper :as helper]
[clojure.test :refer :all]))
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.conversion :refer [to-db-object]]
[clojure.test :refer :all])
(:import [com.mongodb WriteConcern]
java.util.Date))
;;
;; Fixture functions
;;
(defn purge-collection
[collection-name, f]
(monger.collection/remove collection-name)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(defn purge-collection
[coll f]
(mc/remove db coll)
(f)
(monger.collection/remove collection-name))
(mc/remove db coll))
(defn purge-things-collection
(defn purge-things-collection
[f]
(purge-collection "things" f))
(use-fixtures :each purge-things-collection)
(use-fixtures :each purge-things-collection)
(monger.core/set-default-write-concern! WriteConcern/NORMAL)
;;
;; Tests
;;
(monger.core/set-default-write-concern! WriteConcern/NORMAL)
(deftest ^{:performance true} insert-large-batches-of-documents-without-object-ids
(doseq [n [1000 10000 100000]]
(deftest ^{:performance true} insert-large-batches-of-documents-without-object-ids
(doseq [n [10 100 1000 10000 20000]]
(let [collection "things"
docs (map (fn [i]
(monger.conversion/to-db-object { :title "Untitled" :created-at (Date.) :number i }))
(to-db-object { :title "Untitled" :created-at (Date.) :number i }))
(take n (iterate inc 1)))]
(monger.collection/remove collection)
(mc/remove db collection)
(println "Inserting " n " documents...")
(time (monger.collection/insert-batch collection docs))
(is (= n (monger.collection/count collection))))))
(time (mc/insert-batch db collection docs))
(is (= n (mc/count db collection)))))))

View file

@ -1,163 +1,169 @@
(ns monger.test.updating-test
(:import [com.mongodb WriteResult WriteConcern DBCursor DBObject]
(:import [com.mongodb WriteResult WriteConcern DBObject]
org.bson.types.ObjectId
java.util.Date)
(:require [monger core util]
(:require [monger.core :as mg]
[monger.collection :as mc]
[monger.util :as mu]
[monger.result :as mr]
[monger.test.helper :as helper]
[clojure.test :refer :all]
[monger.operators :refer :all]
[monger.test.fixtures :refer :all]
[monger.conversion :refer [to-db-object]]))
(helper/connect!)
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(defn purge-collections
[f]
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "libraries")
(f)
(mc/remove db "people")
(mc/remove db "docs")
(mc/remove db "things")
(mc/remove db "libraries"))
(use-fixtures :each purge-people purge-docs purge-things purge-libraries)
(use-fixtures :each purge-collections)
;;
;; update, save
;;
(deftest ^{:updating true} update-document-by-id-without-upsert
(deftest ^{:updating true} update-document-by-id-without-upsert
(let [collection "libraries"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
date (Date.)
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(mc/insert collection doc)
(is (= (doc (mc/find-by-id collection doc-id))))
(mc/update collection { :_id doc-id } { :language "Erlang" })
(is (= (modified-doc (mc/find-by-id collection doc-id))))))
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update db collection { :_id doc-id } { :language "Erlang" })
(is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id
(deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id
(let [collection "libraries"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
date (Date.)
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(mc/insert collection doc)
(is (= (doc (mc/find-by-id collection doc-id))))
(mc/update-by-id collection doc-id { :language "Erlang" })
(is (= (modified-doc (mc/find-by-id collection doc-id))))))
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update-by-id db collection doc-id { :language "Erlang" })
(is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id
(deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id
(let [collection "libraries"
doc-id (ObjectId.)
date (Date.)
doc { :created-at date :data-store "MongoDB" :language { :primary "Clojure" } :_id doc-id }
modified-doc { :created-at date :data-store "MongoDB" :language { :primary "Erlang" } :_id doc-id }]
(mc/insert collection doc)
(is (= (doc (mc/find-by-id collection doc-id))))
(mc/update-by-id collection doc-id { $set { "language.primary" "Erlang" }})
(is (= (modified-doc (mc/find-by-id collection doc-id))))))
(mc/insert db collection doc)
(is (= (doc (mc/find-by-id db collection doc-id))))
(mc/update-by-id db collection doc-id { $set { "language.primary" "Erlang" }})
(is (= (modified-doc (mc/find-by-id db collection doc-id))))))
(deftest ^{:updating true} update-multiple-documents
(deftest ^{:updating true} update-multiple-documents
(let [collection "libraries"]
(mc/insert collection { :language "Clojure", :name "monger" })
(mc/insert collection { :language "Clojure", :name "langohr" })
(mc/insert collection { :language "Clojure", :name "incanter" })
(mc/insert collection { :language "Scala", :name "akka" })
(is (= 3 (mc/count collection { :language "Clojure" })))
(is (= 1 (mc/count collection { :language "Scala" })))
(is (= 0 (mc/count collection { :language "Python" })))
(mc/update collection { :language "Clojure" } { $set { :language "Python" } } :multi true)
(is (= 0 (mc/count collection { :language "Clojure" })))
(is (= 1 (mc/count collection { :language "Scala" })))
(is (= 3 (mc/count collection { :language "Python" })))))
(mc/insert-batch db collection [{ :language "Clojure", :name "monger" }
{ :language "Clojure", :name "langohr" }
{ :language "Clojure", :name "incanter" }
{ :language "Scala", :name "akka" }])
(is (= 3 (mc/count db collection { :language "Clojure" })))
(is (= 1 (mc/count db collection { :language "Scala" })))
(is (= 0 (mc/count db collection { :language "Python" })))
(mc/update db collection { :language "Clojure" } { $set { :language "Python" } } {:multi true})
(is (= 0 (mc/count db collection { :language "Clojure" })))
(is (= 1 (mc/count db collection { :language "Scala" })))
(is (= 3 (mc/count db collection { :language "Python" })))))
(deftest ^{:updating true} save-a-new-document
(deftest ^{:updating true} save-a-new-document
(let [collection "people"
document {:name "Joe" :age 30}]
(is (mr/ok? (mc/save "people" document)))
(is (= 1 (mc/count collection)))))
(is (mr/ok? (mc/save db "people" document)))
(is (= 1 (mc/count db collection)))))
(deftest ^{:updating true} save-and-return-a-new-document
(deftest ^{:updating true} save-and-return-a-new-document
(let [collection "people"
document {:name "Joe" :age 30}
returned (mc/save-and-return "people" document)]
returned (mc/save-and-return db "people" document)]
(is (:_id returned))
(is (= document (dissoc returned :_id)))
(is (= 1 (mc/count collection)))))
(is (= 1 (mc/count db collection)))))
(deftest ^{:updating true} save-a-new-basic-db-object
(deftest ^{:updating true} save-a-new-basic-db-object
(let [collection "people"
doc (to-db-object {:name "Joe" :age 30})]
(is (nil? (monger.util/get-id doc)))
(mc/save monger.core/*mongodb-database* "people" doc WriteConcern/SAFE)
(is (not (nil? (monger.util/get-id doc))))))
(is (nil? (mu/get-id doc)))
(mc/save db "people" doc WriteConcern/SAFE)
(is (not (nil? (mu/get-id doc))))))
(deftest ^{:updating true} update-an-existing-document-using-save
(deftest ^{:updating true} update-an-existing-document-using-save
(let [collection "people"
doc-id "people-1"
document { :_id doc-id, :name "Joe", :age 30 }]
(is (mr/ok? (mc/insert "people" document)))
(is (= 1 (mc/count collection)))
(mc/save collection { :_id doc-id, :name "Alan", :age 40 })
(is (= 1 (mc/count collection { :name "Alan", :age 40 })))))
(is (mr/ok? (mc/insert db collection document)))
(is (= 1 (mc/count db collection)))
(mc/save db collection { :_id doc-id, :name "Alan", :age 40 })
(is (= 1 (mc/count db collection { :name "Alan", :age 40 })))))
(deftest ^{:updating true} update-an-existing-document-using-save-and-return
(deftest ^{:updating true} update-an-existing-document-using-save-and-return
(let [collection "people"
document (mc/insert-and-return "people" {:name "Joe" :age 30})
document (mc/insert-and-return db collection {:name "Joe" :age 30})
doc-id (:_id document)
updated (mc/save-and-return collection {:_id doc-id :name "Alan" :age 40})]
updated (mc/save-and-return db collection {:_id doc-id :name "Alan" :age 40})]
(is (= {:_id doc-id :name "Alan" :age 40} updated))
(is (= 1 (mc/count collection)))
(is (= 1 (mc/count collection {:name "Alan" :age 40})))))
(is (= 1 (mc/count db collection)))
(is (= 1 (mc/count db collection {:name "Alan" :age 40})))))
(deftest ^{:updating true} set-an-attribute-on-existing-document-using-update
(deftest ^{:updating true} set-an-attribute-on-existing-document-using-update
(let [collection "people"
doc-id (monger.util/object-id)
doc-id (mu/object-id)
document { :_id doc-id, :name "Joe", :age 30 }]
(is (mr/ok? (mc/insert "people" document)))
(is (= 1 (mc/count collection)))
(is (= 0 (mc/count collection { :has_kids true })))
(mc/update collection { :_id doc-id } { $set { :has_kids true } })
(is (= 1 (mc/count collection { :has_kids true })))))
(is (mr/ok? (mc/insert db collection document)))
(is (= 1 (mc/count db collection)))
(is (= 0 (mc/count db collection { :has_kids true })))
(mc/update db collection { :_id doc-id } { $set { :has_kids true } })
(is (= 1 (mc/count db collection { :has_kids true })))))
(deftest ^{:updating true} increment-multiple-fields-using-exists-operator-and-update
(deftest ^{:updating true} increment-multiple-fields-using-exists-operator-and-update
(let [collection "matches"
doc-id (monger.util/object-id)
doc-id (mu/object-id)
document { :_id doc-id :abc 0 :def 10 }]
(mc/remove collection)
(is (mr/ok? (mc/insert collection document)))
(is (= 1 (mc/count collection {:abc {$exists true} :def {$exists true}})))
(mc/update collection {:abc {$exists true} :def {$exists true}} {$inc {:abc 1 :def 0}})
(is (= 1 (mc/count collection { :abc 1 })))))
(mc/remove db collection)
(is (mr/ok? (mc/insert db collection document)))
(is (= 1 (mc/count db collection {:abc {$exists true} :def {$exists true}})))
(mc/update db collection {:abc {$exists true} :def {$exists true}} {$inc {:abc 1 :def 0}})
(is (= 1 (mc/count db collection { :abc 1 })))))
(deftest ^{:updating true} upsert-a-document-using-update
(deftest ^{:updating true} upsert-a-document-using-update
(let [collection "libraries"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
date (Date.)
doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id }
modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }]
(is (not (mr/updated-existing? (mc/update collection { :language "Clojure" } doc :upsert true))))
(is (= 1 (mc/count collection)))
(is (mr/updated-existing? (mc/update collection { :language "Clojure" } modified-doc :multi false :upsert true)))
(is (= 1 (mc/count collection)))
(is (= (modified-doc (mc/find-by-id collection doc-id))))
(mc/remove collection)))
(is (not (mr/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true}))))
(is (= 1 (mc/count db collection)))
(is (mr/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true})))
(is (= 1 (mc/count db collection)))
(is (= (modified-doc (mc/find-by-id db collection doc-id))))
(mc/remove db collection)))
(deftest ^{:updating true} upsert-a-document-using-upsert
(deftest ^{:updating true} upsert-a-document-using-upsert
(let [collection "libraries"
doc-id (monger.util/random-uuid)
doc-id (mu/random-uuid)
date (Date.)
doc {:created-at date :data-store "MongoDB" :language "Clojure" :_id doc-id}
modified-doc {:created-at date :data-store "MongoDB" :language "Erlang" :_id doc-id}]
(mc/remove collection)
(is (not (mr/updated-existing? (mc/upsert collection {:language "Clojure"} doc))))
(is (= 1 (mc/count collection)))
(is (mr/updated-existing? (mc/upsert collection {:language "Clojure"} modified-doc :multi false)))
(is (= 1 (mc/count collection)))
(is (= (modified-doc (mc/find-by-id collection doc-id))))
(mc/remove collection)))
(mc/remove db collection)
(is (not (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} doc))))
(is (= 1 (mc/count db collection)))
(is (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} modified-doc {:multi false})))
(is (= 1 (mc/count db collection)))
(is (= (modified-doc (mc/find-by-id db collection doc-id))))
(mc/remove db collection))))