Require connection/db/gridfs as an explicit argument (initial pass)

This commit is contained in:
Michael Klishin 2014-05-10 16:27:52 -04:00
parent 04e6c5bce6
commit 9ad38a9e7a
10 changed files with 292 additions and 517 deletions

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,24 +25,6 @@
(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
;;

View file

@ -25,7 +25,7 @@
* http://clojuremongodb.info/articles/aggregation.html"
(:refer-clojure :exclude [find remove count drop distinct empty?])
(:import [com.mongodb Mongo DB DBCollection WriteResult DBObject WriteConcern
DBCursor MapReduceCommand MapReduceCommand$OutputType]
DBCursor MapReduceCommand MapReduceCommand$OutputType]
[java.util List Map]
[clojure.lang IPersistentMap ISeq]
org.bson.types.ObjectId)
@ -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,33 +143,27 @@
This function returns clojure Seq of Maps.
If you want to work directly with DBObject, use find.
"
([^String collection]
(with-open [dbc (find collection)]
(map (fn [x] (from-db-object x true)) dbc)))
([^String collection ^Map ref]
(with-open [dbc (find collection ref)]
([^DB db ^String coll]
(with-open [dbc (find db coll)]
(map (fn [x] (from-db-object x true)) dbc)))
([^String collection ^Map ref fields]
(with-open [dbc (find collection ref fields)]
([^DB db ^String coll ^Map ref]
(with-open [dbc (find db coll 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)]
([^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)]
(seq dbc)))
([^String collection ^Map ref]
(with-open [dbc (find collection 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)]
(seq dbc))))
([^DB db ^String coll]
(with-open [dbc (find db coll)]
(seq dbc)))
([^DB db ^String coll ^Map ref]
(with-open [dbc (find db coll ref)]
(seq dbc)))
([^DB db ^String coll ^Map ref fields]
(with-open [dbc (find db coll ref fields)]
(seq dbc))))
;;
;; monger.collection/find-one
@ -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,21 +346,22 @@
;; 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
multi false
write-concern monger.core/*mongodb-write-concern*}}]
(.update (.getCollection monger.core/*mongodb-database* (name collection))
(to-db-object conditions)
(to-db-object document)
upsert
multi
write-concern)))
[^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 db (name coll))
(to-db-object conditions)
(to-db-object document)
upsert
multi
write-concern))
(defn ^WriteResult upsert
"Performs an upsert.
@ -405,16 +370,18 @@
sets :upsert to true.
See monger.collection/update documentation"
[^String collection ^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))
[^DB db ^String coll ^Map conditions ^Map document & {:keys [multi write-concern]
:or {multi false
write-concern monger.core/*mongodb-write-concern*}}]
(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
write-concern monger.core/*mongodb-write-concern*}}]
[^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
@ -435,18 +402,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 +428,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 +445,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]
(check-not-nil! id "id must not be nil")
(let [coll (.getCollection db (name collection))]
(.remove coll (to-db-object {:_id id})))))
[^DB db ^String coll id]
(check-not-nil! id "id must not be nil")
(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 +480,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 +509,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 +538,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 +548,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 +567,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 +584,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 +596,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 +617,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 +631,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 +642,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 +662,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

@ -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,11 +31,7 @@
(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*)
(def ^:dynamic ^WriteConcern *mongodb-write-concern* WriteConcern/ACKNOWLEDGED)
;;
@ -46,13 +42,13 @@
"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,10 +75,8 @@
(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
@ -90,44 +84,14 @@
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)))
(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)))
[^MongoClient conn ^String db]
(.dropDatabase conn db))
(defn server-address
([^String hostname]
@ -135,7 +99,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,56 +128,26 @@
(.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)
@ -236,37 +169,21 @@
(when (and user pwd)
(when-not (authenticate conn 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))))
(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)))
@ -295,8 +212,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,6 +18,7 @@
[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]))
@ -41,37 +42,23 @@
(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 query]
(.getFileList fs query)))
[^GridFS fs query]
(.getFileList fs query))
(def ^{:private true} converter
(fpartial from-db-object true))
(defn files-as-maps
([]
(map converter (all-files)))
([query]
(map converter (all-files (to-db-object query))))
([^GridFS fs query]
(map converter (all-files fs (to-db-object query)))))
[^GridFS fs query]
(map converter (all-files fs (to-db-object query))))
;;
@ -141,48 +128,26 @@
;; 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-one
[^GridFS fs query]
(.findOne fs (to-db-object query)))
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-maps
[^GridFS fs query]
(map converter (find fs query)))
(defn find-one-as-map
[^GridFS fs query]
(converter (find-one fs 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)))
;; 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-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

@ -132,10 +132,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
(find {})
(sort {:created_at 1}))]
(vec (map :_id xs))))))
(let [xs (with-collection db migrations-collection
(find {})
(sort {:created_at 1}))]
(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))