diff --git a/src/mongo_driver_3/collection.clj b/src/mongo_driver_3/collection.clj index 61c0b88..0ed0788 100644 --- a/src/mongo_driver_3/collection.clj +++ b/src/mongo_driver_3/collection.clj @@ -605,17 +605,31 @@ (let [opts' (->CreateCollectionOptions opts)] (.createCollection db coll opts')))) +(defn ->RenameCollectionOptions + "Coerce options map into RenameCollectionOptions. See `rename` usage." + [{:keys [rename-collection-options drop-target?]}] + (let [opts (or rename-collection-options (RenameCollectionOptions.))] + (when (some? drop-target?) (.dropTarget opts drop-target?)) + + opts)) + (defn rename - "Renames `coll` to `new-coll` in the same DB." - [^MongoDatabase db coll new-coll opts] - (let [{:keys [drop-target?]} opts - opts' (RenameCollectionOptions.)] + "Renames `coll` to `new-coll` in the same DB. - (when drop-target? (.dropTarget opts' true)) + Takes an options map: + -- query options + :drop-target? Boolean drop tne target collection if it exists. Default: false - (.renameCollection (collection db coll opts) - (MongoNamespace. (.getName db) new-coll) - opts'))) + :rename-collection-options A RenameCollectionOptions for configuring directly. If specified, + any other query options will be applied to it" + ([^MongoDatabase db coll new-coll] + (rename db coll new-coll {})) + ([^MongoDatabase db coll new-coll opts] + (let [opts' (->RenameCollectionOptions opts)] + + (.renameCollection (collection db coll opts) + (MongoNamespace. (.getName db) new-coll) + opts')))) (defn drop "Drops a collection from a database." @@ -666,30 +680,24 @@ -- optional any attributes available in `->IndexOptions`" - [^MongoDatabase db coll indexes] - (->> indexes - (map (fn [x] (IndexModel. (document (:keys x)) (->IndexOptions x)))) - (.createIndexes (collection db coll)))) + ([^MongoDatabase db coll indexes] + (create-indexes db coll indexes {})) + ([^MongoDatabase db coll indexes opts] + (->> indexes + (map (fn [x] (IndexModel. (document (:keys x)) (->IndexOptions x)))) + (.createIndexes (collection db coll opts))))) (defn list-indexes "Lists indexes." - [^MongoDatabase db coll] - (->> (.listIndexes (collection db coll)) - (map #(from-document % true)))) + ([^MongoDatabase db coll] + (list-indexes db coll {})) + ([^MongoDatabase db coll opts] + (->> (.listIndexes (collection db coll opts)) + (map #(from-document % true))))) ;;; Utility functions -(defn empty? - "Returns true if a collection is empty" - [^MongoDatabase db coll] - (zero? (count-documents db coll))) - -(defn exists? - "Returns true if collection exists" - [^MongoDatabase db coll] - (some #(= coll %) (.listCollectionNames db))) - -(defn with-transaction +(defn- with-transaction "Executes `body` in a transaction. `body` should be a fn with one or more mongo operations in it. diff --git a/test/mongo_driver_3/collection_test.clj b/test/mongo_driver_3/collection_test.clj index 777f86b..ebdc53f 100644 --- a/test/mongo_driver_3/collection_test.clj +++ b/test/mongo_driver_3/collection_test.clj @@ -4,9 +4,10 @@ [mongo-driver-3.collection :as mc]) (:import (com.mongodb ReadConcern ReadPreference WriteConcern) (java.util.concurrent TimeUnit) - (com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions UpdateOptions ReplaceOptions IndexOptions CreateCollectionOptions) + (com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions UpdateOptions ReplaceOptions IndexOptions CreateCollectionOptions RenameCollectionOptions) (java.time ZoneId LocalDate LocalTime LocalDateTime) - (java.util Date UUID))) + (java.util Date UUID) + (com.mongodb.client MongoDatabase))) ;;; Unit @@ -97,6 +98,16 @@ (let [opts (DeleteOptions.)] (is (= opts (mc/->DeleteOptions {:delete-options opts})) "configure directly"))) +(deftest test->RenameCollectionOptions + (is (instance? RenameCollectionOptions (mc/->RenameCollectionOptions {}))) + (are [expected arg] + (= expected (.isDropTarget (mc/->RenameCollectionOptions {:drop-target? arg}))) + true true + false false + false nil) + (let [opts (RenameCollectionOptions.)] + (is (= opts (mc/->RenameCollectionOptions {:rename-collection-options opts})) "configure directly"))) + (deftest test->FindOneAndUpdateOptions (is (instance? FindOneAndUpdateOptions (mc/->FindOneAndUpdateOptions {}))) (let [opts (FindOneAndUpdateOptions.)] @@ -459,4 +470,63 @@ (let [res (mc/update-many db "test" {:id 1} {:$set {:r 1}} {:upsert? true})] (is (= 0 (.getMatchedCount res))) (is (= 0 (.getModifiedCount res))) - (is (some? (.getUpsertedId res))))))) \ No newline at end of file + (is (some? (.getUpsertedId res))))))) + +(defn- coll-exists? + "Returns true if collection exists" + [db coll] + (some #(= coll %) (.listCollectionNames db))) + +(deftest ^:integration test-create + (testing "not existing" + (let [db (new-db @client) + _ (mc/create db "my-coll")] + (is (true? (coll-exists? db "my-coll"))))) + + (testing "existing" + (let [db (new-db @client) + _ (mc/create db "my-coll")] + (is (thrown? Exception (mc/create db "my-coll")))))) + +(deftest ^:integration test-rename + (testing "not existing" + (let [db (new-db @client) + _ (mc/create db "old") + _ (mc/rename db "old" "new")] + (is (not (coll-exists? db "old"))) + (is (true? (coll-exists? db "new"))))) + + (testing "existing" + (let [db (new-db @client) + _ (mc/create db "old") + _ (mc/create db "new")] + (is (thrown? Exception (mc/rename db "old" "new"))) + (mc/rename db "old" "new" {:drop-target? true}) + (is (not (coll-exists? db "old"))) + (is (true? (coll-exists? db "new")))))) + +(deftest ^:integration test-drop + (testing "existing" + (let [db (new-db @client) + _ (mc/create db "my-coll") + _ (mc/drop db "my-coll")] + (is (not (coll-exists? db "my-coll"))))) + + (testing "not existing" + (let [db (new-db @client)] + (is (nil? (mc/drop db "my-coll")))))) + +(deftest ^:integration test-list-indexes + (let [db (new-db @client) + _ (mc/create db "test")] + (is (= 1 (count (mc/list-indexes db "test"))) "has default index"))) + +(deftest ^:integration test-create-index + (let [db (new-db @client) + _ (mc/create-index db "test" {:a 1})] + (is (= [{:_id 1} {:a 1}] (map :key (mc/list-indexes db "test")))))) + +(deftest ^:integration test-create-indexes + (let [db (new-db @client) + _ (mc/create-indexes db "test" [{:keys {:a 1}} {:keys {:b 1}}])] + (is (= [{:_id 1} {:a 1} {:b 1}] (map :key (mc/list-indexes db "test")))))) \ No newline at end of file