Merge branch 'multi-database-support'

This is a backwards-compatible way of making most of functions in monger.collection
and monger.gridfs support explicitly passed database objects. In some cases
we cannot do that because of Clojure compiler limitations on # of arities
each function can have. For those cases, see monger.core/with-db, monger.core/with-grifs
and so on.

Fixes #4.
This commit is contained in:
Michael S. Klishin 2012-01-29 08:00:00 +04:00
commit 2a250208da
3 changed files with 140 additions and 64 deletions

View file

@ -32,11 +32,14 @@
(monger.collection/insert \"people\" { :name \"Joe\", :age 30, WriteConcern/SAFE })
"
([^String collection, ^DBObject document]
([^String collection ^DBObject document]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.insert ^DBCollection coll ^DBObject (to-db-object document) ^WriteConcern monger.core/*mongodb-write-concern*)))
([^String collection, ^DBObject document, ^WriteConcern concern]
([^String collection ^DBObject document ^WriteConcern concern]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.insert ^DBCollection coll ^DBObject (to-db-object document) ^WriteConcern concern)))
([^DB db ^String collection ^DBObject document ^WriteConcern concern]
(let [^DBCollection coll (.getCollection db collection)]
(.insert ^DBCollection coll ^DBObject (to-db-object document) ^WriteConcern concern))))
@ -55,6 +58,9 @@
(.insert ^DBCollection coll ^List (to-db-object documents) ^WriteConcern monger.core/*mongodb-write-concern*)))
([^String collection, ^List documents, ^WriteConcern concern]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.insert ^DBCollection coll ^List (to-db-object documents) ^WriteConcern concern)))
([^DB db ^String collection, ^List documents, ^WriteConcern concern]
(let [^DBCollection coll (.getCollection db collection)]
(.insert ^DBCollection coll ^List (to-db-object documents) ^WriteConcern concern))))
;;
@ -80,12 +86,16 @@
([^String collection]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.find coll)))
([^String collection, ^Map ref]
([^String collection ^Map ref]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.find ^DBCollection coll ^DBObject (to-db-object ref))))
([^String collection, ^Map ref, ^List fields]
([^String collection ^Map ref ^List fields]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)
map-of-fields (fields-to-db-object fields)]
(.find ^DBCollection coll ^DBObject (to-db-object ref) ^DBObject (to-db-object map-of-fields))))
([^DB db ^String collection ^Map ref ^List fields]
(let [^DBCollection coll (.getCollection db collection)
map-of-fields (fields-to-db-object fields)]
(.find ^DBCollection coll ^DBObject (to-db-object ref) ^DBObject (to-db-object map-of-fields)))))
(defn ^ISeq find-maps
@ -95,19 +105,23 @@
"
([^String collection]
(map (fn [x] (from-db-object x true)) (find collection)))
([^String collection, ^Map ref]
([^String collection ^Map ref]
(map (fn [x] (from-db-object x true)) (find collection ref)))
([^String collection, ^Map ref, ^List fields]
(map (fn [x] (from-db-object x true)) (find collection ref fields))))
([^String collection ^Map ref ^List fields]
(map (fn [x] (from-db-object x true)) (find collection ref fields)))
([^DB db ^String collection ^Map ref ^List fields]
(map (fn [x] (from-db-object x true)) (find db collection ref fields))))
(defn ^ISeq find-seq
"Queries for objects in this collection, returns ISeq of DBObjects."
([^String collection]
(seq (find collection)))
([^String collection, ^Map ref]
([^String collection ^Map ref]
(seq (find collection ref)))
([^String collection, ^Map ref, ^List fields]
(seq (find collection ref fields))))
([^String collection ^Map ref ^List fields]
(seq (find collection ref fields)))
([^DB db ^String collection ^Map ref ^List fields]
(seq (find db collection ref fields))))
;;
;; monger.collection/find-one
@ -125,21 +139,25 @@
(mgcol/find-one collection { :language \"Clojure\" } [:language])
"
([^String collection, ^Map ref]
([^String collection ^Map ref]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.findOne ^DBCollection coll ^DBObject (to-db-object ref))))
([^String collection, ^Map ref, ^List fields]
([^String collection ^Map ref ^List fields]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)
map-of-fields (fields-to-db-object fields)]
(.findOne ^DBCollection coll ^DBObject (to-db-object ref) ^DBObject (to-db-object map-of-fields))))
([^DB db ^String collection ^Map ref ^List fields]
(let [^DBCollection coll (.getCollection db collection)
map-of-fields (fields-to-db-object fields)]
(.findOne ^DBCollection coll ^DBObject (to-db-object ref) ^DBObject (to-db-object map-of-fields)))))
(defn ^IPersistentMap find-one-as-map
"Returns a single object converted to Map from this collection matching the query."
([^String collection, ^Map ref]
([^String collection ^Map ref]
(from-db-object ^DBObject (find-one collection ref) true))
([^String collection, ^Map ref, keywordize]
([^String collection ^Map ref keywordize]
(from-db-object ^DBObject (find-one collection ref) keywordize))
([^String collection, ^Map ref, ^List fields, keywordize]
([^String collection ^Map ref ^List fields keywordize]
(from-db-object ^DBObject (find-one collection ref fields) keywordize)))
@ -159,18 +177,20 @@
;; Note that _id field is always returned.
(mgcol/find-one-by-id collection \"4ef45ab4744e9fd632640e2d\" [:language])
"
([^String collection, id]
([^String collection id]
(find-one collection { :_id id }))
([^String collection, id, ^List fields]
(find-one collection { :_id id } fields)))
([^String collection id ^List fields]
(find-one collection { :_id id } fields))
([^DB db ^String collection id ^List fields]
(find-one db collection { :_id id } fields)))
(defn ^IPersistentMap find-map-by-id
"Returns a single object, converted to map with matching _id field."
([^String collection, id]
([^String collection id]
(from-db-object ^DBObject (find-one-as-map collection { :_id id }) true))
([^String collection, id, keywordize]
([^String collection id keywordize]
(from-db-object ^DBObject (find-one-as-map collection { :_id id }) keywordize))
([^String collection, id, ^List fields, keywordize]
([^String collection id ^List fields keywordize]
(from-db-object ^DBObject (find-one-as-map collection { :_id id } fields) keywordize)))
@ -196,8 +216,11 @@
(^long [^String collection]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.count coll)))
(^long [^String collection, ^Map conditions]
(^long [^String collection ^Map conditions]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.count coll (to-db-object conditions))))
(^long [^DB db ^String collection ^Map conditions]
(let [^DBCollection coll (.getCollection db collection)]
(.count coll (to-db-object conditions)))))
(defn any?
@ -212,8 +235,10 @@
"
([^String collection]
(> (count collection) 0))
([^String collection, ^Map conditions]
(> (count collection conditions) 0)))
([^String collection ^Map conditions]
(> (count collection conditions) 0))
([^DB db ^String collection ^Map conditions]
(> (count db collection conditions) 0)))
(defn empty?
@ -223,7 +248,9 @@
(mgcol/empty? \"things\")
"
([^String collection]
(= (count collection) 0)))
(= (count collection) 0))
([^DB db ^String collection]
(= (count db collection {}) 0)))
;; monger.collection/update
@ -260,7 +287,7 @@
(monger.collection/update \"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, multi false, write-concern monger.core/*mongodb-write-concern* } }]
[^String collection ^Map conditions ^Map document & { :keys [upsert multi write-concern] :or { upsert false, multi false, write-concern monger.core/*mongodb-write-concern* } }]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.update coll (to-db-object conditions) (to-db-object document) upsert multi write-concern)))
@ -277,11 +304,14 @@
(monger.collection/save \"people\" { :first_name \"Ian\" :last_name \"Gillan\" })
"
([^String collection, ^Map document]
([^String collection ^Map document]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.save coll (to-db-object document) monger.core/*mongodb-write-concern*)))
([^String collection, ^Map document, ^WriteConcern write-concern]
([^String collection ^Map document ^WriteConcern write-concern]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.save coll document write-concern)))
([^DB db ^String collection ^Map document ^WriteConcern write-concern]
(let [^DBCollection coll (.getCollection db collection)]
(.save coll document write-concern))))
@ -300,8 +330,11 @@
([^String collection]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.remove coll (to-db-object {}))))
([^String collection, ^Map conditions]
([^String collection ^Map conditions]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.remove coll (to-db-object conditions))))
([^DB db ^String collection ^Map conditions]
(let [^DBCollection coll (.getCollection db collection)]
(.remove coll (to-db-object conditions)))))
@ -319,9 +352,12 @@
(monger.collection/create-index collection { \"language\" 1 })
"
[^String collection, ^Map keys]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.createIndex coll (to-db-object keys))))
([^String collection ^Map keys]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.createIndex coll (to-db-object keys))))
([^DB db ^String collection ^Map keys]
(let [^DBCollection coll (.getCollection db collection)]
(.createIndex coll (to-db-object keys)))))
;;
@ -368,14 +404,19 @@
(defn drop-index
"Drops an index from this collection."
[^String collection, ^String name]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.dropIndex coll name)))
([^String collection ^String name]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.dropIndex coll name)))
([^DB db ^String collection ^String name]
(let [^DBCollection coll (.getCollection db collection)]
(.dropIndex coll name))))
(defn drop-indexes
"Drops an indices from this collection."
[^String collection]
(.dropIndexes ^DBCollection (.getCollection monger.core/*mongodb-database* collection)))
([^String collection]
(.dropIndexes ^DBCollection (.getCollection monger.core/*mongodb-database* collection)))
([^DB db ^String collection]
(.dropIndexes ^DBCollection (.getCollection db collection))))
;;
@ -390,13 +431,17 @@
(monger.collection/exists? \"coll\")
"
[^String collection]
(.collectionExists monger.core/*mongodb-database* collection))
([^String collection]
(.collectionExists monger.core/*mongodb-database* collection))
([^DB db ^String collection]
(.collectionExists db collection)))
(defn create
"Creates a collection with a given name and options."
[^String collection, ^Map options]
(.createCollection monger.core/*mongodb-database* collection (to-db-object options)))
([^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))))
(defn drop
"Deletes collection from database.
@ -405,9 +450,12 @@
(monger.collection/drop \"collection-to-drop\")
"
[^String collection]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.drop coll)))
([^String collection]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.drop coll)))
([^DB db ^String collection]
(let [^DBCollection coll (.getCollection db collection)]
(.drop coll))))
(defn rename
"Renames collection.
@ -419,8 +467,11 @@
([^String from, ^String to]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* from)]
(.rename coll to)))
([^String from, ^String to, ^Boolean drop-target]
([^String from ^String to ^Boolean drop-target]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* from)]
(.rename coll to drop-target)))
([^DB db ^String from ^String to ^Boolean drop-target]
(let [^DBCollection coll (.getCollection db from)]
(.rename coll to drop-target))))
;;
@ -443,11 +494,14 @@
(defn distinct
"Finds distinct values for a key"
([^String collection, ^String key]
([^String collection ^String key]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.distinct coll ^String (to-db-object key))))
([^String collection, ^String key, ^Map query]
([^String collection ^String key ^Map query]
(let [^DBCollection coll (.getCollection monger.core/*mongodb-database* collection)]
(.distinct coll ^String (to-db-object key) ^DBObject (to-db-object query))))
([^DB db ^String collection ^String key ^Map query]
(let [^DBCollection coll (.getCollection db collection)]
(.distinct coll ^String (to-db-object key) ^DBObject (to-db-object query)))))

View file

@ -3,7 +3,7 @@
(:require [monger.core]
[clojure.java.io :as io])
(:use [monger.conversion])
(:import [com.mongodb DBObject]
(:import [com.mongodb DB DBObject]
[com.mongodb.gridfs GridFS GridFSInputFile]
[java.io InputStream File]))
@ -30,17 +30,23 @@
([]
(remove {}))
([query]
(.remove ^GridFS monger.core/*mongodb-gridfs* ^DBObject (to-db-object query))))
(.remove ^GridFS monger.core/*mongodb-gridfs* ^DBObject (to-db-object query)))
([^GridFS fs query]
(.remove fs ^DBObject (to-db-object query))))
(defn remove-all
[]
(remove {}))
([]
(remove {}))
([^GridFS fs]
(remove fs {})))
(defn all-files
([]
(.getFileList ^GridFS monger.core/*mongodb-gridfs*))
([query]
(.getFileList ^GridFS monger.core/*mongodb-gridfs* query)))
(.getFileList ^GridFS monger.core/*mongodb-gridfs* query))
([^GridFS fs query]
(.getFileList fs query)))
(defprotocol GridFSInputFileFactory

View file

@ -30,6 +30,13 @@
(is (monger.result/ok? (mgcol/insert "people" doc)))
(is (= 1 (mgcol/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? (mgcol/insert monger.core/*mongodb-database* "people" doc WriteConcern/SAFE))))
(is (= 5 (mgcol/count collection)))))
(deftest insert-a-basic-document-without-id-and-with-explicit-write-concern
(let [collection "people"
doc { :name "Joe", :age 30 }]
@ -68,6 +75,13 @@
(is (monger.result/ok? (mgcol/insert-batch "people" docs WriteConcern/NORMAL)))
(is (= 2 (mgcol/count collection)))))
(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? (mgcol/insert-batch monger.core/*mongodb-database* "people" docs WriteConcern/NORMAL))))
(is (= 88 (mgcol/count collection)))))
@ -84,12 +98,12 @@
{ :language "Scala", :name "akka" }] )
(is (= 4 (mgcol/count collection)))
(is (mgcol/any? collection))
(is (= 3 (mgcol/count collection { :language "Clojure" })))
(is (mgcol/any? collection { :language "Clojure" }))
(is (= 3 (mgcol/count monger.core/*mongodb-database* collection { :language "Clojure" })))
(is (mgcol/any? monger.core/*mongodb-database* collection { :language "Clojure" }))
(is (= 1 (mgcol/count collection { :language "Scala" })))
(is (mgcol/any? collection { :language "Scala" }))
(is (= 0 (mgcol/count collection { :language "Python" })))
(is (not (mgcol/any? collection { :language "Python" })))))
(is (= 0 (mgcol/count monger.core/*mongodb-database* collection { :language "Python" })))
(is (not (mgcol/any? monger.core/*mongodb-database* collection { :language "Python" })))))
(deftest remove-all-documents-from-collection
@ -306,7 +320,8 @@
{ :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 collection { :language "Java" })))
(is (empty? (mgcol/find-maps monger.core/*mongodb-database* collection { :language "Java" } [:language :name])))))
@ -367,7 +382,7 @@
(let [collection "people"
doc (mgcnv/to-db-object { :name "Joe", :age 30 })]
(is (nil? (monger.util/get-id doc)))
(mgcol/save "people" doc)
(mgcol/save monger.core/*mongodb-database* "people" doc WriteConcern/SAFE)
(is (not (nil? (monger.util/get-id doc))))))
@ -474,7 +489,7 @@
{ :state "IL" :quantity 3 :price 5.50 }]
expected [{:_id "CA", :value 204.9} {:_id "IL", :value 39.5} {:_id "NY", :value 697.0}]]
(deftest basic-inline-map-reduce-example
(mgcol/remove collection)
(mgcol/remove monger.core/*mongodb-database* collection {})
(is (mgres/ok? (mgcol/insert-batch collection batch)))
(let [output (mgcol/map-reduce collection mapper reducer nil MapReduceCommand$OutputType/INLINE {})
results (mgcnv/from-db-object ^DBObject (.results ^MapReduceOutput output) true)]
@ -482,7 +497,7 @@
(is (= expected results))))
(deftest basic-map-reduce-example-that-replaces-named-collection
(mgcol/remove collection)
(mgcol/remove monger.core/*mongodb-database* collection {})
(is (mgres/ok? (mgcol/insert-batch collection batch)))
(let [output (mgcol/map-reduce collection mapper reducer "mr_outputs" {})
results (mgcnv/from-db-object ^DBObject (.results ^MapReduceOutput output) true)]
@ -495,7 +510,7 @@
(.drop ^MapReduceOutput output)))
(deftest basic-map-reduce-example-that-merged-results-into-named-collection
(mgcol/remove collection)
(mgcol/remove monger.core/*mongodb-database* collection {})
(is (mgres/ok? (mgcol/insert-batch collection batch)))
(mgcol/map-reduce collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})
(is (mgres/ok? (mgcol/insert collection { :state "OR" :price 17.95 :quantity 4 })))
@ -520,7 +535,7 @@
{ :state "CA" :quantity 2 :price 2.95 }
{ :state "IL" :quantity 3 :price 5.50 }]]
(mgcol/insert-batch collection batch)
(is (= ["CA" "IL" "NY"] (sort (mgcol/distinct collection :state))))
(is (= ["CA" "IL" "NY"] (sort (mgcol/distinct monger.core/*mongodb-database* collection :state {}))))
(is (= ["CA" "NY"] (sort (mgcol/distinct collection :state { :price { $gt 100.00 } }))))))
@ -536,11 +551,12 @@
(let [collection "things"
_ (mgcol/insert collection { :language "Clojure", :name "langohr" })]
(is (mgcol/any? "things"))
(is (mgcol/any? "things" {:language "Clojure"}))))
(is (mgcol/any? monger.core/*mongodb-database* "things" {:language "Clojure"}))))
(deftest empty-on-empty-collection
(let [collection "things"]
(is (mgcol/empty? collection))))
(is (mgcol/empty? collection))
(is (mgcol/empty? monger.core/*mongodb-database* collection))))
(deftest empty-on-non-empty-collection
(let [collection "things"