remove reflection warnings

This commit is contained in:
George Narroway 2019-11-19 16:01:21 +08:00
parent b7ba5599bf
commit db93922521
5 changed files with 189 additions and 190 deletions

View file

@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. This change
### Added ### Added
- list collections - list collections
- start session - start session
- remove reflection warnings
## [0.3.1] ## [0.3.1]
### Added ### Added

View file

@ -1,7 +1,7 @@
(ns mongo-driver-3.client (ns mongo-driver-3.client
(:refer-clojure :exclude [find]) (:refer-clojure :exclude [find])
(:require [mongo-driver-3.collection :as mc]) (:require [mongo-driver-3.collection :as mc])
(:import (com.mongodb.client MongoClients MongoClient) (:import (com.mongodb.client MongoClients MongoClient ClientSession MongoDatabase)
(com.mongodb ConnectionString ClientSessionOptions TransactionOptions) (com.mongodb ConnectionString ClientSessionOptions TransactionOptions)
(java.util.concurrent TimeUnit))) (java.util.concurrent TimeUnit)))
@ -30,26 +30,69 @@
[^MongoClient client] [^MongoClient client]
(.close client)) (.close client))
(defn list-collections
"Lists collections in a database, returning as a seq of maps unless otherwise configured.
Arguments:
- `db` a MongoDatabase
- `opts` (optional), a map of:
- `:name-only?` returns just the string names
- `:keywordize?` keywordize the keys of return results, default: true. Only applicable if `:name-only?` is false.
- `:raw?` return the mongo iterable directly instead of processing into a seq, default: false
- `:session` a ClientSession"
([^MongoDatabase db] (list-collections db {}))
([^MongoDatabase db {:keys [raw? keywordize? ^ClientSession session] :or {keywordize? true}}]
(let [it (if session
(.listCollections db session)
(.listCollections db))]
(if-not raw?
(map #(mc/from-document % keywordize?) (seq it))
it))))
(defn list-collection-names
"Lists collection names in a database, returning as a seq of strings unless otherwise configured.
Arguments:
- `db` a MongoDatabase
- `opts` (optional), a map of:
- `:raw?` return the mongo MongoIterable directly instead of processing into a seq, default: false
- `:session` a ClientSession"
([^MongoDatabase db] (list-collection-names db {}))
([^MongoDatabase db opts]
(let [it (if-let [^ClientSession session (:session opts)]
(.listCollectionNames db session)
(.listCollectionNames db))]
(if-not (:raw? opts)
(seq it)
it))))
(defn ->TransactionOptions (defn ->TransactionOptions
"Coerces options map into a TransactionOptions." "Coerces options map into a TransactionOptions. See `start-session` for usage."
[{:keys [read-concern read-preference max-commit-time-ms] :as opts}] [{:keys [max-commit-time-ms] :as opts}]
(-> (TransactionOptions/builder) (let [rp (mc/->ReadPreference opts)
(#(if max-commit-time-ms (.maxCommitTime % max-commit-time-ms (TimeUnit/MILLISECONDS)) %)) rc (mc/->ReadConcern opts)
(#(if-let [rp (mc/->ReadPreference read-preference)] (.readPreference % rp) %)) wc (mc/->WriteConcern opts)]
(#(if-let [rc (mc/->ReadConcern read-concern)] (.readConcern % rc) %))
(#(if-let [wc (mc/->WriteConcern opts)] (.writeConcern % wc) %)) (when (some some? [max-commit-time-ms rp rc wc])
(.build))) (cond-> (TransactionOptions/builder)
max-commit-time-ms (.maxCommitTime max-commit-time-ms (TimeUnit/MILLISECONDS))
rp (.readPreference rp)
rc (.readConcern rc)
wc (.writeConcern wc)
true (.build)))))
(defn ->ClientSessionOptions (defn ->ClientSessionOptions
"Coerces an options map into a ClientSessionOptions. "Coerces an options map into a ClientSessionOptions See `start-session` for usage.
See `start-session` for usage" See `start-session` for usage"
[{:keys [client-session-options causally-consistent?] :as opts}] [{:keys [client-session-options causally-consistent?] :as opts}]
(let [trans-opts (->TransactionOptions opts)] (let [trans-opts (->TransactionOptions opts)]
(-> (if client-session-options (ClientSessionOptions/builder client-session-options) (ClientSessionOptions/builder)) (cond-> (if client-session-options (ClientSessionOptions/builder client-session-options) (ClientSessionOptions/builder))
(.defaultTransactionOptions trans-opts) trans-opts (.defaultTransactionOptions trans-opts)
(#(if (some? causally-consistent?) (.causallyConsistent % causally-consistent?) %)) (some? causally-consistent?) (.causallyConsistent causally-consistent?)
(.build)))) true (.build))))
(defn start-session (defn start-session
"Creates a client session. "Creates a client session.
@ -75,48 +118,10 @@
- `:write-concern/journal?` If true, block until write operations have been committed to the journal. - `:write-concern/journal?` If true, block until write operations have been committed to the journal.
- `:client-session-options` a ClientSessionOptions, for configuring directly. If specified, any - `:client-session-options` a ClientSessionOptions, for configuring directly. If specified, any
other [preceding] query options will be applied to it." other [preceding] query options will be applied to it."
([client] (start-session client {})) ([^MongoClient client] (start-session client {}))
([client opts] ([^MongoClient client opts]
(.startSession client (->ClientSessionOptions opts)))) (.startSession client (->ClientSessionOptions opts))))
(defn collections
"Lists collections in a database, returning as a seq of maps unless otherwise configured.
Arguments:
- `db` a MongoDatabase
- `opts` (optional), a map of:
- `:name-only?` returns just the string names
- `:keywordize?` keywordize the keys of return results, default: true. Only applicable if `:name-only?` is false.
- `:raw?` return the mongo iterable directly instead of processing into a seq, default: false
- `:session` a ClientSession"
([db] (collections db {}))
([db {:keys [raw? keywordize? session] :or {keywordize? true}}]
(let [it (if session
(.listCollections db session)
(.listCollections db))]
(if-not raw?
(map #(mc/from-document % keywordize?) (seq it))
it))))
(defn collection-names
"Lists collection names in a database, returning as a seq of strings unless otherwise configured.
Arguments:
- `db` a MongoDatabase
- `opts` (optional), a map of:
- `:raw?` return the mongo MongoIterable directly instead of processing into a seq, default: false
- `:session` a ClientSession"
([db] (collection-names db {}))
([db opts]
(let [it (if-let [session (:session opts)]
(.listCollectionNames db session)
(.listCollectionNames db))]
(if-not (:raw? opts)
(seq it)
it))))
;;; Utility ;;; Utility
(defn connect-to-db (defn connect-to-db

View file

@ -2,7 +2,7 @@
(:refer-clojure :exclude [find empty? drop]) (:refer-clojure :exclude [find empty? drop])
(:import (clojure.lang Ratio Keyword Named IPersistentMap) (:import (clojure.lang Ratio Keyword Named IPersistentMap)
(com.mongodb ReadConcern ReadPreference WriteConcern MongoNamespace) (com.mongodb ReadConcern ReadPreference WriteConcern MongoNamespace)
(com.mongodb.client MongoDatabase MongoCollection TransactionBody) (com.mongodb.client MongoDatabase MongoCollection TransactionBody ClientSession)
(com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions CreateCollectionOptions RenameCollectionOptions IndexOptions IndexModel UpdateOptions ReplaceOptions) (com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions CreateCollectionOptions RenameCollectionOptions IndexOptions IndexModel UpdateOptions ReplaceOptions)
(java.util List Collection) (java.util List Collection)
(java.util.concurrent TimeUnit) (java.util.concurrent TimeUnit)
@ -88,35 +88,35 @@
(defn ->ReadConcern (defn ->ReadConcern
"Coerce `rc` into a ReadConcern if not nil. See `collection` for usage." "Coerce `rc` into a ReadConcern if not nil. See `collection` for usage."
[rc] [{:keys [read-concern]}]
(when rc (when read-concern
(if (instance? ReadConcern rc) (if (instance? ReadConcern read-concern)
rc read-concern
(or (kw->ReadConcern rc) (throw (IllegalArgumentException. (or (kw->ReadConcern read-concern) (throw (IllegalArgumentException.
(str "No match for read concern of " (name rc)))))))) (str "No match for read concern of " (name read-concern))))))))
(defn ->ReadPreference (defn ->ReadPreference
"Coerce `rp` into a ReadPreference if not nil. See `collection` for usage." "Coerce `rp` into a ReadPreference if not nil. See `collection` for usage."
[rp] [{:keys [read-preference]}]
(when rp (when read-preference
(if (instance? ReadPreference rp) (if (instance? ReadPreference read-preference)
rp read-preference
(ReadPreference/valueOf (name rp))))) (ReadPreference/valueOf (name read-preference)))))
(defn ->WriteConcern (defn ^WriteConcern ->WriteConcern
"Coerces write-concern related options to a WriteConcern. See `collection` for usage." "Coerces write-concern related options to a WriteConcern. See `collection` for usage."
[{:keys [write-concern write-concern/w write-concern/w-timeout-ms write-concern/journal?]}] [{:keys [write-concern ^Integer write-concern/w ^Long write-concern/w-timeout-ms ^Boolean write-concern/journal?]}]
(when (some some? [write-concern w w-timeout-ms journal?]) (when (some some? [write-concern w w-timeout-ms journal?])
(let [wc (when write-concern (let [^WriteConcern wc (when write-concern
(if (instance? WriteConcern write-concern) (if (instance? WriteConcern write-concern)
write-concern write-concern
(WriteConcern/valueOf (name write-concern))))] (WriteConcern/valueOf (name write-concern))))]
(-> (or wc (WriteConcern/ACKNOWLEDGED)) (cond-> (or wc (WriteConcern/ACKNOWLEDGED))
(#(if w (.withW % w) %)) w (.withW w)
(#(if w-timeout-ms (.withWTimeout % w-timeout-ms (TimeUnit/MILLISECONDS)) %)) w-timeout-ms (.withWTimeout w-timeout-ms (TimeUnit/MILLISECONDS))
(#(if (some? journal?) (.withJournal % journal?) %)))))) (some? journal?) (.withJournal journal?)))))
(defn collection (defn ^MongoCollection collection
"Coerces `coll` to a MongoCollection with some options. "Coerces `coll` to a MongoCollection with some options.
Arguments: Arguments:
@ -141,12 +141,14 @@
([^MongoDatabase db coll] ([^MongoDatabase db coll]
(collection db coll {})) (collection db coll {}))
([^MongoDatabase db coll opts] ([^MongoDatabase db coll opts]
(let [coll' (if (instance? MongoCollection coll) coll (.getCollection db coll)) (let [^MongoCollection coll' (if (instance? MongoCollection coll) coll (.getCollection db coll))
{:keys [read-concern read-preference]} opts] rp (->ReadPreference opts)
(-> coll' rc (->ReadConcern opts)
(#(if-let [rp (->ReadPreference read-preference)] (.withReadPreference % rp) %)) wc (->WriteConcern opts)]
(#(if-let [rc (->ReadConcern read-concern)] (.withReadConcern % rc) %)) (cond-> ^MongoCollection coll'
(#(if-let [wc (->WriteConcern opts)] (.withWriteConcern % wc) %)))))) rp (.withReadPreference rp)
rc (.withReadConcern rc)
wc (.withWriteConcern wc)))))
;;; CRUD functions ;;; CRUD functions
@ -169,28 +171,27 @@
([^MongoDatabase db coll pipeline] ([^MongoDatabase db coll pipeline]
(aggregate db coll pipeline {})) (aggregate db coll pipeline {}))
([^MongoDatabase db coll pipeline opts] ([^MongoDatabase db coll pipeline opts]
(let [{:keys [session allow-disk-use? batch-size bypass-document-validation? keywordize? raw?] :or {keywordize? true raw? false}} opts (let [{:keys [^ClientSession session allow-disk-use? ^Integer batch-size bypass-document-validation? keywordize? raw?] :or {keywordize? true raw? false}} opts
it (-> (if session it (cond-> (if session
(.aggregate (collection db coll opts) session (document pipeline)) (.aggregate (collection db coll opts) session ^List (map document pipeline))
(.aggregate (collection db coll opts) (document pipeline))) (.aggregate (collection db coll opts) ^List (map document pipeline)))
(#(if (some? allow-disk-use?) (.allowDiskUse % allow-disk-use?) %)) (some? allow-disk-use?) (.allowDiskUse allow-disk-use?)
(#(if batch-size (.batchSize % batch-size) %)) (some? bypass-document-validation?) (.bypassDocumentValidation bypass-document-validation?)
(#(if (some? bypass-document-validation?) (.bypassDocumentValidation % bypass-document-validation?) %)))] batch-size (.batchSize batch-size))]
(if-not raw? (if-not raw?
(map (fn [x] (from-document x keywordize?)) (seq it)) (map (fn [x] (from-document x keywordize?)) (seq it))
it)))) it))))
(defn ->CountOptions (defn ^CountOptions ->CountOptions
"Coerce options map into CountOptions. See `count-documents` for usage." "Coerce options map into CountOptions. See `count-documents` for usage."
[{:keys [count-options hint limit max-time-ms skip]}] [{:keys [count-options hint limit max-time-ms skip]}]
(let [opts (or count-options (CountOptions.))] (let [^CountOptions opts (or count-options (CountOptions.))]
(when hint (.hint opts (document hint))) (cond-> opts
(when limit (.limit opts limit)) hint (.hint (document hint))
(when max-time-ms (.maxTime opts max-time-ms (TimeUnit/MILLISECONDS))) limit (.limit limit)
(when skip (.skip opts skip)) max-time-ms (.maxTime max-time-ms (TimeUnit/MILLISECONDS))
skip (.skip skip))))
opts))
(defn count-documents (defn count-documents
"Count documents in a collection, optionally matching a filter query `q`. "Count documents in a collection, optionally matching a filter query `q`.
@ -220,10 +221,10 @@
(.countDocuments (collection db coll opts) session (document q) opts') (.countDocuments (collection db coll opts) session (document q) opts')
(.countDocuments (collection db coll opts) (document q) opts'))))) (.countDocuments (collection db coll opts) (document q) opts')))))
(defn ->DeleteOptions (defn ^DeleteOptions ->DeleteOptions
"Coerce options map into DeleteOptions. See `delete-one` and `delete-many` for usage." "Coerce options map into DeleteOptions. See `delete-one` and `delete-many` for usage."
[{:keys [delete-options]}] [{:keys [delete-options]}]
(let [opts (or delete-options (DeleteOptions.))] (let [^DeleteOptions opts (or delete-options (DeleteOptions.))]
opts)) opts))
(defn delete-one (defn delete-one
@ -287,14 +288,14 @@
([^MongoDatabase db coll q] ([^MongoDatabase db coll q]
(find db coll q {})) (find db coll q {}))
([^MongoDatabase db coll q opts] ([^MongoDatabase db coll q opts]
(let [{:keys [limit skip sort projection session keywordize? raw?] :or {keywordize? true raw? false}} opts] (let [{:keys [limit skip sort projection ^ClientSession session keywordize? raw?] :or {keywordize? true raw? false}} opts]
(let [it (-> (if session (let [it (cond-> (if session
(.find (collection db coll opts) session (document q)) (.find (collection db coll opts) session (document q))
(.find (collection db coll opts) (document q))) (.find (collection db coll opts) (document q)))
(#(if limit (.limit % limit) %)) limit (.limit limit)
(#(if skip (.skip % skip) %)) skip (.skip skip)
(#(if sort (.sort % (document sort)) %)) sort (.sort (document sort))
(#(if projection (.projection % (document projection)) %)))] projection (.projection (document projection)))]
(if-not raw? (if-not raw?
(map (fn [x] (from-document x keywordize?)) (seq it)) (map (fn [x] (from-document x keywordize?)) (seq it))
@ -309,16 +310,15 @@
([^MongoDatabase db coll q opts] ([^MongoDatabase db coll q opts]
(first (find db coll q (assoc opts :limit 1 :raw? false))))) (first (find db coll q (assoc opts :limit 1 :raw? false)))))
(defn ->FindOneAndUpdateOptions (defn ^FindOneAndUpdateOptions ->FindOneAndUpdateOptions
"Coerce options map into FindOneAndUpdateOptions. See `find-one-and-update` for usage." "Coerce options map into FindOneAndUpdateOptions. See `find-one-and-update` for usage."
[{:keys [find-one-and-update-options upsert? return-new? sort projection]}] [{:keys [find-one-and-update-options upsert? return-new? sort projection]}]
(let [opts (or find-one-and-update-options (FindOneAndUpdateOptions.))] (let [^FindOneAndUpdateOptions opts (or find-one-and-update-options (FindOneAndUpdateOptions.))]
(when (some? upsert?) (.upsert opts upsert?)) (cond-> opts
(when return-new? (.returnDocument opts (ReturnDocument/AFTER))) (some? upsert?) (.upsert upsert?)
(when sort (.sort opts (document sort))) return-new? (.returnDocument (ReturnDocument/AFTER))
(when projection (.projection opts (document projection))) sort (.sort (document sort))
projection (.projection (document projection)))))
opts))
(defn find-one-and-update (defn find-one-and-update
"Atomically find a document (at most one) and modify it. "Atomically find a document (at most one) and modify it.
@ -343,23 +343,22 @@
([^MongoDatabase db coll q update] ([^MongoDatabase db coll q update]
(find-one-and-update db coll q update {})) (find-one-and-update db coll q update {}))
([^MongoDatabase db coll q update opts] ([^MongoDatabase db coll q update opts]
(let [{:keys [keywordize? session] :or {keywordize? true}} opts (let [{:keys [keywordize? ^ClientSession session] :or {keywordize? true}} opts
opts' (->FindOneAndUpdateOptions opts)] opts' (->FindOneAndUpdateOptions opts)]
(-> (if session (-> (if session
(.findOneAndUpdate (collection db coll opts) session (document q) (document update) opts') (.findOneAndUpdate (collection db coll opts) session (document q) (document update) opts')
(.findOneAndUpdate (collection db coll opts) (document q) (document update) opts')) (.findOneAndUpdate (collection db coll opts) (document q) (document update) opts'))
(from-document keywordize?))))) (from-document keywordize?)))))
(defn ->FindOneAndReplaceOptions (defn ^FindOneAndReplaceOptions ->FindOneAndReplaceOptions
"Coerce options map into FindOneAndReplaceOptions. See `find-one-and-replace` for usage." "Coerce options map into FindOneAndReplaceOptions. See `find-one-and-replace` for usage."
[{:keys [find-one-and-replace-options upsert? return-new? sort projection]}] [{:keys [find-one-and-replace-options upsert? return-new? sort projection]}]
(let [opts (or find-one-and-replace-options (FindOneAndReplaceOptions.))] (let [^FindOneAndReplaceOptions opts (or find-one-and-replace-options (FindOneAndReplaceOptions.))]
(when (some? upsert?) (.upsert opts upsert?)) (cond-> opts
(when return-new? (.returnDocument opts (ReturnDocument/AFTER))) (some? upsert?) (.upsert upsert?)
(when sort (.sort opts (document sort))) return-new? (.returnDocument (ReturnDocument/AFTER))
(when projection (.projection opts (document projection))) sort (.sort (document sort))
projection (.projection (document projection)))))
opts))
(defn find-one-and-replace (defn find-one-and-replace
"Atomically find a document (at most one) and replace it. "Atomically find a document (at most one) and replace it.
@ -391,10 +390,10 @@
(.findOneAndReplace (collection db coll opts) (document q) (document doc) opts')) (.findOneAndReplace (collection db coll opts) (document q) (document doc) opts'))
(from-document keywordize?))))) (from-document keywordize?)))))
(defn ->InsertOneOptions (defn ^InsertOneOptions ->InsertOneOptions
"Coerce options map into InsertOneOptions. See `insert-one` for usage." "Coerce options map into InsertOneOptions. See `insert-one` for usage."
[{:keys [insert-one-options bypass-document-validation?]}] [{:keys [insert-one-options bypass-document-validation?]}]
(let [opts (or insert-one-options (InsertOneOptions.))] (let [^InsertOneOptions opts (or insert-one-options (InsertOneOptions.))]
(when (some? bypass-document-validation?) (.bypassDocumentValidation opts bypass-document-validation?)) (when (some? bypass-document-validation?) (.bypassDocumentValidation opts bypass-document-validation?))
opts)) opts))
@ -423,14 +422,13 @@
(.insertOne (collection db coll opts) session (document doc) opts') (.insertOne (collection db coll opts) session (document doc) opts')
(.insertOne (collection db coll opts) (document doc) opts'))))) (.insertOne (collection db coll opts) (document doc) opts')))))
(defn ->InsertManyOptions (defn ^InsertManyOptions ->InsertManyOptions
"Coerce options map into InsertManyOptions. See `insert-many` for usage." "Coerce options map into InsertManyOptions. See `insert-many` for usage."
[{:keys [insert-many-options bypass-document-validation? ordered?]}] [{:keys [insert-many-options bypass-document-validation? ordered?]}]
(let [opts (or insert-many-options (InsertManyOptions.))] (let [^InsertManyOptions opts (or insert-many-options (InsertManyOptions.))]
(when (some? bypass-document-validation?) (.bypassDocumentValidation opts bypass-document-validation?)) (cond-> opts
(when (some? ordered?) (.ordered opts ordered?)) (some? bypass-document-validation?) (.bypassDocumentValidation bypass-document-validation?)
(some? ordered?) (.ordered ordered?))))
opts))
(defn insert-many (defn insert-many
"Inserts multiple documents into a collection. "Inserts multiple documents into a collection.
@ -453,18 +451,17 @@
(insert-many db coll docs {})) (insert-many db coll docs {}))
([^MongoDatabase db coll docs opts] ([^MongoDatabase db coll docs opts]
(let [opts' (->InsertManyOptions opts)] (let [opts' (->InsertManyOptions opts)]
(if-let [session (:session opts)] (if-let [^ClientSession session (:session opts)]
(.insertMany (collection db coll opts) session (map document docs) opts') (.insertMany (collection db coll opts) session ^List (map document docs) opts')
(.insertMany (collection db coll opts) (map document docs) opts'))))) (.insertMany (collection db coll opts) ^List (map document docs) opts')))))
(defn ->ReplaceOptions (defn ^ReplaceOptions ->ReplaceOptions
"Coerce options map into ReplaceOptions. See `replace-one` and `replace-many` for usage." "Coerce options map into ReplaceOptions. See `replace-one` and `replace-many` for usage."
[{:keys [replace-options upsert? bypass-document-validation?]}] [{:keys [replace-options upsert? bypass-document-validation?]}]
(let [opts (or replace-options (ReplaceOptions.))] (let [^ReplaceOptions opts (or replace-options (ReplaceOptions.))]
(when (some? upsert?) (.upsert opts upsert?)) (cond-> opts
(when (some? bypass-document-validation?) (.bypassDocumentValidation opts bypass-document-validation?)) (some? upsert?) (.upsert upsert?)
(some? bypass-document-validation?) (.bypassDocumentValidation bypass-document-validation?))))
opts))
(defn replace-one (defn replace-one
"Replace a single document in a collection and returns an UpdateResult. "Replace a single document in a collection and returns an UpdateResult.
@ -486,18 +483,17 @@
([^MongoDatabase db coll q doc] ([^MongoDatabase db coll q doc]
(find-one-and-replace db coll q doc {})) (find-one-and-replace db coll q doc {}))
([^MongoDatabase db coll q doc opts] ([^MongoDatabase db coll q doc opts]
(if-let [session (:session opts)] (if-let [^ClientSession session (:session opts)]
(.replaceOne (collection db coll opts) session (document q) (document doc) (->ReplaceOptions opts)) (.replaceOne (collection db coll opts) session (document q) (document doc) (->ReplaceOptions opts))
(.replaceOne (collection db coll opts) (document q) (document doc) (->ReplaceOptions opts))))) (.replaceOne (collection db coll opts) (document q) (document doc) (->ReplaceOptions opts)))))
(defn ->UpdateOptions (defn ^UpdateOptions ->UpdateOptions
"Coerce options map into UpdateOptions. See `update-one` and `update-many` for usage." "Coerce options map into UpdateOptions. See `update-one` and `update-many` for usage."
[{:keys [update-options upsert? bypass-document-validation?]}] [{:keys [update-options upsert? bypass-document-validation?]}]
(let [opts (or update-options (UpdateOptions.))] (let [^UpdateOptions opts (or update-options (UpdateOptions.))]
(when (some? upsert?) (.upsert opts upsert?)) (cond-> opts
(when (some? bypass-document-validation?) (.bypassDocumentValidation opts bypass-document-validation?)) (some? upsert?) (.upsert upsert?)
(some? bypass-document-validation?) (.bypassDocumentValidation bypass-document-validation?))))
opts))
(defn update-one (defn update-one
"Updates a single document in a collection and returns an UpdateResult. "Updates a single document in a collection and returns an UpdateResult.
@ -519,7 +515,7 @@
([^MongoDatabase db coll q update] ([^MongoDatabase db coll q update]
(update-one db coll q update {})) (update-one db coll q update {}))
([^MongoDatabase db coll q update opts] ([^MongoDatabase db coll q update opts]
(if-let [session (:session opts)] (if-let [^ClientSession session (:session opts)]
(.updateOne (collection db coll opts) session (document q) (document update) (->UpdateOptions opts)) (.updateOne (collection db coll opts) session (document q) (document update) (->UpdateOptions opts))
(.updateOne (collection db coll opts) (document q) (document update) (->UpdateOptions opts))))) (.updateOne (collection db coll opts) (document q) (document update) (->UpdateOptions opts)))))
@ -541,23 +537,22 @@
Additionally takes options specified in `collection`" Additionally takes options specified in `collection`"
([^MongoDatabase db coll q update] ([^MongoDatabase db coll q update]
(update-many db coll q {})) (update-many db coll q update {}))
([^MongoDatabase db coll q update opts] ([^MongoDatabase db coll q update opts]
(if-let [session (:session opts)] (if-let [^ClientSession session (:session opts)]
(.updateMany (collection db coll opts) session (document q) (document update) (->UpdateOptions opts)) (.updateMany (collection db coll opts) session (document q) (document update) (->UpdateOptions opts))
(.updateMany (collection db coll opts) (document q) (document update) (->UpdateOptions opts))))) (.updateMany (collection db coll opts) (document q) (document update) (->UpdateOptions opts)))))
;;; Admin functions ;;; Admin functions
(defn ->CreateCollectionOptions (defn ^CreateCollectionOptions ->CreateCollectionOptions
"Coerce options map into CreateCollectionOptions. See `create` usage." "Coerce options map into CreateCollectionOptions. See `create` usage."
[{:keys [create-collection-options capped? max-documents max-size-bytes]}] [{:keys [create-collection-options capped? max-documents max-size-bytes]}]
(let [opts (or create-collection-options (CreateCollectionOptions.))] (let [^CreateCollectionOptions opts (or create-collection-options (CreateCollectionOptions.))]
(when (some? capped?) (.capped opts capped?)) (cond-> opts
(when max-documents (.maxDocuments opts max-documents)) (some? capped?) (.capped capped?)
(when max-size-bytes (.sizeInBytes opts max-size-bytes)) max-documents (.maxDocuments max-documents)
max-size-bytes (.sizeInBytes max-size-bytes))))
opts))
(defn create (defn create
"Creates a collection "Creates a collection
@ -572,19 +567,18 @@
- `:max-size-bytes` max collection size in bytes for a capped collection - `:max-size-bytes` max collection size in bytes for a capped collection
- `:create-collection-options` A CreateCollectionOptions for configuring directly. If specified, - `:create-collection-options` A CreateCollectionOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it" any other [preceding] query options will be applied to it"
([^MongoDatabase db coll] ([^MongoDatabase db ^String coll]
(create db coll {})) (create db coll {}))
([^MongoDatabase db coll opts] ([^MongoDatabase db ^String coll opts]
(let [opts' (->CreateCollectionOptions opts)] (let [opts' (->CreateCollectionOptions opts)]
(.createCollection db coll opts')))) (.createCollection db coll opts'))))
(defn ->RenameCollectionOptions (defn ^RenameCollectionOptions ->RenameCollectionOptions
"Coerce options map into RenameCollectionOptions. See `rename` usage." "Coerce options map into RenameCollectionOptions. See `rename` usage."
[{:keys [rename-collection-options drop-target?]}] [{:keys [rename-collection-options drop-target?]}]
(let [opts (or rename-collection-options (RenameCollectionOptions.))] (let [^RenameCollectionOptions opts (or rename-collection-options (RenameCollectionOptions.))]
(when (some? drop-target?) (.dropTarget opts drop-target?)) (cond-> opts
(some? drop-target?) (.dropTarget drop-target?))))
opts))
(defn rename (defn rename
"Renames `coll` to `new-coll` in the same DB. "Renames `coll` to `new-coll` in the same DB.
@ -612,17 +606,16 @@
[^MongoDatabase db coll] [^MongoDatabase db coll]
(.drop (collection db coll))) (.drop (collection db coll)))
(defn ->IndexOptions (defn ^IndexOptions ->IndexOptions
"Coerces an options map into an IndexOptions. "Coerces an options map into an IndexOptions.
See `create-index` for usage" See `create-index` for usage"
[{:keys [index-options name sparse? unique?]}] [{:keys [index-options name sparse? unique?]}]
(let [opts (or index-options (IndexOptions.))] (let [^IndexOptions opts (or index-options (IndexOptions.))]
(when name (.name opts name)) (cond-> opts
(when (some? sparse?) (.sparse opts sparse?)) name (.name name)
(when (some? unique?) (.unique opts unique?)) (some? sparse?) (.sparse sparse?)
(some? unique?) (.unique unique?))))
opts))
(defn create-index (defn create-index
"Creates an index "Creates an index
@ -679,11 +672,11 @@
Ensure `session` is passed as an option to each operation. Ensure `session` is passed as an option to each operation.
e.g. e.g.
(def s (.startSession conn)) (def s (start-session client))
(with-transaction s (with-transaction s
(fn [] (fn []
(insert-one my-db \"coll\" {:name \"hello\"} {:session s}) (insert-one my-db \"coll\" {:name \"hello\"} {:session s})
(insert-one my-db \"coll\" {:name \"world\"} {:session s})))" (insert-one my-db \"coll\" {:name \"world\"} {:session s})))"
[session body] [^ClientSession session body]
(.withTransaction session (reify TransactionBody (.withTransaction session (reify TransactionBody
(execute [_] body)))) (execute [_] body))))

View file

@ -2,7 +2,7 @@
(:require [clojure.test :refer :all] (:require [clojure.test :refer :all]
[mongo-driver-3.client :as mg] [mongo-driver-3.client :as mg]
[mongo-driver-3.collection :as mc]) [mongo-driver-3.collection :as mc])
(:import (com.mongodb.client MongoClient MongoDatabase MongoIterable ListCollectionsIterable ClientSession) (:import (com.mongodb.client MongoClient MongoDatabase MongoIterable ListCollectionsIterable)
(java.util UUID) (java.util UUID)
(com.mongodb ClientSessionOptions ReadConcern ReadPreference) (com.mongodb ClientSessionOptions ReadConcern ReadPreference)
(java.util.concurrent TimeUnit))) (java.util.concurrent TimeUnit)))
@ -55,18 +55,18 @@
[client] [client]
(mg/get-db client (.toString (UUID/randomUUID)))) (mg/get-db client (.toString (UUID/randomUUID))))
(deftest ^:integration test-collection-names (deftest ^:integration test-list-collections
(let [db (new-db @client) (let [db (new-db @client)
_ (mc/create db "test")] _ (mc/create db "test")]
(is (= ["test"] (mg/collection-names db))) (is (= ["test"] (map :name (mg/list-collections db))))
(is (instance? MongoIterable (mg/collection-names db {:raw? true}))))) (is (= ["test"] (map #(get % "name") (mg/list-collections db {:keywordize? false}))))
(is (instance? ListCollectionsIterable (mg/list-collections db {:raw? true})))))
(deftest ^:integration test-collections (deftest ^:integration test-list-collection-names
(let [db (new-db @client) (let [db (new-db @client)
_ (mc/create db "test")] _ (mc/create db "test")]
(is (= ["test"] (map :name (mg/collections db)))) (is (= ["test"] (mg/list-collection-names db)))
(is (= ["test"] (map #(get % "name") (mg/collections db {:keywordize? false})))) (is (instance? MongoIterable (mg/list-collection-names db {:raw? true})))))
(is (instance? ListCollectionsIterable (mg/collections db {:raw? true})))))
#_(deftest ^:integration test-start-session #_(deftest ^:integration test-start-session
(is (instance? ClientSession (mg/start-session @client)))) (is (instance? ClientSession (mg/start-session @client))))

View file

@ -12,14 +12,14 @@
;;; Unit ;;; Unit
(deftest test->ReadConcern (deftest test->ReadConcern
(is (nil? (mc/->ReadConcern nil))) (is (nil? (mc/->ReadConcern {})))
(is (thrown? IllegalArgumentException (mc/->ReadConcern "invalid"))) (is (thrown? IllegalArgumentException (mc/->ReadConcern {:read-concern "invalid"})))
(is (instance? ReadConcern (mc/->ReadConcern :available)))) (is (instance? ReadConcern (mc/->ReadConcern {:read-concern :available}))))
(deftest test->ReadPreference (deftest test->ReadPreference
(is (nil? (mc/->ReadPreference nil))) (is (nil? (mc/->ReadPreference {})))
(is (thrown? IllegalArgumentException (mc/->ReadPreference "invalid"))) (is (thrown? IllegalArgumentException (mc/->ReadPreference {:read-preference "invalid"})))
(is (instance? ReadPreference (mc/->ReadPreference :primary)))) (is (instance? ReadPreference (mc/->ReadPreference {:read-preference :primary}))))
(deftest test->WriteConcern (deftest test->WriteConcern
(is (= (WriteConcern/W1) (mc/->WriteConcern {:write-concern :w1})) "accepts kw") (is (= (WriteConcern/W1) (mc/->WriteConcern {:write-concern :w1})) "accepts kw")