From 7766475e522e718981edc9bba26e6adf2bf641d0 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:26:51 -0400 Subject: [PATCH 01/48] Remove old test helpers --- test/monger/test/fixtures.clj | 21 --------------------- test/monger/test/helper.clj | 17 ----------------- 2 files changed, 38 deletions(-) delete mode 100644 test/monger/test/fixtures.clj delete mode 100644 test/monger/test/helper.clj diff --git a/test/monger/test/fixtures.clj b/test/monger/test/fixtures.clj deleted file mode 100644 index 8145a8f..0000000 --- a/test/monger/test/fixtures.clj +++ /dev/null @@ -1,21 +0,0 @@ -(ns monger.test.fixtures - (:require [monger.testkit :refer [defcleaner]])) - -;; -;; fixture functions -;; - -(defcleaner people "people") -(defcleaner docs "docs") -(defcleaner finder-docs "regular_finders_docs") -(defcleaner querying-docs "querying_docs") -(defcleaner things "things") -(defcleaner libraries "libraries") -(defcleaner scores "scores") -(defcleaner locations "locations") -(defcleaner domains "domains") -(defcleaner pages "pages") - -(defcleaner cached "cached") - -(defcleaner migrations "meta.migrations") diff --git a/test/monger/test/helper.clj b/test/monger/test/helper.clj deleted file mode 100644 index 89006f1..0000000 --- a/test/monger/test/helper.clj +++ /dev/null @@ -1,17 +0,0 @@ -(ns monger.test.helper - (:require [monger core util]) - (:import [com.mongodb WriteConcern])) - -(def connected (atom false)) -(defn connected? - [] - @connected) - -(defn connect! - [] - (when-not (connected?) - (do - (monger.core/connect!) - (monger.core/set-db! (monger.core/get-db "monger-test")) - (monger.core/set-default-write-concern! WriteConcern/SAFE) - (reset! connected true)))) From 1e9463e4666f3be1f2c070b6c10c9e1998e11e34 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:26:59 -0400 Subject: [PATCH 02/48] Remove testkit --- src/clojure/monger/testkit.clj | 44 ---------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 src/clojure/monger/testkit.clj diff --git a/src/clojure/monger/testkit.clj b/src/clojure/monger/testkit.clj deleted file mode 100644 index a363519..0000000 --- a/src/clojure/monger/testkit.clj +++ /dev/null @@ -1,44 +0,0 @@ -;; Copyright (c) 2011-2014 Michael S. Klishin -;; -;; The use and distribution terms for this software are covered by the -;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) -;; which can be found in the file epl-v10.html at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. - -(ns monger.testkit - "Automated testing helpers" - (:require [monger.collection :as mc])) - - -;; -;; API -;; - -(defmacro defcleaner - "Defines a fixture function that removes all documents from a collection. If collection is not specified, - a conventionally named var will be used. Supposed to be used with clojure.test/use-fixtures but may - be useful on its own. - - Examples: - - (defcleaner events) ;; collection name will be taken from the events-collection var - (defcleaner people \"accounts\") ;; collection name is given - " - ([entities] - (let [coll-arg (symbol (str entities "-collection")) - fn-name (symbol (str "purge-" entities))] - `(defn ~fn-name - [f#] - (mc/remove ~coll-arg) - (f#) - (mc/remove ~coll-arg)))) - ([entities coll-name] - (let [coll-arg (name coll-name) - fn-name (symbol (str "purge-" entities))] - `(defn ~fn-name - [f#] - (mc/remove ~coll-arg) - (f#) - (mc/remove ~coll-arg))))) From 04e6c5bce6cc63935ec052315c7f2de9716e1122 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:27:28 -0400 Subject: [PATCH 03/48] Get rid of monger.multi, the entire API will now require a conn/db/gridfs arg --- src/clojure/monger/multi/collection.clj | 360 --------------- .../test/multi/atomic_modifiers_test.clj | 409 ------------------ test/monger/test/multi/collection_test.clj | 133 ------ test/monger/test/multi/find_test.clj | 149 ------- test/monger/test/multi/indexing_test.clj | 60 --- test/monger/test/multi/inserting_test.clj | 192 -------- test/monger/test/multi/updating_test.clj | 186 -------- 7 files changed, 1489 deletions(-) delete mode 100644 src/clojure/monger/multi/collection.clj delete mode 100644 test/monger/test/multi/atomic_modifiers_test.clj delete mode 100644 test/monger/test/multi/collection_test.clj delete mode 100644 test/monger/test/multi/find_test.clj delete mode 100644 test/monger/test/multi/indexing_test.clj delete mode 100644 test/monger/test/multi/inserting_test.clj delete mode 100644 test/monger/test/multi/updating_test.clj diff --git a/src/clojure/monger/multi/collection.clj b/src/clojure/monger/multi/collection.clj deleted file mode 100644 index cba76b8..0000000 --- a/src/clojure/monger/multi/collection.clj +++ /dev/null @@ -1,360 +0,0 @@ -(ns monger.multi.collection - "Includes versions of key monger.collection functions that always take a database - as explicit argument instead of relying on monger.core/*mongodb-database*. - - Use these functions when you need to work with multiple databases or manage database - and connection lifecycle explicitly." - (:refer-clojure :exclude [find remove count empty? distinct drop]) - (:import [com.mongodb Mongo DB DBCollection WriteResult DBObject WriteConcern DBCursor MapReduceCommand MapReduceCommand$OutputType] - [java.util List Map] - [clojure.lang IPersistentMap ISeq] - org.bson.types.ObjectId) - (:require monger.core - monger.result - [monger.conversion :refer :all] - [monger.constraints :refer :all])) - - -;; -;; API -;; - -(defn ^WriteResult insert - "Like monger.collection/insert but always takes a database as explicit argument" - ([^DB db ^String collection document] - (.insert (.getCollection db (name collection)) - (to-db-object document) - monger.core/*mongodb-write-concern*)) - ([^DB db ^String collection document ^WriteConcern concern] - (.insert (.getCollection db (name collection)) - (to-db-object document) - concern))) - - -(defn ^clojure.lang.IPersistentMap insert-and-return - "Like monger.collection/insert-and-return but always takes a database as explicit argument" - ([^DB db ^String collection document] - (let [doc (merge {:_id (ObjectId.)} document)] - (insert db collection doc monger.core/*mongodb-write-concern*) - doc)) - ([^DB db ^String collection document ^WriteConcern concern] - ;; MongoDB Java driver will generate the _id and set it but it tries to mutate the inserted DBObject - ;; and it does not work very well in our case, because that DBObject is short lived and produced - ;; from the Clojure map we are passing in. Plus, this approach is very awkward with immutable data - ;; structures being the default. MK. - (let [doc (merge {:_id (ObjectId.)} document)] - (insert db collection doc concern) - doc))) - - -(defn ^WriteResult insert-batch - "Like monger.collection/insert-batch but always takes a database as explicit argument" - ([^DB db ^String collection ^List documents] - (.insert (.getCollection db (name collection)) - ^List (to-db-object documents) - monger.core/*mongodb-write-concern*)) - ([^DB db ^String collection ^List documents ^WriteConcern concern] - (.insert (.getCollection db (name collection)) - ^List (to-db-object documents) - concern))) - - -;; -;; monger.multi.collection/find -;; - -(defn ^DBCursor find - "Like monger.collection/find but always takes a database as explicit argument" - ([^DB db ^String collection] - (.find (.getCollection db (name collection)))) - ([^DB db ^String collection ^Map ref] - (.find (.getCollection db (name collection)) - (to-db-object ref))) - ([^DB db ^String collection ^Map ref fields] - (.find (.getCollection db (name collection)) - (to-db-object ref) - (as-field-selector fields)))) - -(defn find-maps - "Like monger.collection/find-maps but always takes a database as explicit argument" - ([^DB db ^String collection] - (with-open [dbc (find db collection)] - (map (fn [x] (from-db-object x true)) dbc))) - ([^DB db ^String collection ^Map ref] - (with-open [dbc (find db collection ref)] - (map (fn [x] (from-db-object x true)) dbc))) - ([^DB db ^String collection ^Map ref fields] - (with-open [dbc (find db collection ref fields)] - (map (fn [x] (from-db-object x true)) dbc)))) - -(defn find-seq - "Like monger.collection/find-seq but always takes a database as explicit argument" - ([^DB db ^String collection] - (with-open [dbc (find db collection)] - (seq dbc))) - ([^DB db ^String collection ^Map ref] - (with-open [dbc (find db collection ref)] - (seq dbc))) - ([^DB db ^String collection ^Map ref fields] - (with-open [dbc (find db collection ref fields)] - (seq dbc)))) - -;; -;; monger.multi.collection/find-one -;; - -(defn ^DBObject find-one - "Like monger.collection/find-one but always takes a database as explicit argument" - ([^DB db ^String collection ^Map ref] - (.findOne (.getCollection db (name collection)) - (to-db-object ref))) - ([^DB db ^String collection ^Map ref fields] - (.findOne (.getCollection db (name collection)) - (to-db-object ref) - ^DBObject (as-field-selector fields)))) - -(defn ^IPersistentMap find-one-as-map - "Like monger.collection/find-one-as-map but always takes a database as explicit argument" - ([^DB db ^String collection ^Map ref] - (from-db-object ^DBObject (find-one db collection ref) true)) - ([^DB db ^String collection ^Map ref fields] - (from-db-object ^DBObject (find-one db collection ref fields) true)) - ([^DB db ^String collection ^Map ref fields keywordize] - (from-db-object ^DBObject (find-one db collection ref fields) keywordize))) - -;; -;; monger.multi.collection/find-and-modify -;; - -(defn ^IPersistentMap find-and-modify - "Like monger.collection/find-and-modify but always takes a database as explicit argument" - ([^DB db ^String collection ^Map conditions ^Map document & {:keys [fields sort remove return-new upsert keywordize] :or - {fields nil sort nil remove false return-new false upsert false keywordize true}}] - (let [coll (.getCollection db (name collection)) - maybe-fields (when fields (as-field-selector fields)) - maybe-sort (when sort (to-db-object sort))] - (from-db-object - ^DBObject (.findAndModify ^DBCollection coll (to-db-object conditions) maybe-fields maybe-sort remove - (to-db-object document) return-new upsert) keywordize)))) - -;; -;; monger.multi.collection/find-by-id -;; - -(defn ^DBObject find-by-id - "Like monger.collection/find-by-id but always takes a database as explicit argument" - ([^DB db ^String collection id] - (check-not-nil! id "id must not be nil") - (find-one db collection {:_id id})) - ([^DB db ^String collection id fields] - (check-not-nil! id "id must not be nil") - (find-one db collection {:_id id} fields))) - -(defn ^IPersistentMap find-map-by-id - "Like monger.collection/find-map-by-id but always takes a database as explicit argument" - ([^DB db ^String collection id] - (check-not-nil! id "id must not be nil") - (from-db-object ^DBObject (find-one-as-map db collection {:_id id}) true)) - ([^DB db ^String collection id fields] - (check-not-nil! id "id must not be nil") - (from-db-object ^DBObject (find-one-as-map db collection {:_id id} fields) true)) - ([^DB db ^String collection id fields keywordize] - (check-not-nil! id "id must not be nil") - (from-db-object ^DBObject (find-one-as-map db collection {:_id id} fields) keywordize))) - -;; -;; monger.multi.collection/count -;; - -(defn count - "Like monger.collection/count but always takes a database as explicit argument" - (^long [^DB db ^String collection] - (.count (.getCollection db (name collection)) (to-db-object {}))) - (^long [^DB db ^String collection ^Map conditions] - (.count (.getCollection db (name collection)) (to-db-object conditions)))) - -(defn any? - "Like monger.collection/any? but always takes a database as explicit argument" - ([^DB db ^String collection] - (> (count db collection) 0)) - ([^DB db ^String collection ^Map conditions] - (> (count db collection conditions) 0))) - -(defn empty? - "Like monger.collection/empty? but always takes a database as explicit argument" - ([^DB db ^String collection] - (= (count db collection {}) 0))) - -(defn ^WriteResult update - "Like monger.collection/update but always takes a database as explicit argument" - ([^DB db ^String collection ^Map conditions ^Map document & {:keys [upsert multi write-concern] :or {upsert false - multi false - write-concern monger.core/*mongodb-write-concern*}}] - (.update (.getCollection db (name collection)) - (to-db-object conditions) - (to-db-object document) - upsert - multi - write-concern))) - -(defn ^WriteResult upsert - "Like monger.collection/upsert but always takes a database as explicit argument" - [^DB db ^String collection ^Map conditions ^Map document & {:keys [multi write-concern] :or {multi false - write-concern monger.core/*mongodb-write-concern*}}] - (update db collection conditions document :multi multi :write-concern write-concern :upsert true)) - -(defn ^WriteResult update-by-id - "Like monger.collection/update-by-id but always takes a database as explicit argument" - [^DB db ^String collection id ^Map document & {:keys [upsert write-concern] :or {upsert false - write-concern monger.core/*mongodb-write-concern*}}] - (check-not-nil! id "id must not be nil") - (.update (.getCollection db (name collection)) - (to-db-object {:_id id}) - (to-db-object document) - upsert - false - write-concern)) - -(defn ^WriteResult save - "Like monger.collection/save but always takes a database as explicit argument" - ([^DB db ^String collection ^Map document] - (.save (.getCollection db (name collection)) - (to-db-object document) - monger.core/*mongodb-write-concern*)) - ([^DB db ^String collection ^Map document ^WriteConcern write-concern] - (.save (.getCollection db (name collection)) - (to-db-object document) - write-concern))) - -(defn ^clojure.lang.IPersistentMap save-and-return - "Like monger.collection/save-and-return but always takes a database as explicit argument" - ([^DB db ^String collection ^Map document] - (save-and-return ^DB db collection document ^WriteConcern monger.core/*mongodb-write-concern*)) - ([^DB db ^String collection ^Map document ^WriteConcern write-concern] - ;; see the comment in insert-and-return. Here we additionally need to make sure to not scrap the :_id key if - ;; it is already present. MK. - (let [doc (merge {:_id (ObjectId.)} document)] - (save db collection doc write-concern) - doc))) - -(defn ^WriteResult remove - "Like monger.collection/remove but always takes a database as explicit argument" - ([^DB db ^String collection] - (.remove (.getCollection db (name collection)) (to-db-object {}))) - ([^DB db ^String collection ^Map conditions] - (.remove (.getCollection db (name collection)) (to-db-object conditions)))) - -(defn ^WriteResult remove-by-id - "Like monger.collection/remove-by-id but always takes a database as explicit argument" - ([^DB db ^String collection id] - (check-not-nil! id "id must not be nil") - (let [coll (.getCollection db (name collection))] - (.remove coll (to-db-object {:_id id}))))) - -;; -;; monger.multi.collection/create-index -;; - -(defn create-index - "Like monger.collection/create-index but always takes a database as explicit argument" - ([^DB db ^String collection ^Map keys] - (.createIndex (.getCollection db (name collection)) (as-field-selector keys))) - ([^DB db ^String collection ^Map keys ^Map options] - (.createIndex (.getCollection db (name collection)) - (as-field-selector keys) - (to-db-object options)))) - -;; -;; monger.multi.collection/ensure-index -;; - -(defn ensure-index - "Like monger.collection/ensure-index but always takes a database as explicit argument" - ([^DB db ^String collection ^Map keys] - (.ensureIndex (.getCollection db (name collection)) (as-field-selector keys))) - ([^DB db ^String collection ^Map keys ^Map options] - (.ensureIndex (.getCollection db (name collection)) - (as-field-selector keys) - (to-db-object options))) - ([^DB db ^String collection ^Map keys ^String name ^Boolean unique?] - (.ensureIndex (.getCollection db (name collection)) - (as-field-selector keys) - name - unique?))) - -;; -;; monger.multi.collection/indexes-on -;; - -(defn indexes-on - "Like monger.collection/indexes-on but always takes a database as explicit argument" - [^DB db ^String collection] - (from-db-object (.getIndexInfo (.getCollection db (name collection))) true)) - - -;; -;; monger.multi.collection/drop-index -;; - -(defn drop-index - "Like monger.collection/drop-index but always takes a database as explicit argument" - ([^DB db ^String collection ^String idx-name] - (.dropIndex (.getCollection db (name collection)) idx-name))) - -(defn drop-indexes - "Like monger.collection/drop-indexes but always takes a database as explicit argument" - ([^DB db ^String collection] - (.dropIndexes (.getCollection db (name collection))))) - - -;; -;; monger.multi.collection/exists?, /create, /drop, /rename -;; - - -(defn exists? - "Like monger.collection/exists? but always takes a database as explicit argument" - ([^DB db ^String collection] - (.collectionExists db collection))) - -(defn create - "Like monger.collection/create but always takes a database as explicit argument" - ([^DB db ^String collection ^Map options] - (.createCollection db collection (to-db-object options)))) - -(defn drop - "Like monger.collection/drop but always takes a database as explicit argument" - ([^DB db ^String collection] - (.drop (.getCollection db (name collection))))) - -(defn rename - "Like monger.collection/rename but always takes a database as explicit argument" - ([^DB db ^String from, ^String to] - (.rename (.getCollection db from) to)) - ([^DB db ^String from ^String to ^Boolean drop-target] - (.rename (.getCollection db from) to drop-target))) - -;; -;; Map/Reduce -;; - -(defn map-reduce - "Like monger.collection/map-reduce but always takes a database as explicit argument" - ([^DB db ^String collection ^String js-mapper ^String js-reducer ^String output ^Map query] - (let [coll (.getCollection db (name collection))] - (.mapReduce coll js-mapper js-reducer output (to-db-object query)))) - ([^DB db ^String collection ^String js-mapper ^String js-reducer ^String output ^MapReduceCommand$OutputType output-type ^Map query] - (let [coll (.getCollection db (name collection))] - (.mapReduce coll js-mapper js-reducer output output-type (to-db-object query))))) - - -;; -;; monger.multi.collection/distinct -;; - -(defn distinct - "Like monger.collection/distinct but always takes a database as explicit argument" - ([^DB db ^String collection ^String key] - (.distinct (.getCollection db (name collection)) ^String (to-db-object key))) - ([^DB db ^String collection ^String key ^Map query] - (.distinct (.getCollection db (name collection)) ^String (to-db-object key) (to-db-object query)))) diff --git a/test/monger/test/multi/atomic_modifiers_test.clj b/test/monger/test/multi/atomic_modifiers_test.clj deleted file mode 100644 index 4abb5c2..0000000 --- a/test/monger/test/multi/atomic_modifiers_test.clj +++ /dev/null @@ -1,409 +0,0 @@ -(ns monger.test.multi.atomic-modifiers-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject] - [org.bson.types ObjectId] - [java.util Date]) - (:require [monger.core :as mg] - [monger core util] - [monger.multi.collection :as mc] - [monger.result :as mgres] - [monger.test.helper :as helper] - [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) - -(helper/connect!) - -(def db (mg/get-db "altdb")) - -(defn purge-altdb - [f] - (mc/remove db "scores") - (mc/remove db "things") - (mc/remove db "docs") - (f)) - -(use-fixtures :each purge-altdb) - -;; -;; $inc -;; - -(deftest increment-a-single-existing-field-using-$inc-modifier - (let [db (mg/get-db "altdb") - coll "scores" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :username "l33r0y" :score 100 }) - (mc/update db coll { :_id oid } { $inc { :score 20 } }) - (is (= 120 (:score (mc/find-map-by-id db coll oid)))))) - -(deftest set-a-single-non-existing-field-using-$inc-modifier - (let [db (mg/get-db "altdb") - coll "scores" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :username "l33r0y" }) - (mc/update db coll { :_id oid } { $inc { :score 30 } }) - (is (= 30 (:score (mc/find-map-by-id db coll oid)))))) - - -(deftest increment-multiple-existing-fields-using-$inc-modifier - (let [db (mg/get-db "altdb") - coll "scores" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :username "l33r0y" :score 100 :bonus 0 }) - (mc/update db coll { :_id oid } {$inc { :score 20 :bonus 10 } }) - (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mc/find-map-by-id db coll oid))))) - - -(deftest increment-and-set-multiple-existing-fields-using-$inc-modifier - (let [db (mg/get-db "altdb") - coll "scores" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :username "l33r0y" :score 100 }) - (mc/update db coll { :_id oid } { $inc { :score 20 :bonus 10 } }) - (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mc/find-map-by-id db coll oid))))) - - - -;; -;; $set -;; - -(deftest update-a-single-existing-field-using-$set-modifier - (let [db (mg/get-db "altdb") - coll "things" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :weight 10.0 }) - (mc/update db coll { :_id oid } { $set { :weight 20.5 } }) - (is (= 20.5 (:weight (mc/find-map-by-id db coll oid [:weight])))))) - -(deftest set-a-single-non-existing-field-using-$set-modifier - (let [db (mg/get-db "altdb") - coll "things" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :weight 10.0 }) - (mc/update db coll { :_id oid } { $set { :height 17.2 } }) - (is (= 17.2 (:height (mc/find-map-by-id db coll oid [:height])))))) - -(deftest update-multiple-existing-fields-using-$set-modifier - (let [db (mg/get-db "altdb") - coll "things" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :weight 10.0 :height 15.2 }) - (mc/update db coll { :_id oid } { $set { :weight 20.5 :height 25.6 } }) - (is (= { :_id oid :weight 20.5 :height 25.6 } (mc/find-map-by-id db coll oid [:weight :height]))))) - - -(deftest update-and-set-multiple-fields-using-$set-modifier - (let [db (mg/get-db "altdb") - coll "things" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :weight 10.0 }) - (mc/update db coll { :_id oid } {$set { :weight 20.5 :height 25.6 } }) - (is (= { :_id oid :weight 20.5 :height 25.6 } (mc/find-map-by-id db coll oid [:weight :height]))))) - - -;; -;; $unset -;; - -(deftest unset-a-single-existing-field-using-$unset-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :title "Document 1" :published true }) - (mc/update db coll { :_id oid } { $unset { :published 1 } }) - (is (= { :_id oid :title "Document 1" } (mc/find-map-by-id db coll oid))))) - - -(deftest unset-multiple-existing-fields-using-$unset-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :title "Document 1" :published true :featured true }) - (mc/update db coll { :_id oid } { $unset { :published 1 :featured true } }) - (is (= { :_id oid :title "Document 1" } (mc/find-map-by-id db coll oid))))) - - -(deftest unsetting-an-unexisting-field-using-$unset-modifier-is-not-considered-an-issue - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.)] - (mc/insert db coll { :_id oid :title "Document 1" :published true }) - (is (mgres/ok? (mc/update db coll { :_id oid } { $unset { :published 1 :featured true } }))) - (is (= { :_id oid :title "Document 1" } (mc/find-map-by-id db coll oid))))) - -;; -;; $setOnInsert -;; - -(deftest setOnInsert-in-upsert-for-non-existing-document - (let [db (mg/get-db "altdb") - coll "docs" - now 456 - oid (ObjectId.)] - (mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true) - (is (= { :_id oid :lastseen now :firstseen now} (mc/find-map-by-id db coll oid))))) - -(deftest setOnInsert-in-upsert-for-existing-document - (let [db (mg/get-db "altdb") - coll "docs" - before 123 - now 456 - oid (ObjectId.)] - (mc/insert db coll { :_id oid :firstseen before :lastseen before}) - (mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true) - (is (= { :_id oid :lastseen now :firstseen before} (mc/find-map-by-id db coll oid))))) - -;; -;; $push -;; - -(deftest initialize-an-array-using-$push-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mc/insert db coll { :_id oid :title title }) - (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["modifiers"] } (mc/find-map-by-id db coll oid))))) - -(deftest add-value-to-an-existing-array-using-$push-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) - (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mc/find-map-by-id db coll oid))))) - - -;; this is a common mistake, I leave it here to demonstrate it. You almost never -;; actually want to do this! What you really want is to use $pushAll instead of $push. MK. -(deftest add-array-value-to-an-existing-array-using-$push-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) - (mc/update db coll { :_id oid } { $push { :tags ["modifiers" "operators"] } }) - (is (= { :_id oid :title title :tags ["mongodb" ["modifiers" "operators"]] } (mc/find-map-by-id db coll oid))))) - - - -(deftest double-add-value-to-an-existing-array-using-$push-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) - (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) - (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers" "modifiers"] } (mc/find-map-by-id db coll oid))))) - -;; -;; $pushAll -;; - -(deftest initialize-an-array-using-$pushAll-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pushAll modifier appends multiple values to field"] - (mc/insert db coll { :_id oid :title title }) - (mc/update db coll { :_id oid } { $pushAll { :tags ["mongodb" "docs"] } }) - (is (= { :_id oid :title title :tags ["mongodb" "docs"] } (mc/find-map-by-id db coll oid))))) - -(deftest add-value-to-an-existing-array-using-$pushAll-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pushAll modifier appends multiple values to field"] - (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) - (mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers" "docs"] } (mc/find-map-by-id db coll oid))))) - - -(deftest double-add-value-to-an-existing-array-using-$pushAll-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pushAll modifier appends multiple values to field"] - (mc/insert db coll { :_id oid :title title :tags ["mongodb" "docs"] }) - (mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } }) - (is (= { :_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"] } (mc/find-map-by-id db coll oid))))) - - -;; -;; $addToSet -;; - -(deftest initialize-an-array-using-$addToSet-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$addToSet modifier appends value to field unless it is already there"] - (mc/insert db coll { :_id oid :title title }) - (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["modifiers"] } (mc/find-map-by-id db coll oid))))) - -(deftest add-value-to-an-existing-array-using-$addToSet-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$addToSet modifier appends value to field unless it is already there"] - (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) - (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mc/find-map-by-id db coll oid))))) - - -(deftest double-add-value-to-an-existing-array-using-$addToSet-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$addToSet modifier appends value to field unless it is already there"] - (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) - (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mc/find-map-by-id db coll oid))))) - - -;; -;; $pop -;; - -(deftest pop-last-value-in-the-array-using-$pop-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pop modifier removes last or first value in the array"] - (mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] }) - (mc/update db coll { :_id oid } { $pop { :tags 1 } }) - (is (= { :_id oid :title title :tags ["products" "apple"] } (mc/find-map-by-id db coll oid))))) - -(deftest unshift-first-value-in-the-array-using-$pop-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pop modifier removes last or first value in the array"] - (mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] }) - (mc/update db coll { :_id oid } { $pop { :tags -1 } }) - (is (= { :_id oid :title title :tags ["apple" "reviews"] } (mc/find-map-by-id db coll oid))))) - -(deftest pop-last-values-from-multiple-arrays-using-$pop-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pop modifier removes last or first value in the array"] - (mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] :categories ["apple" "reviews" "drafts"] }) - (mc/update db coll { :_id oid } { $pop { :tags 1 :categories 1 } }) - (is (= { :_id oid :title title :tags ["products" "apple"] :categories ["apple" "reviews"] } (mc/find-map-by-id db coll oid))))) - - -;; -;; $pull -;; - -(deftest remove-all-value-entries-from-array-using-$pull-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pull modifier removes all value entries in the array"] - (mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) - (mc/update db coll { :_id oid } { $pull { :measurements 1.2 } }) - (is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.3 1.0] } (mc/find-map-by-id db coll oid))))) - -(deftest remove-all-value-entries-from-array-using-$pull-modifier-based-on-a-condition - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pull modifier removes all value entries in the array"] - (mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) - (mc/update db coll { :_id oid } { $pull { :measurements { $gte 1.2 } } }) - (is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.0] } (mc/find-map-by-id db coll oid))))) -;; -;; $pullAll -;; - -(deftest remove-all-value-entries-from-array-using-$pullAll-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$pullAll modifier removes entries of multiple values in the array"] - (mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) - (mc/update db coll { :_id oid } { $pullAll { :measurements [1.0 1.1 1.2] } }) - (is (= { :_id oid :title title :measurements [1.3] } (mc/find-map-by-id db coll oid))))) - - -;; -;; $rename -;; - -(deftest rename-a-single-field-using-$rename-modifier - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - title "$rename renames fields" - v [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0]] - (mc/insert db coll { :_id oid :title title :measurements v }) - (mc/update db coll { :_id oid } { $rename { :measurements "results" } }) - (is (= { :_id oid :title title :results v } (mc/find-map-by-id db coll oid))))) - - -;; -;; find-and-modify -;; - -(deftest find-and-modify-a-single-document - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - doc {:_id oid :name "Sophie Bangs" :level 42} - conditions {:name "Sophie Bangs"} - update {$inc {:level 1}}] - (mc/insert db coll doc) - (let [res (mc/find-and-modify db coll conditions update :return-new true)] - (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 43}))))) - - -(deftest find-and-modify-remove-a-document - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - doc {:_id oid :name "Sophie Bangs" :level 42} - conditions {:name "Sophie Bangs"}] - (mc/insert db coll doc) - (let [res (mc/find-and-modify db coll conditions {} :remove true)] - (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42})) - (is (empty? (mc/find-maps db coll conditions)))))) - - -(deftest find-and-modify-upsert-a-document - (testing "case 1" - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - doc {:_id oid :name "Sophie Bangs" :level 42}] - (let [res (mc/find-and-modify db coll doc doc :upsert true)] - (is (empty? res)) - (is (select-keys (mc/find-map-by-id db coll oid) [:name :level]) (dissoc doc :_id))))) - (testing "case 2" - (let [db (mg/get-db "altdb") - coll "docs" - query {:name "Sophie Bangs"} - doc (merge query {:level 42})] - (let [res (mc/find-and-modify db coll query doc :upsert true :return-new true)] - (is (:_id res)) - (is (select-keys (mc/find-map-by-id db coll (:_id res)) [:name :level]) doc))))) - - -(deftest find-and-modify-after-sort - (let [db (mg/get-db "altdb") - coll "docs" - oid (ObjectId.) - oid2 (ObjectId.) - doc {:name "Sophie Bangs"} - doc1 (assoc doc :_id oid :level 42) - doc2 (assoc doc :_id oid2 :level 0)] - (mc/insert-batch db coll [doc1 doc2]) - (let [res (mc/find-and-modify db coll doc {$inc {:level 1}} :sort {:level -1})] - (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42}))))) diff --git a/test/monger/test/multi/collection_test.clj b/test/monger/test/multi/collection_test.clj deleted file mode 100644 index 52216f5..0000000 --- a/test/monger/test/multi/collection_test.clj +++ /dev/null @@ -1,133 +0,0 @@ -(ns monger.test.multi.collection-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType] - org.bson.types.ObjectId - java.util.Date) - (:require [monger.core :as mg] - [monger.multi.collection :as mc] - [monger.result :as mgres] - [monger.test.helper :as helper] - [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) - -(helper/connect!) - -(def db (mg/get-db "altdb")) - -(defn purge-altdb - [f] - (mc/remove db "things") - (mc/remove db "libraries") - (f)) - -(use-fixtures :each purge-altdb) - -(deftest get-collection-size - (let [db (mg/get-db "altdb") - collection "things"] - (is (= 0 (mc/count db collection))) - (mc/insert-batch db collection [{:language "Clojure" :name "langohr"} - {:language "Clojure" :name "monger"} - {:language "Clojure" :name "incanter"} - {:language "Scala" :name "akka"}]) - (is (= 4 (mc/count db collection))) - (is (mc/any? db collection)) - (is (= 3 (mc/count db collection {:language "Clojure"}))) - (is (mc/any? db collection {:language "Clojure"})) - (is (= 1 (mc/count db collection {:language "Scala" }))) - (is (mc/any? db collection {:language "Scala"})) - (is (= 0 (mc/count db collection {:language "Python" }))) - (is (not (mc/any? db collection {:language "Python"}))))) - -(deftest remove-all-documents-from-collection - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{:language "Clojure" :name "monger"} - {:language "Clojure" :name "langohr"} - {:language "Clojure" :name "incanter"} - {:language "Scala" :name "akka"}]) - (is (= 4 (mc/count db collection))) - (mc/remove db collection) - (is (= 0 (mc/count db collection))))) - -(deftest remove-some-documents-from-collection - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{:language "Clojure" :name "monger"} - {:language "Clojure" :name "langohr"} - {:language "Clojure" :name "incanter"} - {:language "Scala" :name "akka"}]) - (is (= 4 (mc/count db collection))) - (mc/remove db collection {:language "Clojure"}) - (is (= 1 (mc/count db collection))))) - -(deftest remove-a-single-document-from-collection - (let [db (mg/get-db "altdb") - collection "libraries" - oid (ObjectId.)] - (mc/insert-batch db collection [{:language "Clojure" :name "monger" :_id oid}]) - (mc/remove-by-id db collection oid) - (is (= 0 (mc/count db collection))) - (is (nil? (mc/find-by-id db collection oid))))) - -(deftest checking-for-collection-existence-when-it-does-not-exist - (let [db (mg/get-db "altdb") - collection "widgets"] - (mc/drop db collection) - (is (false? (mc/exists? db collection))))) - -(deftest checking-for-collection-existence-when-it-does-exist - (let [db (mg/get-db "altdb") - collection "widgets"] - (mc/drop db collection) - (mc/insert-batch db collection [{:name "widget1"} - {:name "widget2"}]) - (is (mc/exists? db collection)) - (mc/drop db collection) - (is (false? (mc/exists? db collection))) - (mc/create db "widgets" {:capped true :size 100000 :max 10}) - (is (mc/exists? db collection)) - (mc/rename db collection "gadgets") - (is (not (mc/exists? db collection))) - (is (mc/exists? db "gadgets")) - (mc/drop db "gadgets"))) - -(deftest test-any-on-empty-collection - (let [db (mg/get-db "altdb") - collection "things"] - (is (not (mc/any? db collection))))) - -(deftest test-any-on-non-empty-collection - (let [db (mg/get-db "altdb") - collection "things" - _ (mc/insert db collection {:language "Clojure" :name "langohr"})] - (is (mc/any? db "things")) - (is (mc/any? db "things" {:language "Clojure"})))) - -(deftest test-empty-on-empty-collection - (let [db (mg/get-db "altdb") - collection "things"] - (is (mc/empty? db collection)) - (is (mc/empty? db collection)))) - -(deftest test-empty-on-non-empty-collection - (let [db (mg/get-db "altdb") - collection "things" - _ (mc/insert db collection {:language "Clojure" :name "langohr"})] - (is (not (mc/empty? db "things"))))) - -(deftest test-distinct-values - (let [db (mg/get-db "altdb") - collection "widgets" - batch [{:state "CA" :quantity 1 :price 199.00} - {:state "NY" :quantity 2 :price 199.00} - {:state "NY" :quantity 1 :price 299.00} - {:state "IL" :quantity 2 :price 11.50 } - {:state "CA" :quantity 2 :price 2.95 } - {:state "IL" :quantity 3 :price 5.50 }]] - (mc/insert-batch db collection batch) - (is (= ["CA" "IL" "NY"] (sort (mc/distinct db collection :state {})))) - (is (= ["CA" "NY"] (sort (mc/distinct db collection :state {:price {$gt 100.00}})))))) - - -(run-tests) diff --git a/test/monger/test/multi/find_test.clj b/test/monger/test/multi/find_test.clj deleted file mode 100644 index e07e7e4..0000000 --- a/test/monger/test/multi/find_test.clj +++ /dev/null @@ -1,149 +0,0 @@ -(ns monger.test.multi.find-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject DBRef] - org.bson.types.ObjectId - java.util.Date) - (:require [monger.core :as mg] - [monger.util :as mu] - [monger.multi.collection :as mc] - [monger.test.helper :as helper] - [monger.conversion :as mgcnv] - [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all] - [monger.conversion :refer :all])) - -(helper/connect!) - -(def db (mg/get-db "altdb")) - -(defn purge-altdb - [f] - (mc/remove db "libraries") - (mc/remove db "docs") - (f)) - -(use-fixtures :each purge-altdb) - -;; -;; find -;; - -(deftest find-full-document-when-collection-is-empty - (let [db (mg/get-db "altdb") - collection "docs" - cursor (mc/find db collection)] - (is (empty? (iterator-seq cursor))))) - -(deftest find-document-seq-when-collection-is-empty - (let [db (mg/get-db "altdb") - collection "docs"] - (is (empty? (mc/find-seq db collection))))) - -(deftest find-multiple-documents-when-collection-is-empty - (let [db (mg/get-db "altdb") - collection "libraries"] - (is (empty? (mc/find db collection { :language "Scala" }))))) - -(deftest find-multiple-maps-when-collection-is-empty - (let [db (mg/get-db "altdb") - collection "libraries"] - (is (empty? (mc/find-maps db collection { :language "Scala" }))))) - -(deftest find-multiple-documents-by-regex - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Java", :name "nhibernate" } - { :language "JavaScript", :name "sprout-core" }]) - (is (= 2 (monger.core/count (mc/find db collection { :language #"Java*" })))))) - -(deftest find-multiple-documents - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (is (= 1 (monger.core/count (mc/find db collection { :language "Scala" })))) - (is (= 3 (.count (mc/find db collection { :language "Clojure" })))) - (is (empty? (mc/find db collection { :language "Java" }))))) - - -(deftest find-document-specify-fields - (let [db (mg/get-db "altdb") - collection "libraries" - _ (mc/insert db collection { :language "Clojure", :name "monger" }) - result (mc/find db collection { :language "Clojure"} [:language])] - (is (= (seq [:_id :language]) (keys (mgcnv/from-db-object (.next result) true)))))) - -(deftest find-and-iterate-over-multiple-documents-the-hard-way - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (doseq [doc (take 3 (map (fn [dbo] - (mgcnv/from-db-object dbo true)) - (mc/find-seq db collection { :language "Clojure" })))] - (is (= "Clojure" (:language doc)))))) - -(deftest find-and-iterate-over-multiple-documents - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (doseq [doc (take 3 (mc/find-maps db collection { :language "Clojure" }))] - (is (= "Clojure" (:language doc)))))) - - -(deftest find-multiple-maps - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (is (= 1 (count (mc/find-maps db collection { :language "Scala" })))) - (is (= 3 (count (mc/find-maps db collection { :language "Clojure" })))) - (is (empty? (mc/find-maps db collection { :language "Java" }))) - (is (empty? (mc/find-maps db collection { :language "Java" } [:language :name]))))) - - - -(deftest find-multiple-partial-documents - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (let [scala-libs (mc/find db collection { :language "Scala" } [:name]) - clojure-libs (mc/find db collection { :language "Clojure"} [:language])] - (is (= 1 (.count scala-libs))) - (is (= 3 (.count clojure-libs))) - (doseq [i clojure-libs] - (let [doc (mgcnv/from-db-object i true)] - (is (= (:language doc) "Clojure")))) - (is (empty? (mc/find db collection { :language "Erlang" } [:name])))))) - -(deftest finds-one-as-map - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" }]) - (let [res (mc/find-one-as-map db collection { :name "langohr" })] - (is (map? res)) - (is (= "langohr" (:name res))) - (is (= "Clojure" (:language res)))) - (is (= 2 (count (mc/find-one-as-map db collection { :name "langohr" } [:name])))) - (is (= "langohr" (get (mc/find-one-as-map db collection { :name "langohr" } [:name] false) "name"))))) - -(deftest find-and-modify - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" }]))) - diff --git a/test/monger/test/multi/indexing_test.clj b/test/monger/test/multi/indexing_test.clj deleted file mode 100644 index 9d93794..0000000 --- a/test/monger/test/multi/indexing_test.clj +++ /dev/null @@ -1,60 +0,0 @@ -(ns monger.test.multi.indexing-test - (:import org.bson.types.ObjectId - java.util.Date) - (:require [monger.core :as mg] - [monger.multi.collection :as mc] - [monger.test.helper :as helper] - monger.joda-time - [clojure.test :refer :all] - [monger.test.fixtures :refer :all] - [clj-time.core :refer [now secs ago from-now]])) - -(helper/connect!) - -(def db (mg/get-db "altdb")) - -(defn purge-altdb - [f] - (mc/remove db "libraries") - (mc/remove db "recent_events") - (f)) - -(use-fixtures :each purge-altdb) - -(deftest ^{:indexing true} test-creating-and-dropping-indexes - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/drop-indexes db collection) - (mc/create-index db collection { "language" 1 }) - (is (= "language_1" - (:name (second (mc/indexes-on db collection))))) - (mc/drop-index db collection "language_1") - (mc/create-index db collection ["language"]) - (mc/drop-index db collection "language_1") - (is (nil? (second (mc/indexes-on db collection)))) - (mc/ensure-index db collection (array-map "language" 1) {:unique true}) - (is (= "language_1" - (:name (second (mc/indexes-on db collection))))) - (mc/ensure-index db collection (array-map "language" 1)) - (mc/ensure-index db collection (array-map "language" 1) { :unique true }) - (mc/drop-indexes db collection))) - -(deftest ^{:indexing true :edge-features true :time-consuming true} test-ttl-collections - (let [db (mg/get-db "altdb") - coll "recent_events" - ttl 30 - sleep 120] - (mc/remove db coll) - (mc/ensure-index db coll (array-map :created-at 1) {:expireAfterSeconds ttl}) - (dotimes [i 100] - (mc/insert db coll {:type "signup" :created-at (-> i secs ago) :i i})) - (dotimes [i 100] - (mc/insert db coll {:type "signup" :created-at (-> i secs from-now) :i i})) - (is (= 200 (mc/count db coll {:type "signup"}))) - ;; sleep for 65 seconds. MongoDB 2.1.2 seems to run TTLMonitor once per minute, according to - ;; the log. MK. - (println (format "Now sleeping for %d seconds to test TTL collections!" sleep)) - (Thread/sleep (* sleep 1000)) - (println (format "Documents in the TTL collection: %d" (mc/count db coll {:type "signup"}))) - (is (< (mc/count db coll {:type "signup"}) 100)) - (mc/remove db coll))) diff --git a/test/monger/test/multi/inserting_test.clj b/test/monger/test/multi/inserting_test.clj deleted file mode 100644 index a140b33..0000000 --- a/test/monger/test/multi/inserting_test.clj +++ /dev/null @@ -1,192 +0,0 @@ -(ns monger.test.multi.inserting-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject DBRef] - org.bson.types.ObjectId - java.util.Date) - (:require [monger.core :as mg] - [monger.util :as mu] - [monger.multi.collection :as mc] - [monger.test.helper :as helper] - [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.conversion :refer :all] - [monger.test.fixtures :refer :all])) - -(helper/connect!) - -(def db (mg/get-db "altdb")) - -(defn purge-altdb - [f] - (mc/remove db "people") - (mc/remove db "widgets") - (f)) - -(use-fixtures :each purge-altdb) - -;; -;; insert -;; - -(deftest insert-a-basic-document-without-id-and-with-default-write-concern - (let [db (mg/get-db "altdb") - collection "people" - doc {:name "Joe" :age 30}] - (is (monger.result/ok? (mc/insert db "people" doc))) - (is (= 1 (mc/count db collection))))) - -(deftest insert-a-basic-document-with-explicitly-passed-database-without-id-and-with-default-write-concern - (let [db (mg/get-db "altdb") - collection "people" - doc {:name "Joe" :age 30}] - (dotimes [n 5] - (is (monger.result/ok? (mc/insert db "people" doc WriteConcern/SAFE)))) - (is (= 5 (mc/count db collection))))) - -(deftest insert-a-basic-document-without-id-and-with-explicit-write-concern - (let [db (mg/get-db "altdb") - collection "people" - doc {:name "Joe" :age 30}] - (is (monger.result/ok? (mc/insert db "people" doc WriteConcern/SAFE))) - (is (= 1 (mc/count db collection))))) - -(deftest insert-a-basic-db-object-without-id-and-with-default-write-concern - (let [db (mg/get-db "altdb") - collection "people" - doc (to-db-object {:name "Joe" :age 30})] - (is (nil? (.get ^DBObject doc "_id"))) - (mc/insert db "people" doc) - (is (not (nil? (monger.util/get-id doc)))))) - -(deftest insert-a-map-with-id-and-with-default-write-concern - (let [db (mg/get-db "altdb") - collection "people" - id (ObjectId.) - doc {:name "Joe" :age 30 "_id" id} - result (mc/insert db "people" doc)] - (is (= id (monger.util/get-id doc))))) - -(deftest insert-a-document-with-clojure-ratio-in-it - (let [db (mg/get-db "altdb") - collection "widgets" - id (ObjectId.) - doc {:ratio 11/2 "_id" id} - result (mc/insert db "widgets" doc)] - (is (= 5.5 (:ratio (mc/find-map-by-id db collection id)))))) - -(deftest insert-a-document-with-clojure-keyword-in-it - (let [db (mg/get-db "altdb") - collection "widgets" - id (ObjectId.) - doc {:keyword :kwd "_id" id} - result (mc/insert db "widgets" doc)] - (is (= (name :kwd) (:keyword (mc/find-map-by-id db collection id)))))) - -(deftest insert-a-document-with-clojure-keyword-in-a-set-in-it - (let [db (mg/get-db "altdb") - collection "widgets" - id (ObjectId.) - doc {:keyword1 {:keyword2 #{:kw1 :kw2}} "_id" id} - result (mc/insert db "widgets" doc)] - (is (= (sort ["kw1" "kw2"]) - (sort (get-in (mc/find-map-by-id db collection id) [:keyword1 :keyword2])))))) - -(defrecord Metrics - [rps eps]) - -(deftest insert-a-document-with-clojure-record-in-it - (let [db (mg/get-db "altdb") - collection "widgets" - id (ObjectId.) - doc {:record (Metrics. 10 20) "_id" id} - result (mc/insert db "widgets" doc)] - (is (= {:rps 10 :eps 20} (:record (mc/find-map-by-id db collection id)))))) - -(deftest test-insert-a-document-with-dbref - (let [db (mg/get-db "altdb")] - (mc/remove db "widgets") - (mc/remove db "owners") - (let [coll1 "widgets" - coll2 "owners" - oid (ObjectId.) - joe (mc/insert db "owners" {:name "Joe" :_id oid}) - dbref (DBRef. (mg/current-db) coll2 oid)] - (mc/insert db coll1 {:type "pentagon" :owner dbref}) - (let [fetched (mc/find-one-as-map db coll1 {:type "pentagon"}) - fo (:owner fetched)] - (is (= {:_id oid :name "Joe"} (from-db-object @fo true))))))) - - -;; -;; insert-and-return -;; - -(deftest insert-and-return-a-basic-document-without-id-and-with-default-write-concern - (let [db (mg/get-db "altdb") - collection "people" - doc {:name "Joe" :age 30} - result (mc/insert-and-return db :people doc)] - (is (= (:name doc) - (:name result))) - (is (= (:age doc) - (:age result))) - (is (:_id result)) - (is (= 1 (mc/count db collection))))) - -(deftest insert-and-return-a-basic-document-without-id-but-with-a-write-concern - (let [db (mg/get-db "altdb") - collection "people" - doc {:name "Joe" :age 30 :ratio 3/4} - result (mc/insert-and-return db "people" doc WriteConcern/FSYNC_SAFE)] - (is (= (:name doc) - (:name result))) - (is (= (:age doc) - (:age result))) - (is (= (:ratio doc) - (:ratio result))) - (is (:_id result)) - (is (= 1 (mc/count db collection))))) - -(deftest insert-and-return-with-a-provided-id - (let [db (mg/get-db "altdb") - collection "people" - oid (ObjectId.) - doc {:name "Joe" :age 30 :_id oid} - result (mc/insert-and-return db :people doc)] - (is (= (:_id result) (:_id doc) oid)) - (is (= 1 (mc/count db collection))))) - - -;; -;; insert-batch -;; - -(deftest insert-a-batch-of-basic-documents-without-ids-and-with-default-write-concern - (let [db (mg/get-db "altdb") - collection "people" - docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] - (is (monger.result/ok? (mc/insert-batch db "people" docs))) - (is (= 2 (mc/count db collection))))) - -(deftest insert-a-batch-of-basic-documents-without-ids-and-with-explicit-write-concern - (let [db (mg/get-db "altdb") - collection "people" - docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] - (is (monger.result/ok? (mc/insert-batch db "people" docs WriteConcern/NORMAL))) - (is (= 2 (mc/count db collection))))) - -(deftest insert-a-batch-of-basic-documents-with-explicit-database-without-ids-and-with-explicit-write-concern - (let [db (mg/get-db "altdb") - collection "people" - docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] - (dotimes [n 44] - (is (monger.result/ok? (mc/insert-batch db "people" docs WriteConcern/NORMAL)))) - (is (= 88 (mc/count db collection))))) - -(deftest insert-a-batch-of-basic-documents-from-a-lazy-sequence - (let [db (mg/get-db "altdb") - collection "people" - numbers (range 0 1000)] - (is (monger.result/ok? (mc/insert-batch db "people" (map (fn [^long l] - {:n l}) - numbers)))) - (is (= (count numbers) (mc/count db collection))))) diff --git a/test/monger/test/multi/updating_test.clj b/test/monger/test/multi/updating_test.clj deleted file mode 100644 index de0295c..0000000 --- a/test/monger/test/multi/updating_test.clj +++ /dev/null @@ -1,186 +0,0 @@ -(ns monger.test.multi.updating-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject] - org.bson.types.ObjectId - java.util.Date) - (:require [monger.core :as mg] - [monger core util] - [monger.multi.collection :as mc] - [monger.result :as mr] - [monger.test.helper :as helper] - [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all] - [monger.conversion :refer [to-db-object]])) - -(helper/connect!) - -(def db (mg/get-db "altdb")) - -(defn purge-altdb - [f] - (mc/remove db "libraries") - (mc/remove db "people") - (mc/remove db "matches") - (f)) - -(use-fixtures :each purge-altdb) - - -;; -;; update, save -;; - -(deftest ^{:updating true} update-document-by-id-without-upsert - (let [db (mg/get-db "altdb") - collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } - modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] - (mc/insert db collection doc) - (is (= (doc (mc/find-by-id db collection doc-id)))) - (mc/update db collection { :_id doc-id } { :language "Erlang" }) - (is (= (modified-doc (mc/find-by-id db collection doc-id)))))) - -(deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id - (let [db (mg/get-db "altdb") - collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } - modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] - (mc/insert db collection doc) - (is (= (doc (mc/find-by-id db collection doc-id)))) - (mc/update-by-id db collection doc-id { :language "Erlang" }) - (is (= (modified-doc (mc/find-by-id db collection doc-id)))))) - -(deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id - (let [db (mg/get-db "altdb") - collection "libraries" - doc-id (ObjectId.) - date (Date.) - doc { :created-at date :data-store "MongoDB" :language { :primary "Clojure" } :_id doc-id } - modified-doc { :created-at date :data-store "MongoDB" :language { :primary "Erlang" } :_id doc-id }] - (mc/insert db collection doc) - (is (= (doc (mc/find-by-id db collection doc-id)))) - (mc/update-by-id db collection doc-id { $set { "language.primary" "Erlang" }}) - (is (= (modified-doc (mc/find-by-id db collection doc-id)))))) - - -(deftest ^{:updating true} update-multiple-documents - (let [db (mg/get-db "altdb") - collection "libraries"] - (mc/insert db collection { :language "Clojure", :name "monger" }) - (mc/insert db collection { :language "Clojure", :name "langohr" }) - (mc/insert db collection { :language "Clojure", :name "incanter" }) - (mc/insert db collection { :language "Scala", :name "akka" }) - (is (= 3 (mc/count db collection { :language "Clojure" }))) - (is (= 1 (mc/count db collection { :language "Scala" }))) - (is (= 0 (mc/count db collection { :language "Python" }))) - (mc/update db collection { :language "Clojure" } { $set { :language "Python" } } :multi true) - (is (= 0 (mc/count db collection { :language "Clojure" }))) - (is (= 1 (mc/count db collection { :language "Scala" }))) - (is (= 3 (mc/count db collection { :language "Python" }))))) - - -(deftest ^{:updating true} save-a-new-document - (let [db (mg/get-db "altdb") - collection "people" - document {:name "Joe" :age 30}] - (is (mr/ok? (mc/save db "people" document))) - (is (= 1 (mc/count db collection))))) - -(deftest ^{:updating true} save-and-return-a-new-document - (let [db (mg/get-db "altdb") - collection "people" - document {:name "Joe" :age 30} - returned (mc/save-and-return db "people" document)] - (is (:_id returned)) - (is (= document (dissoc returned :_id))) - (is (= 1 (mc/count db collection))))) - - -(deftest ^{:updating true} save-a-new-basic-db-object - (let [db (mg/get-db "altdb") - collection "people" - doc (to-db-object {:name "Joe" :age 30})] - (is (nil? (monger.util/get-id doc))) - (mc/save db "people" doc WriteConcern/SAFE) - (is (not (nil? (monger.util/get-id doc)))))) - - - -(deftest ^{:updating true} update-an-existing-document-using-save - (let [db (mg/get-db "altdb") - collection "people" - doc-id "people-1" - document { :_id doc-id, :name "Joe", :age 30 }] - (is (mr/ok? (mc/insert db "people" document))) - (is (= 1 (mc/count db collection))) - (mc/save db collection { :_id doc-id, :name "Alan", :age 40 }) - (is (= 1 (mc/count db collection { :name "Alan", :age 40 }))))) - -(deftest ^{:updating true} update-an-existing-document-using-save-and-return - (let [db (mg/get-db "altdb") - collection "people" - document (mc/insert-and-return db "people" {:name "Joe" :age 30}) - doc-id (:_id document) - updated (mc/save-and-return db collection {:_id doc-id :name "Alan" :age 40})] - (is (= {:_id doc-id :name "Alan" :age 40} updated)) - (is (= 1 (mc/count db collection))) - (is (= 1 (mc/count db collection {:name "Alan" :age 40}))))) - - -(deftest ^{:updating true} set-an-attribute-on-existing-document-using-update - (let [db (mg/get-db "altdb") - collection "people" - doc-id (monger.util/object-id) - document { :_id doc-id, :name "Joe", :age 30 }] - (is (mr/ok? (mc/insert db "people" document))) - (is (= 1 (mc/count db collection))) - (is (= 0 (mc/count db collection { :has_kids true }))) - (mc/update db collection { :_id doc-id } { $set { :has_kids true } }) - (is (= 1 (mc/count db collection { :has_kids true }))))) - - -(deftest ^{:updating true} increment-multiple-fields-using-exists-operator-and-update - (let [db (mg/get-db "altdb") - collection "matches" - doc-id (monger.util/object-id) - document { :_id doc-id :abc 0 :def 10 }] - (mc/remove db collection) - (is (mr/ok? (mc/insert db collection document))) - (is (= 1 (mc/count db collection {:abc {$exists true} :def {$exists true}}))) - (mc/update db collection {:abc {$exists true} :def {$exists true}} {$inc {:abc 1 :def 0}}) - (is (= 1 (mc/count db collection { :abc 1 }))))) - - - -(deftest ^{:updating true} upsert-a-document-using-update - (let [db (mg/get-db "altdb") - collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } - modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] - (is (not (mr/updated-existing? (mc/update db collection { :language "Clojure" } doc :upsert true)))) - (is (= 1 (mc/count db collection))) - (is (mr/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc :multi false :upsert true))) - (is (= 1 (mc/count db collection))) - (is (= (modified-doc (mc/find-by-id db collection doc-id)))) - (mc/remove db collection))) - -(deftest ^{:updating true} upsert-a-document-using-upsert - (let [db (mg/get-db "altdb") - collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc {:created-at date :data-store "MongoDB" :language "Clojure" :_id doc-id} - modified-doc {:created-at date :data-store "MongoDB" :language "Erlang" :_id doc-id}] - (mc/remove db collection) - (is (not (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} doc)))) - (is (= 1 (mc/count db collection))) - (is (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} modified-doc :multi false))) - (is (= 1 (mc/count db collection))) - (is (= (modified-doc (mc/find-by-id db collection doc-id)))) - (mc/remove db collection))) From 9ad38a9e7a031f420651e76857cb62f62f686173 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:27:52 -0400 Subject: [PATCH 04/48] Require connection/db/gridfs as an explicit argument (initial pass) --- src/clojure/monger/cache.clj | 20 +- src/clojure/monger/collection.clj | 441 ++++++++++------------ src/clojure/monger/command.clj | 66 ++-- src/clojure/monger/core.clj | 121 +----- src/clojure/monger/cursor.clj | 14 +- src/clojure/monger/db.clj | 21 +- src/clojure/monger/gridfs.clj | 89 ++--- src/clojure/monger/query.clj | 4 +- src/clojure/monger/ragtime.clj | 15 +- src/clojure/monger/ring/session_store.clj | 18 +- 10 files changed, 292 insertions(+), 517 deletions(-) diff --git a/src/clojure/monger/cache.clj b/src/clojure/monger/cache.clj index f3c7c30..4f04106 100644 --- a/src/clojure/monger/cache.clj +++ b/src/clojure/monger/cache.clj @@ -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 ;; diff --git a/src/clojure/monger/collection.clj b/src/clojure/monger/collection.clj index dc86fbb..e25283a 100644 --- a/src/clojure/monger/collection.clj +++ b/src/clojure/monger/collection.clj @@ -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)) diff --git a/src/clojure/monger/command.clj b/src/clojure/monger/command.clj index 5e3e8fb..8928d8b 100644 --- a/src/clojure/monger/command.clj +++ b/src/clojure/monger/command.clj @@ -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})) diff --git a/src/clojure/monger/core.clj b/src/clojure/monger/core.clj index 7307dcb..1bc1b5d 100644 --- a/src/clojure/monger/core.clj +++ b/src/clojure/monger/core.clj @@ -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] diff --git a/src/clojure/monger/cursor.clj b/src/clojure/monger/cursor.clj index e5d9c31..affe05d 100644 --- a/src/clojure/monger/cursor.clj +++ b/src/clojure/monger/cursor.clj @@ -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)))) diff --git a/src/clojure/monger/db.clj b/src/clojure/monger/db.clj index f4b7f96..b6413bf 100644 --- a/src/clojure/monger/db.clj +++ b/src/clojure/monger/db.clj @@ -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)))) diff --git a/src/clojure/monger/gridfs.clj b/src/clojure/monger/gridfs.clj index 8308fec..8aa664c 100644 --- a/src/clojure/monger/gridfs.clj +++ b/src/clojure/monger/gridfs.clj @@ -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))) diff --git a/src/clojure/monger/query.clj b/src/clojure/monger/query.clj index 667fc86..aa49fb4 100644 --- a/src/clojure/monger/query.clj +++ b/src/clojure/monger/query.clj @@ -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#))) diff --git a/src/clojure/monger/ragtime.clj b/src/clojure/monger/ragtime.clj index ab603c8..05d7fd8 100644 --- a/src/clojure/monger/ragtime.clj +++ b/src/clojure/monger/ragtime.clj @@ -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)) diff --git a/src/clojure/monger/ring/session_store.clj b/src/clojure/monger/ring/session_store.clj index ae9d3dd..543a138 100644 --- a/src/clojure/monger/ring/session_store.clj +++ b/src/clojure/monger/ring/session_store.clj @@ -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)) From b0cd0bf6710cb00f518a68c1b47c56449ae23af2 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:28:02 -0400 Subject: [PATCH 05/48] Aggregation framework tests now pass --- .../test/aggregation_framework_test.clj | 158 +++++++++--------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/test/monger/test/aggregation_framework_test.clj b/test/monger/test/aggregation_framework_test.clj index e3d2aba..74a364f 100644 --- a/test/monger/test/aggregation_framework_test.clj +++ b/test/monger/test/aggregation_framework_test.clj @@ -1,88 +1,88 @@ (ns monger.test.aggregation-framework-test - (:require monger.core [monger.collection :as mc] - [monger.test.helper :as helper] + (:require [monger.core :as mg] + [monger.collection :as mc] [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) + [monger.operators :refer :all])) + +(let [conn (mg/connect) + db (mg/get-db conn "monger-test") + coll "docs"] + (defn purge-collections + [f] + (mc/purge-many db [coll]) + (f) + (mc/purge-many db [coll])) + + (use-fixtures :each purge-collections) + + (deftest test-basic-single-stage-$project-aggregation + (let [batch [{ :state "CA" :quantity 1 :price 199.00 } + { :state "NY" :quantity 2 :price 199.00 } + { :state "NY" :quantity 1 :price 299.00 } + { :state "IL" :quantity 2 :price 11.50 } + { :state "CA" :quantity 2 :price 2.95 } + { :state "IL" :quantity 3 :price 5.50 }] + expected #{{:quantity 1 :state "CA"} + {:quantity 2 :state "NY"} + {:quantity 1 :state "NY"} + {:quantity 2 :state "IL"} + {:quantity 2 :state "CA"} + {:quantity 3 :state "IL"}}] + (mc/insert-batch db coll batch) + (is (= 6 (mc/count db coll))) + (let [result (set (map #(select-keys % [:state :quantity]) + (mc/aggregate db coll [{$project {:state 1 :quantity 1}}])))] + (is (= expected result))))) -(helper/connect!) - -(use-fixtures :each purge-docs) - -(deftest test-basic-single-stage-$project-aggregation - (let [collection "docs" - batch [{ :state "CA" :quantity 1 :price 199.00 } - { :state "NY" :quantity 2 :price 199.00 } - { :state "NY" :quantity 1 :price 299.00 } - { :state "IL" :quantity 2 :price 11.50 } - { :state "CA" :quantity 2 :price 2.95 } - { :state "IL" :quantity 3 :price 5.50 }] - expected #{{:quantity 1 :state "CA"} - {:quantity 2 :state "NY"} - {:quantity 1 :state "NY"} - {:quantity 2 :state "IL"} - {:quantity 2 :state "CA"} - {:quantity 3 :state "IL"}}] - (mc/insert-batch collection batch) - (is (= 6 (mc/count collection))) - (let [result (set (map #(select-keys % [:state :quantity]) - (mc/aggregate "docs" [{$project {:state 1 :quantity 1}}])))] - (is (= expected result))))) + (deftest test-basic-projection-with-multiplication + (let [batch [{ :state "CA" :quantity 1 :price 199.00 } + { :state "NY" :quantity 2 :price 199.00 } + { :state "NY" :quantity 1 :price 299.00 } + { :state "IL" :quantity 2 :price 11.50 } + { :state "CA" :quantity 2 :price 2.95 } + { :state "IL" :quantity 3 :price 5.50 }] + expected #{{:_id "NY" :subtotal 398.0} + {:_id "NY" :subtotal 299.0} + {:_id "IL" :subtotal 23.0} + {:_id "CA" :subtotal 5.9} + {:_id "IL" :subtotal 16.5} + {:_id "CA" :subtotal 199.0}}] + (mc/insert-batch db coll batch) + (let [result (set (mc/aggregate db coll [{$project {:subtotal {$multiply ["$quantity", "$price"]} + :_id "$state"}}]))] + (is (= expected result))))) -(deftest test-basic-projection-with-multiplication - (let [collection "docs" - batch [{ :state "CA" :quantity 1 :price 199.00 } - { :state "NY" :quantity 2 :price 199.00 } - { :state "NY" :quantity 1 :price 299.00 } - { :state "IL" :quantity 2 :price 11.50 } - { :state "CA" :quantity 2 :price 2.95 } - { :state "IL" :quantity 3 :price 5.50 }] - expected #{{:_id "NY" :subtotal 398.0} - {:_id "NY" :subtotal 299.0} - {:_id "IL" :subtotal 23.0} - {:_id "CA" :subtotal 5.9} - {:_id "IL" :subtotal 16.5} - {:_id "CA" :subtotal 199.0}}] - (mc/insert-batch collection batch) - (let [result (set (mc/aggregate "docs" [{$project {:subtotal {$multiply ["$quantity", "$price"]} - :_id "$state"}}]))] - (is (= expected result))))) + (deftest test-basic-total-aggregation + (let [batch [{ :state "CA" :quantity 1 :price 199.00 } + { :state "NY" :quantity 2 :price 199.00 } + { :state "NY" :quantity 1 :price 299.00 } + { :state "IL" :quantity 2 :price 11.50 } + { :state "CA" :quantity 2 :price 2.95 } + { :state "IL" :quantity 3 :price 5.50 }] + expected #{{:_id "CA" :total 204.9} {:_id "IL" :total 39.5} {:_id "NY" :total 697.0}}] + (mc/insert-batch db coll batch) + (let [result (set (mc/aggregate db coll [{$project {:subtotal {$multiply ["$quantity", "$price"]} + :_id 1 + :state 1}} + {$group {:_id "$state" + :total {$sum "$subtotal"}}}]))] + (is (= expected result))))) -(deftest test-basic-total-aggregation - (let [collection "docs" - batch [{ :state "CA" :quantity 1 :price 199.00 } - { :state "NY" :quantity 2 :price 199.00 } - { :state "NY" :quantity 1 :price 299.00 } - { :state "IL" :quantity 2 :price 11.50 } - { :state "CA" :quantity 2 :price 2.95 } - { :state "IL" :quantity 3 :price 5.50 }] - expected #{{:_id "CA" :total 204.9} {:_id "IL" :total 39.5} {:_id "NY" :total 697.0}}] - (mc/insert-batch collection batch) - (let [result (set (mc/aggregate "docs" [{$project {:subtotal {$multiply ["$quantity", "$price"]} - :_id 1 - :state 1}} - {$group {:_id "$state" - :total {$sum "$subtotal"}}}]))] - (is (= expected result))))) + (deftest test-$first-aggregation-operator + (let [batch [{ :state "CA" } + { :state "IL"}] + expected "CA"] + (mc/insert-batch db coll batch) + (let [result (:state (first (mc/aggregate db coll [{$group { :_id 1 :state {$first "$state"} }}])))] + (is (= expected result))))) - -(deftest test-$first-aggregation-operator - (let [collection "docs" - batch [{ :state "CA" } - { :state "IL"}] - expected "CA"] - (mc/insert-batch collection batch) - (let [result (:state (first (mc/aggregate collection [{$group { :_id 1 :state {$first "$state"} }}])))] - (is (= expected result))))) - -(deftest test-$last-aggregation-operator - (let [collection "docs" - batch [{ :state "CA" } - { :state "IL"}] - expected "IL"] - (mc/insert-batch collection batch) - (let [result (:state (first (mc/aggregate collection [{$group { :_id 1 :state {$last "$state"} }}])))] - (is (= expected result))))) + (deftest test-$last-aggregation-operator + (let [batch [{ :state "CA" } + { :state "IL"}] + expected "IL"] + (mc/insert-batch db coll batch) + (let [result (:state (first (mc/aggregate db coll [{$group { :_id 1 :state {$last "$state"} }}])))] + (is (= expected result)))))) From e04c694e3c094537c03d372e91a318cf2bf51ff5 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:35:58 -0400 Subject: [PATCH 06/48] monger.core/authenticate should not require a connection --- src/clojure/monger/core.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clojure/monger/core.clj b/src/clojure/monger/core.clj index 1bc1b5d..74c264e 100644 --- a/src/clojure/monger/core.clj +++ b/src/clojure/monger/core.clj @@ -148,7 +148,7 @@ (defn authenticate - ([^MongoClient connection ^DB db ^String username ^chars password] + ([^DB db ^String username ^chars password] (try (.authenticate db username password) ;; MongoDB Java driver's exception hierarchy is a little crazy @@ -167,7 +167,7 @@ user (.getUsername uri) pwd (.getPassword uri)] (when (and user pwd) - (when-not (authenticate conn db user pwd) + (when-not (authenticate db user pwd) (throw (IllegalArgumentException. (format "Could not authenticate with MongoDB. Either database name or credentials are invalid. Database name: %s, username: %s" (.getName db) user))))) {:conn conn :db db})) From d76127de49a7ccfbdb50fc96b0f2fb386263d8e9 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:36:19 -0400 Subject: [PATCH 07/48] Authentication and URI connection tests now pass --- test/monger/test/authentication_test.clj | 69 ++++++++++++------------ 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/test/monger/test/authentication_test.clj b/test/monger/test/authentication_test.clj index d6da98d..1fd999e 100644 --- a/test/monger/test/authentication_test.clj +++ b/test/monger/test/authentication_test.clj @@ -1,52 +1,53 @@ (ns monger.test.authentication-test - (:require [monger core util db] - [monger.test.helper :as helper] + (:require [monger util db] + [monger.core :as mg] [monger.collection :as mc] [clojure.test :refer :all])) -(helper/connect!) - +;; +;; Connection via URI +;; (when-not (System/getenv "CI") (deftest ^{:authentication true} connect-to-mongo-via-uri-without-credentials - (let [connection (monger.core/connect-via-uri! "mongodb://127.0.0.1/monger-test4")] - (is (= (-> connection .getAddress ^InetAddress (.sameHost "127.0.0.1"))))) - ;; reconnect using regular host - (helper/connect!)) + (let [{:keys [conn db]} (mg/connect-via-uri "mongodb://127.0.0.1/monger-test4")] + (is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1")))))) (deftest ^{:authentication true} connect-to-mongo-via-uri-with-valid-credentials - (let [connection (monger.core/connect-via-uri! "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")] - (is (= "monger-test4" (.getName (monger.core/current-db)))) - (is (= (-> connection .getAddress ^InetAddress (.sameHost "127.0.0.1")))) - (mc/remove "documents") + (let [{:keys [conn db]} (mg/connect-via-uri "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")] + (is (= "monger-test4" (.getName db))) + (is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1")))) + (mc/remove db "documents") ;; make sure that the database is selected ;; and operations get through. - (mc/insert "documents" {:field "value"}) - (is (= 1 (mc/count "documents" {})))) - ;; reconnect using regular host - (helper/connect!))) + (mc/insert db "documents" {:field "value"}) + (is (= 1 (mc/count db "documents" {})))))) (if-let [uri (System/getenv "MONGOHQ_URL")] (deftest ^{:external true :authentication true} connect-to-mongo-via-uri-with-valid-credentials - (let [connection (monger.core/connect-via-uri! uri)] - (is (= (-> connection .getAddress ^InetAddress (.sameHost "127.0.0.1"))))) - ;; reconnect using regular host - (helper/connect!))) + (let [{:keys [conn db]} (mg/connect-via-uri uri)] + (is (= (-> conn .getAddress ^InetAddress (.sameHost "127.0.0.1"))))))) -(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-the-default-db - ;; see ./bin/ci/before_script.sh. MK. - (let [username "clojurewerkz/monger" - pwd "monger"] - (is (monger.core/authenticate username (.toCharArray pwd))))) +;; +;; Regular connecton +;; -(deftest ^{:authentication true} test-authentication-with-valid-credentials-on-an-arbitrary-db - ;; see ./bin/ci/before_script.sh. MK. - (let [username "clojurewerkz/monger" - pwd "monger"] - (is (monger.core/authenticate (monger.core/get-db "monger-test") username (.toCharArray pwd))))) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (deftest ^{:authentication true} test-authentication-with-valid-credentials-on-the-default-db + ;; see ./bin/ci/before_script.sh. MK. + (let [username "clojurewerkz/monger" + pwd "monger"] + (is (mg/authenticate db username (.toCharArray pwd))))) -(deftest ^{:authentication true} test-authentication-with-invalid-credentials - (let [username "monger" - ^String pwd (monger.util/random-str 128 32)] - (is (not (monger.core/authenticate (monger.core/get-db "monger-test2") username (.toCharArray pwd)))))) + (deftest ^{:authentication true} test-authentication-with-valid-credentials-on-an-arbitrary-db + ;; see ./bin/ci/before_script.sh. MK. + (let [username "clojurewerkz/monger" + pwd "monger"] + (is (mg/authenticate (mg/get-db conn "monger-test") username (.toCharArray pwd))))) + + (deftest ^{:authentication true} test-authentication-with-invalid-credentials + (let [username "monger" + ^String pwd (monger.util/random-str 128 32)] + (is (not (mg/authenticate (mg/get-db conn "monger-test2") username (.toCharArray pwd))))))) From d99b6c52aa6afedecea9c3d1ae7637b219e64bec Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:45:36 -0400 Subject: [PATCH 08/48] monger.cache tests now pass --- src/clojure/monger/cache.clj | 56 ++++----------- test/monger/test/cache_test.clj | 119 ++++++++++---------------------- 2 files changed, 50 insertions(+), 125 deletions(-) diff --git a/src/clojure/monger/cache.clj b/src/clojure/monger/cache.clj index 4f04106..5143d73 100644 --- a/src/clojure/monger/cache.clj +++ b/src/clojure/monger/cache.clj @@ -29,65 +29,33 @@ ;; API ;; -(defrecord BasicMongerCache [collection]) +(defrecord BasicMongerCache [db collection]) (extend-protocol cache/CacheProtocol BasicMongerCache (lookup [c k] - (let [m (mc/find-map-by-id (:collection c) k)] + (let [m (mc/find-map-by-id (:db c) (:collection c) k)] (:value m))) (has? [c k] - (not (nil? (mc/find-by-id (get c :collection) k)))) + (not (nil? (mc/find-by-id (:db c) (:collection c) k)))) (hit [this k] this) (miss [c k v] - (mc/insert (get c :collection) {:_id k :value v}) - c) - (evict [c k] - (mc/remove-by-id (get c :collection) k) - c) - (seed [c m] - (mc/insert-batch (get c :collection) (map (fn [[k v]] - {:_id k :value v}) m)) - c)) - - -(defn basic-monger-cache-factory - ([] - (BasicMongerCache. default-cache-collection)) - ([collection] - (BasicMongerCache. collection)) - ([collection base] - (cache/seed (BasicMongerCache. collection) base))) - - -(defrecord DatabaseAwareMongerCache [db collection]) - -(extend-protocol cache/CacheProtocol - DatabaseAwareMongerCache - (lookup [c k] - (let [m (find-map-by-id (:db c) (:collection c) k)] - (:value m))) - (has? [c k] - (not (nil? (find-by-id (:db c) (:collection c) k)))) - (hit [this k] - this) - (miss [c k v] - (mc/insert (:db c) (:collection c) {:_id k :value v} WriteConcern/SAFE) + (mc/insert (:db c) (:collection c) {:_id k :value v}) c) (evict [c k] (mc/remove-by-id (:db c) (:collection c) k) c) (seed [c m] (mc/insert-batch (:db c) (:collection c) (map (fn [[k v]] - {:_id k :value v}) m) WriteConcern/SAFE) + {:_id k :value v}) m)) c)) -(defn db-aware-monger-cache-factory - ([db] - (DatabaseAwareMongerCache. db default-cache-collection)) - ([db collection] - (DatabaseAwareMongerCache. db collection)) - ([db collection base] - (cache/seed (DatabaseAwareMongerCache. db collection) base))) +(defn basic-monger-cache-factory + ([^DB db] + (BasicMongerCache. db default-cache-collection)) + ([^DB db collection] + (BasicMongerCache. db collection)) + ([^DB db collection base] + (cache/seed (BasicMongerCache. db collection) base))) diff --git a/test/monger/test/cache_test.clj b/test/monger/test/cache_test.clj index d80284d..0845af0 100644 --- a/test/monger/test/cache_test.clj +++ b/test/monger/test/cache_test.clj @@ -1,6 +1,5 @@ (ns monger.test.cache-test - (:require [monger.test.helper :as helper] - [monger.core :as mg] + (:require [monger.core :as mg] [monger.collection :as mc] [clojure.core.cache :refer :all] [clojure.test :refer :all] @@ -83,87 +82,45 @@ ;; Tests ;; -(helper/connect!) - -(use-fixtures :each (fn [f] - (mc/remove "basic_monger_cache_entries") - (let [db (mg/get-db "altcache")] - (mc/remove db "db_aware_monger_cache_entries" {})) - (f) - (mc/remove "basic_monger_cache_entries") - (let [db (mg/get-db "altcache")] - (mc/remove db "db_aware_monger_cache_entries" {})))) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (use-fixtures :each (fn [f] + (mc/remove db "basic_monger_cache_entries") + (f) + (mc/remove db "basic_monger_cache_entries"))) -(deftest ^{:cache true} - test-has?-with-basic-monger-cache - (testing "that has? returns false for misses" - (let [coll "basic_monger_cache_entries" - c (basic-monger-cache-factory coll)] - (is (not (has? c (str (UUID/randomUUID))))) - (is (not (has? c (str (UUID/randomUUID))))))) - (testing "that has? returns true for hits" - (let [coll "basic_monger_cache_entries" - c (basic-monger-cache-factory coll {"a" 1 "b" "cache" "c" 3/4})] - (is (has? c "a")) - (is (has? c "b")) - (is (has? c "c")) - (is (not (has? c "d")))))) + (deftest ^{:cache true} + test-has?-with-basic-monger-cache + (testing "that has? returns false for misses" + (let [coll "basic_monger_cache_entries" + c (basic-monger-cache-factory db coll)] + (is (not (has? c (str (UUID/randomUUID))))) + (is (not (has? c (str (UUID/randomUUID))))))) + (testing "that has? returns true for hits" + (let [coll "basic_monger_cache_entries" + c (basic-monger-cache-factory db coll {"a" 1 "b" "cache" "c" 3/4})] + (is (has? c "a")) + (is (has? c "b")) + (is (has? c "c")) + (is (not (has? c "d")))))) -(deftest ^{:cache true} - test-lookup-with-basic-moger-cache - (testing "that lookup returns nil for misses" - (let [coll "basic_monger_cache_entries" - c (basic-monger-cache-factory coll)] - (are [v] (is (nil? (lookup c v))) - :missing-key - "missing-key" - (gensym "missing-key")))) - (testing "that lookup returns cached values for hits" - (let [l (Long/valueOf 10000) - coll "basic_monger_cache_entries" - c (basic-monger-cache-factory coll {:skey "Value" :lkey l "kkey" :keyword})] - (are [v k] (is (= v (lookup c k))) - "Value" :skey - l :lkey - "keyword" "kkey")))) + (deftest ^{:cache true} + test-lookup-with-basic-monger-cache + (testing "that lookup returns nil for misses" + (let [coll "basic_monger_cache_entries" + c (basic-monger-cache-factory db coll)] + (are [v] (is (nil? (lookup c v))) + :missing-key + "missing-key" + (gensym "missing-key")))) + (testing "that lookup returns cached values for hits" + (let [l (Long/valueOf 10000) + coll "basic_monger_cache_entries" + c (basic-monger-cache-factory db coll {:skey "Value" :lkey l "kkey" :keyword})] + (are [v k] (is (= v (lookup c k))) + "Value" :skey + l :lkey + "keyword" "kkey"))))) - -(deftest ^{:cache true} - test-has?-with-db-aware-monger-cache - (testing "that has? returns false for misses" - (let [db (mg/get-db "altcache") - coll "db_aware_monger_cache_entries" - c (db-aware-monger-cache-factory db coll)] - (is (not (has? c (str (UUID/randomUUID))))) - (is (not (has? c (str (UUID/randomUUID))))))) - (testing "that has? returns true for hits" - (let [db (mg/get-db "altcache") - coll "db_aware_monger_cache_entries" - c (db-aware-monger-cache-factory db coll {"a" 1 "b" "cache" "c" 3/4})] - (is (has? c "a")) - (is (has? c "b")) - (is (has? c "c")) - (is (not (has? c "d")))))) - - -(deftest ^{:cache true} - test-lookup-with-db-aware-moger-cache - (testing "that lookup returns nil for misses" - (let [db (mg/get-db "altcache") - coll "db_aware_monger_cache_entries" - c (db-aware-monger-cache-factory db coll)] - (are [v] (is (nil? (lookup c v))) - :missing-key - "missing-key" - (gensym "missing-key")))) - (testing "that lookup returns cached values for hits" - (let [l (Long/valueOf 10000) - db (mg/get-db "altcache") - coll "db_aware_monger_cache_entries" - c (db-aware-monger-cache-factory db coll {:skey "Value" :lkey l "kkey" :keyword})] - (are [v k] (is (= v (lookup c k))) - "Value" :skey - l :lkey - "keyword" "kkey")))) From ab4a9a381ff349002fc862ddb73e14b3c6f59c08 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:48:25 -0400 Subject: [PATCH 09/48] Compile --- src/clojure/monger/command.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clojure/monger/command.clj b/src/clojure/monger/command.clj index 8928d8b..cf33f7f 100644 --- a/src/clojure/monger/command.clj +++ b/src/clojure/monger/command.clj @@ -20,7 +20,7 @@ * http://clojuremongodb.info/articles/mapreduce.html" (:require monger.core [monger.conversion :refer :all]) - (:import [com.mongodb DB DBObject])) + (:import [com.mongodb MongoClient DB DBObject])) ;; From d114073413ffd2b429a4830ca170b3abd57cbe43 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:48:32 -0400 Subject: [PATCH 10/48] monger.command tests now pass --- test/monger/test/command_test.clj | 48 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/test/monger/test/command_test.clj b/test/monger/test/command_test.clj index d3144db..cc257ae 100644 --- a/test/monger/test/command_test.clj +++ b/test/monger/test/command_test.clj @@ -1,36 +1,34 @@ (ns monger.test.command-test (:require [monger.core :as mg] [monger.command :as mcom] - [monger.test.helper :as helper] [monger.collection :as mc] [clojure.test :refer :all] [monger.result :refer [ok?]] [monger.conversion :refer [from-db-object]])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (deftest ^{:command true} test-reindex-collection + (let [_ (mc/insert db "test" {:name "Clojure"}) + result (mcom/reindex-collection db "test")] + (is (ok? result)) + (is (get result "indexes")))) + (deftest ^{:command true} test-server-status + (let [status (mcom/server-status db)] + (is (ok? status)) + (is (not-empty status)) + (is (get status "serverUsed")))) -(deftest ^{:command true} test-reindex-collection - (let [_ (mc/insert "test" {:name "Clojure"}) - result (mcom/reindex-collection "test")] - (is (ok? result)) - (is (get result "indexes")))) + (deftest ^{:command true} test-top + (let [result (mcom/top conn)] + (is (ok? result)) + (is (not-empty result)) + (is (get result "serverUsed")))) -(deftest ^{:command true} test-server-status - (let [status (mcom/server-status)] - (is (ok? status)) - (is (not-empty status)) - (is (get status "serverUsed")))) - -(deftest ^{:command true} test-top - (let [result (mcom/top)] - (is (ok? result)) - (is (not-empty result)) - (is (get result "serverUsed")))) - -(deftest ^{:command true} test-running-is-master-as-an-arbitrary-command - (let [raw (mg/command {:isMaster 1}) - result (from-db-object raw true)] - (is (ok? result)) - (is (ok? raw)) - (is (:ismaster result)))) + (deftest ^{:command true} test-running-is-master-as-an-arbitrary-command + (let [raw (mg/command db {:isMaster 1}) + result (from-db-object raw true)] + (is (ok? result)) + (is (ok? raw)) + (is (:ismaster result))))) From d3cb048d2b8a45039f88c1fcf03a287619e79e2b Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:52:44 -0400 Subject: [PATCH 11/48] monger.core tests now pass --- test/monger/test/core_test.clj | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/test/monger/test/core_test.clj b/test/monger/test/core_test.clj index 53bdd66..2e09e40 100644 --- a/test/monger/test/core_test.clj +++ b/test/monger/test/core_test.clj @@ -1,30 +1,27 @@ (ns monger.test.core-test - (:require [monger core collection util result] - [monger.test.helper :as helper] + (:require [monger util result] + [monger.core :as mg :refer [server-address mongo-options]] [monger.collection :as mc] - [clojure.test :refer :all] - [monger.core :refer [server-address mongo-options]]) + [clojure.test :refer :all]) (:import [com.mongodb MongoClient DB WriteConcern MongoClientOptions ServerAddress])) (println (str "Using Clojure version " *clojure-version*)) -(helper/connect!) (deftest connect-to-mongo-with-default-host-and-port - (let [connection (monger.core/connect)] + (let [connection (mg/connect)] (is (instance? com.mongodb.MongoClient connection)))) (deftest connect-and-disconnect - (monger.core/connect!) - (monger.core/disconnect!) - (monger.core/connect!)) + (let [conn (mg/connect)] + (mg/disconnect conn))) (deftest connect-to-mongo-with-default-host-and-explicit-port - (let [connection (monger.core/connect { :port 27017 })] + (let [connection (mg/connect { :port 27017 })] (is (instance? com.mongodb.MongoClient connection)))) (deftest connect-to-mongo-with-default-port-and-explicit-host - (let [connection (monger.core/connect { :host "127.0.0.1" })] + (let [connection (mg/connect { :host "127.0.0.1" })] (is (instance? com.mongodb.MongoClient connection)))) (deftest test-server-address @@ -36,31 +33,32 @@ (deftest use-existing-mongo-connection (let [^MongoClientOptions opts (mongo-options :threads-allowed-to-block-for-connection-multiplier 300) - connection (MongoClient. "127.0.0.1" opts)] - (monger.core/set-connection! connection) - (is (= monger.core/*mongodb-connection* connection)))) + connection (MongoClient. "127.0.0.1" opts) + db (mg/get-db connection "monger-test")] + (mg/disconnect connection))) (deftest connect-to-mongo-with-extra-options (let [^MongoClientOptions opts (mongo-options :threads-allowed-to-block-for-connection-multiplier 300) - ^ServerAddress sa (server-address "127.0.0.1" 27017)] - (monger.core/connect! sa opts))) + ^ServerAddress sa (server-address "127.0.0.1" 27017) + conn (mg/connect sa opts)] + (mg/disconnect conn))) (deftest get-database - (let [connection (monger.core/connect) - db (monger.core/get-db connection "monger-test")] + (let [connection (mg/connect) + db (mg/get-db connection "monger-test")] (is (instance? com.mongodb.DB db)))) (deftest test-get-db-names - (let [dbs (monger.core/get-db-names)] + (let [conn (mg/connect) + dbs (mg/get-db-names conn)] (is (not (empty? dbs))) (is (dbs "monger-test")))) (deftest get-last-error - (let [connection (monger.core/connect) - db (monger.core/get-db connection "monger-test")] - (is (monger.result/ok? (monger.core/get-last-error))) - (is (monger.result/ok? (monger.core/get-last-error db))) - (is (monger.result/ok? (monger.core/get-last-error db WriteConcern/NORMAL))) - (is (monger.result/ok? (monger.core/get-last-error db 1 100 true))))) + (let [connection (mg/connect) + db (mg/get-db connection "monger-test")] + (is (monger.result/ok? (mg/get-last-error db))) + (is (monger.result/ok? (mg/get-last-error db WriteConcern/NORMAL))) + (is (monger.result/ok? (mg/get-last-error db 1 100 true))))) From 912b9e4d457c42703a1fd32e546c534626c656aa Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 16:57:42 -0400 Subject: [PATCH 12/48] monger.db tests now pass --- test/monger/test/db_test.clj | 53 ++++++++++++++---------------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/test/monger/test/db_test.clj b/test/monger/test/db_test.clj index c9a0049..afd7023 100644 --- a/test/monger/test/db_test.clj +++ b/test/monger/test/db_test.clj @@ -1,44 +1,31 @@ (ns monger.test.db-test - (:require [monger core db] - [monger.test.helper :as helper] + (:require [monger.db :as mdb] + [monger.core :as mg] [monger.collection :as mc] [clojure.test :refer :all]) (:import [com.mongodb Mongo DB] java.util.Set)) -(helper/connect!) - - ;; do not run this test for CI, it complicates matters by messing up ;; authentication for some other tests :( MK. -(when-not (System/getenv "CI") - (deftest test-drop-database - ;; drop a secondary database here. MK. - (monger.core/with-db (monger.core/get-db "monger-test3") - (let [collection "test" - _ (mc/insert collection {:name "Clojure"}) - check (mc/count collection) - _ (monger.db/drop-db)] +(let [conn (mg/connect)] + (when-not (System/getenv "CI") + (deftest test-drop-database + ;; drop a secondary database here. MK. + (let [db (mg/get-db conn "monger-test3") + collection "test" + _ (mc/insert db collection {:name "Clojure"}) + check (mc/count db collection) + _ (mdb/drop-db db)] (is (= 1 check)) - (is (not (mc/exists? collection))) - (is (= 0 (mc/count collection)))))) + (is (not (mc/exists? db collection))) + (is (= 0 (mc/count db collection)))))) - (deftest test-use-database - (monger.core/use-db! "monger-test5") - (is (= "monger-test5" (.getName (monger.core/current-db)))) - (let [collection "test" - _ (mc/insert collection {:name "Clojure"}) - check (mc/count collection) - _ (monger.db/drop-db)] - (is (= 1 check)) - (is (not (mc/exists? collection))) - (is (= 0 (mc/count collection)))))) - - -(deftest test-get-collection-names - (mc/insert "test-1" {:name "Clojure"}) - (mc/insert "test-2" {:name "Clojure"}) - (let [^Set collections (monger.db/get-collection-names)] - (is (.contains collections "test-1")) - (is (.contains collections "test-2")))) + (deftest test-get-collection-names + (let [db (mg/get-db conn "monger-test")] + (mc/insert db "test-1" {:name "Clojure"}) + (mc/insert db "test-2" {:name "Clojure"}) + (let [^Set xs (mdb/get-collection-names db)] + (is (.contains xs "test-1")) + (is (.contains xs "test-2")))))) From 42ca0efa5cb44d159dcecf54b1172c9f21e16122 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:04:28 -0400 Subject: [PATCH 13/48] Cosmetics --- src/clojure/monger/command.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clojure/monger/command.clj b/src/clojure/monger/command.clj index cf33f7f..2ce82d2 100644 --- a/src/clojure/monger/command.clj +++ b/src/clojure/monger/command.clj @@ -53,8 +53,8 @@ (defn rename-collection "Changes the name of an existing collection using the renameCollection command" - ([^DB db ^String from ^String to] - (monger.core/command db (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" From 8b237db38256dff9fbd2119988857058cdf6a699 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:04:38 -0400 Subject: [PATCH 14/48] Cosmetics --- src/clojure/monger/core.clj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/clojure/monger/core.clj b/src/clojure/monger/core.clj index 74c264e..d467768 100644 --- a/src/clojure/monger/core.clj +++ b/src/clojure/monger/core.clj @@ -179,13 +179,13 @@ 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." - ([^DB database ^Map cmd] - (.command ^DB database ^DBObject (to-db-object cmd)))) + [^DB database ^Map cmd] + (.command ^DB database ^DBObject (to-db-object cmd))) (defn ^com.mongodb.CommandResult raw-command "Like monger.core/command but accepts DBObjects" - ([^DB database ^DBObject cmd] - (.command database cmd))) + [^DB database ^DBObject cmd] + (.command database cmd)) (defprotocol Countable (count [this] "Returns size of the object")) From a7cceebe9ca5cd9a2553558021bf2d8cedc6a79e Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:04:55 -0400 Subject: [PATCH 15/48] Search tests now pass --- src/clojure/monger/search.clj | 6 +-- test/monger/test/full_text_search_test.clj | 47 ++++++++++++---------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/clojure/monger/search.clj b/src/clojure/monger/search.clj index c88e643..6682887 100644 --- a/src/clojure/monger/search.clj +++ b/src/clojure/monger/search.clj @@ -11,7 +11,7 @@ "Full text search queries support (MongoDB 2.4+)" (:require [monger.command :as cmd] [monger.conversion :as cnv]) - (:import [com.mongodb CommandResult BasicDBList DBObject])) + (:import [com.mongodb DB CommandResult BasicDBList DBObject])) ;; ;; Implementation @@ -28,8 +28,8 @@ (defn search "Performs a full text search query" - [^String collection query] - (cmd/search collection query)) + [^DB db ^String collection query] + (cmd/search db collection query)) (defn results-from "Returns a lazy sequence of results from a search query response, sorted by score. diff --git a/test/monger/test/full_text_search_test.clj b/test/monger/test/full_text_search_test.clj index d40cd87..321a5e1 100644 --- a/test/monger/test/full_text_search_test.clj +++ b/test/monger/test/full_text_search_test.clj @@ -3,33 +3,38 @@ [monger.collection :as mc] [monger.search :as ms] [monger.command :as cmd] - [monger.test.helper :as helper] [clojure.test :refer [deftest is use-fixtures]] - [monger.test.fixtures :refer :all] - [monger.result :refer [ok?]]) + [monger.result :refer [ok?]]) (:import com.mongodb.BasicDBObjectBuilder)) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test") + coll "search-docs"] -(defn enable-search - [f] - ;; {:textSearchEnabled true :setParameter 1} - (let [bldr (doto (BasicDBObjectBuilder.) - (.append "setParameter" 1) - (.append "textSearchEnabled" true)) - cmd (.get bldr)] - (is (ok? (cmd/raw-admin-command cmd)))) - (f)) + (defn enable-search + [f] + ;; {:textSearchEnabled true :setParameter 1} + (let [bldr (doto (BasicDBObjectBuilder.) + (.append "setParameter" 1) + (.append "textSearchEnabled" true)) + cmd (.get bldr)] + (is (ok? (cmd/raw-admin-command conn cmd)))) + (f)) -(use-fixtures :each purge-docs) -(use-fixtures :once enable-search) + (defn purge-collections + [f] + (mc/purge-many db [coll]) + (f) + (mc/purge-many db [coll])) -(deftest ^{:search true} test-basic-full-text-search-query - (let [coll "docs"] - (mc/ensure-index coll (array-map :subject "text" :content "text")) - (mc/insert coll {:subject "hello there" :content "this should be searchable"}) - (mc/insert coll {:subject "untitled" :content "this is just noize"}) - (let [res (ms/search coll "hello") + (use-fixtures :each purge-collections) + (use-fixtures :once enable-search) + + (deftest ^{:search true} test-basic-full-text-search-query + (mc/ensure-index db coll (array-map :subject "text" :content "text")) + (mc/insert db coll {:subject "hello there" :content "this should be searchable"}) + (mc/insert db coll {:subject "untitled" :content "this is just noize"}) + (let [res (ms/search db coll "hello") xs (ms/results-from res)] (is (= "hello there" (-> xs first :obj :subject))) (is (= 1.0 (-> xs first :score)))))) From 56eebda3fd1a0e5ecbdd8312c3e038779fc7a721 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:34:22 -0400 Subject: [PATCH 16/48] GridFS tests now pass, plus API improvements that make sense for 2.0 --- src/clojure/monger/core.clj | 13 +- src/clojure/monger/gridfs.clj | 52 +++--- test/monger/test/gridfs_test.clj | 284 +++++++++++++++---------------- 3 files changed, 184 insertions(+), 165 deletions(-) diff --git a/src/clojure/monger/core.clj b/src/clojure/monger/core.clj index d467768..ff71224 100644 --- a/src/clojure/monger/core.clj +++ b/src/clojure/monger/core.clj @@ -38,7 +38,7 @@ ;; API ;; -(defn ^com.mongodb.MongoClient connect +(defn ^MongoClient connect "Connects to MongoDB. When used without arguments, connects to Arguments: @@ -79,7 +79,7 @@ (set (.getDatabaseNames conn))) -(defn ^com.mongodb.DB get-db +(defn ^DB get-db "Get database reference by name. EXAMPLES @@ -93,6 +93,15 @@ [^MongoClient conn ^String db] (.dropDatabase conn db)) +(defn ^GridFS get-gridfs + "Get GridFS for the given database. + + EXAMPLES + + (monger.core/get-gridfs connection \"myapp_production\")" + [^MongoClient conn ^String name] + (GridFS. (.getDB conn name))) + (defn server-address ([^String hostname] (ServerAddress. hostname)) diff --git a/src/clojure/monger/gridfs.clj b/src/clojure/monger/gridfs.clj index 8aa664c..c0d15f2 100644 --- a/src/clojure/monger/gridfs.clj +++ b/src/clojure/monger/gridfs.clj @@ -20,7 +20,7 @@ (:import [com.mongodb DB DBObject] org.bson.types.ObjectId [com.mongodb.gridfs GridFS GridFSInputFile] - [java.io InputStream File])) + [java.io InputStream ByteArrayInputStream File])) ;; ;; Implementation @@ -50,42 +50,49 @@ (remove fs {})) (defn all-files - [^GridFS fs query] - (.getFileList fs query)) + ([^GridFS fs] + (.getFileList fs (to-db-object {}))) + ([^GridFS fs query] + (.getFileList fs query))) (def ^{:private true} converter (fpartial from-db-object true)) (defn files-as-maps - [^GridFS fs query] - (map converter (all-files fs (to-db-object query)))) + ([^GridFS fs] + (files-as-maps fs {})) + ([^GridFS fs query] + (map converter (all-files fs (to-db-object query))))) ;; ;; Plumbing (low-level API) ;; -(defprotocol GridFSInputFileFactory - (^com.mongodb.gridfs.GridFSInputFile make-input-file [input] "Makes GridFSInputFile out of the given input")) +(defprotocol InputStreamFactory + (^InputStream to-input-stream [input] "Makes InputStream out of the given input")) (extend byte-array-type - GridFSInputFileFactory - {:make-input-file (fn [^bytes input] - (.createFile ^GridFS monger.core/*mongodb-gridfs* input))}) + InputStreamFactory + {:to-input-stream (fn [^bytes input] + (ByteArrayInputStream. input))}) -(extend-protocol GridFSInputFileFactory +(extend-protocol InputStreamFactory String - (make-input-file [^String input] - (.createFile ^GridFS monger.core/*mongodb-gridfs* ^InputStream (io/make-input-stream input {:encoding "UTF-8"}))) + (to-input-stream [^String input] + (io/make-input-stream input {:encoding "UTF-8"})) File - (make-input-file [^File input] - (.createFile ^GridFS monger.core/*mongodb-gridfs* ^InputStream (io/make-input-stream input {:encoding "UTF-8"}))) + (to-input-stream [^File input] + (io/make-input-stream input {:encoding "UTF-8"})) InputStream - (make-input-file [^InputStream input] - (.createFile ^GridFS monger.core/*mongodb-gridfs* ^InputStream input))) + (to-input-stream [^InputStream input] + input)) +(defn ^GridFSInputFile make-input-file + [^GridFS fs input] + (.createFile fs (to-input-stream input))) (defmacro store [^GridFSInputFile input & body] @@ -93,9 +100,8 @@ (.save f# GridFS/DEFAULT_CHUNKSIZE) (from-db-object f# true))) - ;; -;; "New" DSL, a higher-level API +;; Higher-level API ;; (defn save @@ -132,6 +138,14 @@ [^GridFS fs query] (.find fs (to-db-object query))) +(defn find-by-filename + [^GridFS fs ^String filename] + (.find fs (to-db-object {"filename" filename}))) + +(defn find-by-md5 + [^GridFS fs ^String md5] + (.find fs (to-db-object {"md5" md5}))) + (defn find-one [^GridFS fs query] (.findOne fs (to-db-object query))) diff --git a/test/monger/test/gridfs_test.clj b/test/monger/test/gridfs_test.clj index 0132fd1..9326e49 100644 --- a/test/monger/test/gridfs_test.clj +++ b/test/monger/test/gridfs_test.clj @@ -1,167 +1,163 @@ (ns monger.test.gridfs-test (:refer-clojure :exclude [count remove find]) (:require [monger.gridfs :as gridfs] - [monger.test.helper :as helper] [clojure.java.io :as io] [clojure.test :refer :all] - [monger.core :refer [count]] - [monger.test.fixtures :refer :all] + [monger.core :as mg :refer [count]] [monger.operators :refer :all] [monger.conversion :refer :all] [monger.gridfs :refer [store make-input-file store-file filename content-type metadata]]) (:import [java.io InputStream File FileInputStream] [com.mongodb.gridfs GridFS GridFSInputFile GridFSDBFile])) -(defn purge-gridfs* - [] - (gridfs/remove-all)) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test") + fs (mg/get-gridfs conn "monger-test")] + (defn purge-gridfs* + [] + (gridfs/remove-all fs)) -(defn purge-gridfs - [f] - (gridfs/remove-all) - (f) - (gridfs/remove-all)) + (defn purge-gridfs + [f] + (gridfs/remove-all fs) + (f) + (gridfs/remove-all fs)) -(use-fixtures :each purge-gridfs) + (use-fixtures :each purge-gridfs) -(helper/connect!) + (deftest ^{:gridfs true} test-storing-files-to-gridfs-using-relative-fs-paths + (let [input "./test/resources/mongo/js/mapfun1.js"] + (is (= 0 (count (gridfs/all-files fs)))) + (store (make-input-file fs input) + (.setFilename "monger.test.gridfs.file1") + (.setContentType "application/octet-stream")) + (is (= 1 (count (gridfs/all-files fs)))))) + + + (deftest ^{:gridfs true} test-storing-files-to-gridfs-using-file-instances + (let [input (io/as-file "./test/resources/mongo/js/mapfun1.js")] + (is (= 0 (count (gridfs/all-files fs)))) + (store-file (make-input-file fs input) + (filename "monger.test.gridfs.file2") + (content-type "application/octet-stream")) + (is (= 1 (count (gridfs/all-files fs)))))) + + (deftest ^{:gridfs true} test-storing-bytes-to-gridfs + (let [input (.getBytes "A string") + md {:format "raw" :source "AwesomeCamera D95"} + fname "monger.test.gridfs.file3" + ct "application/octet-stream"] + (is (= 0 (count (gridfs/all-files fs)))) + (store-file (make-input-file fs input) + (filename fname) + (metadata md) + (content-type "application/octet-stream")) + (let [f (first (gridfs/files-as-maps fs))] + (is (= ct (:contentType f))) + (is (= fname (:filename f))) + (is (= md (:metadata f)))) + (is (= 1 (count (gridfs/all-files fs)))))) + + (deftest ^{:gridfs true} test-storing-files-to-gridfs-using-absolute-fs-paths + (let [tmp-file (File/createTempFile "monger.test.gridfs" "test-storing-files-to-gridfs-using-absolute-fs-paths") + _ (spit tmp-file "Some content") + input (.getAbsolutePath tmp-file)] + (is (= 0 (count (gridfs/all-files fs)))) + (store-file (make-input-file fs input) + (filename "monger.test.gridfs.file4") + (content-type "application/octet-stream")) + (is (= 1 (count (gridfs/all-files fs)))))) + + (deftest ^{:gridfs true} test-storing-files-to-gridfs-using-input-stream + (let [tmp-file (File/createTempFile "monger.test.gridfs" "test-storing-files-to-gridfs-using-input-stream") + _ (spit tmp-file "Some other content")] + (is (= 0 (count (gridfs/all-files fs)))) + (store-file fs + (make-input-file (FileInputStream. tmp-file)) + (filename "monger.test.gridfs.file4b") + (content-type "application/octet-stream")) + (is (= 1 (count (gridfs/all-files fs)))))) -(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-relative-fs-paths - (let [input "./test/resources/mongo/js/mapfun1.js"] - (is (= 0 (count (gridfs/all-files)))) - (store (make-input-file input) - (.setFilename "monger.test.gridfs.file1") - (.setContentType "application/octet-stream")) - (is (= 1 (count (gridfs/all-files)))))) + (deftest ^{:gridfs true} test-finding-individual-files-on-gridfs + (testing "gridfs/find-one" + (purge-gridfs*) + (let [input "./test/resources/mongo/js/mapfun1.js" + ct "binary/octet-stream" + fname "monger.test.gridfs.file5" + md5 "14a09deabb50925a3381315149017bbd" + stored (store-file (make-input-file fs input) + (filename fname) + (content-type ct))] + (is (= 1 (count (gridfs/all-files fs)))) + (is (:_id stored)) + (is (:uploadDate stored)) + (is (= 62 (:length stored))) + (is (= md5 (:md5 stored))) + (is (= fname (:filename stored))) + (is (= ct (:contentType stored))) + (are [a b] (is (= a (:md5 (from-db-object (gridfs/find-one fs b) true)))) + md5 {:_id (:_id stored)} + md5 (to-db-object {:md5 md5})))) + (testing "gridfs/find-one-as-map" + (purge-gridfs*) + (let [input "./test/resources/mongo/js/mapfun1.js" + ct "binary/octet-stream" + fname "monger.test.gridfs.file6" + md5 "14a09deabb50925a3381315149017bbd" + stored (store-file (make-input-file fs input) + (filename fname) + (metadata (to-db-object {:meta "data"})) + (content-type ct))] + (is (= 1 (count (gridfs/all-files fs)))) + (is (:_id stored)) + (is (:uploadDate stored)) + (is (= 62 (:length stored))) + (is (= md5 (:md5 stored))) + (is (= fname (:filename stored))) + (is (= ct (:contentType stored))) + (let [m (gridfs/find-one-as-map fs {:filename fname})] + (is (= {:meta "data"} (:metadata m)))) + (are [a query] (is (= a (:md5 (gridfs/find-one-as-map fs query)))) + md5 {:_id (:_id stored)} + md5 {:md5 md5})))) - -(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-file-instances - (let [input (io/as-file "./test/resources/mongo/js/mapfun1.js")] - (is (= 0 (count (gridfs/all-files)))) - (store-file (make-input-file input) - (filename "monger.test.gridfs.file2") - (content-type "application/octet-stream")) - (is (= 1 (count (gridfs/all-files)))))) - -(deftest ^{:gridfs true} test-storing-bytes-to-gridfs - (let [input (.getBytes "A string") - md {:format "raw" :source "AwesomeCamera D95"} - fname "monger.test.gridfs.file3" - ct "application/octet-stream"] - (is (= 0 (count (gridfs/all-files)))) - (store-file (make-input-file input) - (filename fname) - (metadata md) - (content-type "application/octet-stream")) - (let [f (first (gridfs/files-as-maps))] - (is (= ct (:contentType f))) - (is (= fname (:filename f))) - (is (= md (:metadata f)))) - (is (= 1 (count (gridfs/all-files)))))) - -(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-absolute-fs-paths - (let [tmp-file (File/createTempFile "monger.test.gridfs" "test-storing-files-to-gridfs-using-absolute-fs-paths") - _ (spit tmp-file "Some content") - input (.getAbsolutePath tmp-file)] - (is (= 0 (count (gridfs/all-files)))) - (store-file (make-input-file input) - (filename "monger.test.gridfs.file4") - (content-type "application/octet-stream")) - (is (= 1 (count (gridfs/all-files)))))) - -(deftest ^{:gridfs true} test-storing-files-to-gridfs-using-input-stream - (let [tmp-file (File/createTempFile "monger.test.gridfs" "test-storing-files-to-gridfs-using-input-stream") - _ (spit tmp-file "Some other content")] - (is (= 0 (count (gridfs/all-files)))) - (store-file (make-input-file (FileInputStream. tmp-file)) - (filename "monger.test.gridfs.file4b") - (content-type "application/octet-stream")) - (is (= 1 (count (gridfs/all-files)))))) - - - -(deftest ^{:gridfs true} test-finding-individual-files-on-gridfs - (testing "gridfs/find-one" - (purge-gridfs*) - (let [input "./test/resources/mongo/js/mapfun1.js" - ct "binary/octet-stream" - fname "monger.test.gridfs.file5" - md5 "14a09deabb50925a3381315149017bbd" - stored (store-file (make-input-file input) - (filename fname) - (content-type ct))] - (is (= 1 (count (gridfs/all-files)))) - (is (:_id stored)) - (is (:uploadDate stored)) - (is (= 62 (:length stored))) - (is (= md5 (:md5 stored))) - (is (= fname (:filename stored))) - (is (= ct (:contentType stored))) - (are [a b] (is (= a (:md5 (from-db-object (gridfs/find-one b) true)))) - md5 (:_id stored) - md5 fname - md5 (to-db-object {:md5 md5})))) - (testing "gridfs/find-one-as-map" - (purge-gridfs*) + (deftest ^{:gridfs true} test-finding-multiple-files-on-gridfs (let [input "./test/resources/mongo/js/mapfun1.js" ct "binary/octet-stream" - fname "monger.test.gridfs.file6" md5 "14a09deabb50925a3381315149017bbd" - stored (store-file (make-input-file input) - (filename fname) - (metadata (to-db-object {:meta "data"})) - (content-type ct))] - (is (= 1 (count (gridfs/all-files)))) - (is (:_id stored)) - (is (:uploadDate stored)) - (is (= 62 (:length stored))) - (is (= md5 (:md5 stored))) - (is (= fname (:filename stored))) - (is (= ct (:contentType stored))) - (let [m (gridfs/find-one-as-map {:filename fname})] - (is (= {:meta "data"} (:metadata m)))) - (are [a query] (is (= a (:md5 (gridfs/find-one-as-map query)))) - md5 (:_id stored) - md5 fname - md5 {:md5 md5})))) - -(deftest ^{:gridfs true} test-finding-multiple-files-on-gridfs - (let [input "./test/resources/mongo/js/mapfun1.js" - ct "binary/octet-stream" - md5 "14a09deabb50925a3381315149017bbd" - stored1 (store-file (make-input-file input) - (filename "monger.test.gridfs.file6") - (content-type ct)) - stored2 (store-file (make-input-file input) - (filename "monger.test.gridfs.file7") - (content-type ct)) - list1 (gridfs/find "monger.test.gridfs.file6") - list2 (gridfs/find "monger.test.gridfs.file7") - list3 (gridfs/find "888000___.monger.test.gridfs.file") - list4 (gridfs/find { :md5 md5 })] - (is (= 2 (count (gridfs/all-files)))) - (are [a b] (is (= (map #(.get ^GridFSDBFile % "_id") a) - (map :_id b))) - list1 [stored1] - list2 [stored2] - list3 [] - list4 [stored1 stored2]))) + stored1 (store-file (make-input-file fs input) + (filename "monger.test.gridfs.file6") + (content-type ct)) + stored2 (store-file (make-input-file fs input) + (filename "monger.test.gridfs.file7") + (content-type ct)) + list1 (gridfs/find-by-filename fs "monger.test.gridfs.file6") + list2 (gridfs/find-by-filename fs "monger.test.gridfs.file7") + list3 (gridfs/find-by-filename fs "888000___.monger.test.gridfs.file") + list4 (gridfs/find-by-md5 fs md5)] + (is (= 2 (count (gridfs/all-files fs)))) + (are [a b] (is (= (map #(.get ^GridFSDBFile % "_id") a) + (map :_id b))) + list1 [stored1] + list2 [stored2] + list3 [] + list4 [stored1 stored2]))) -(deftest ^{:gridfs true} test-removing-multiple-files-from-gridfs - (let [input "./test/resources/mongo/js/mapfun1.js" - ct "binary/octet-stream" - md5 "14a09deabb50925a3381315149017bbd" - stored1 (store-file (make-input-file input) - (filename "monger.test.gridfs.file8") - (content-type ct)) - stored2 (store-file (make-input-file input) - (filename "monger.test.gridfs.file9") - (content-type ct))] - (is (= 2 (count (gridfs/all-files)))) - (gridfs/remove { :filename "monger.test.gridfs.file8" }) - (is (= 1 (count (gridfs/all-files)))) - (gridfs/remove { :md5 md5 }) - (is (= 0 (count (gridfs/all-files)))))) + (deftest ^{:gridfs true} test-removing-multiple-files-from-gridfs + (let [input "./test/resources/mongo/js/mapfun1.js" + ct "binary/octet-stream" + md5 "14a09deabb50925a3381315149017bbd" + stored1 (store-file (make-input-file fs input) + (filename "monger.test.gridfs.file8") + (content-type ct)) + stored2 (store-file (make-input-file fs input) + (filename "monger.test.gridfs.file9") + (content-type ct))] + (is (= 2 (count (gridfs/all-files fs)))) + (gridfs/remove fs { :filename "monger.test.gridfs.file8" }) + (is (= 1 (count (gridfs/all-files fs)))) + (gridfs/remove fs { :md5 md5 }) + (is (= 0 (count (gridfs/all-files fs))))))) From c6ef174535bf385b0c285cb606d3bf8ccfe13b0a Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:39:39 -0400 Subject: [PATCH 17/48] monger.test.indexing-test now passes --- test/monger/test/indexing_test.clj | 83 ++++++++++++++---------------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/test/monger/test/indexing_test.clj b/test/monger/test/indexing_test.clj index 18cb2d7..a6f6c57 100644 --- a/test/monger/test/indexing_test.clj +++ b/test/monger/test/indexing_test.clj @@ -1,53 +1,46 @@ (ns monger.test.indexing-test (:import org.bson.types.ObjectId java.util.Date) - (:require [monger core util] + (:require [monger.core :as mg] [monger.collection :as mc] - [monger.test.helper :as helper] monger.joda-time [clojure.test :refer :all] - [monger.test.fixtures :refer :all] - [clj-time.core :refer [now secs ago from-now]])) + [clj-time.core :refer [now seconds ago from-now]])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (deftest ^{:indexing true} test-creating-and-dropping-indexes + (let [collection "libraries"] + (mc/drop-indexes db collection) + (mc/create-index db collection { "language" 1 }) + (is (= "language_1" + (:name (second (mc/indexes-on db collection))))) + (mc/drop-index db collection "language_1") + (mc/create-index db collection ["language"]) + (mc/drop-index db collection "language_1") + (is (nil? (second (mc/indexes-on db collection)))) + (mc/ensure-index db collection (array-map "language" 1) {:unique true}) + (is (= "language_1" + (:name (second (mc/indexes-on db collection))))) + (mc/ensure-index db collection (array-map "language" 1)) + (mc/ensure-index db collection (array-map "language" 1) { :unique true }) + (mc/drop-indexes db collection))) - -;; -;; indexes -;; - -(deftest ^{:indexing true} test-creating-and-dropping-indexes - (let [collection "libraries"] - (mc/drop-indexes collection) - (mc/create-index collection { "language" 1 }) - (is (= "language_1" - (:name (second (mc/indexes-on collection))))) - (mc/drop-index collection "language_1") - (mc/create-index collection ["language"]) - (mc/drop-index collection "language_1") - (is (nil? (second (mc/indexes-on collection)))) - (mc/ensure-index collection (array-map "language" 1) {:unique true}) - (is (= "language_1" - (:name (second (mc/indexes-on collection))))) - (mc/ensure-index collection (array-map "language" 1)) - (mc/ensure-index collection (array-map "language" 1) { :unique true }) - (mc/drop-indexes collection))) - -(deftest ^{:indexing true :edge-features true :time-consuming true} test-ttl-collections - (let [coll "recent_events" - ttl 30 - sleep 120] - (mc/remove coll) - (mc/ensure-index coll (array-map :created-at 1) {:expireAfterSeconds ttl}) - (dotimes [i 100] - (mc/insert coll {:type "signup" :created-at (-> i secs ago) :i i})) - (dotimes [i 100] - (mc/insert coll {:type "signup" :created-at (-> i secs from-now) :i i})) - (is (= 200 (mc/count coll {:type "signup"}))) - ;; sleep for 65 seconds. MongoDB 2.1.2 seems to run TTLMonitor once per minute, according to - ;; the log. MK. - (println (format "Now sleeping for %d seconds to test TTL collections!" sleep)) - (Thread/sleep (* sleep 1000)) - (println (format "Documents in the TTL collection: %d" (mc/count coll {:type "signup"}))) - (is (< (mc/count coll {:type "signup"}) 100)) - (mc/remove coll))) + (deftest ^{:indexing true :time-consuming true} test-ttl-collections + (let [coll "recent_events" + ttl 30 + sleep 120] + (mc/remove db coll) + (mc/ensure-index db coll (array-map :created-at 1) {:expireAfterSeconds ttl}) + (dotimes [i 100] + (mc/insert db coll {:type "signup" :created-at (-> i seconds ago) :i i})) + (dotimes [i 100] + (mc/insert db coll {:type "signup" :created-at (-> i seconds from-now) :i i})) + (is (= 200 (mc/count db coll {:type "signup"}))) + ;; sleep for 65 seconds. MongoDB 2.1.2 seems to run TTLMonitor once per minute, according to + ;; the log. MK. + (println (format "Now sleeping for %d seconds to test TTL collections!" sleep)) + (Thread/sleep (* sleep 1000)) + (println (format "Documents in the TTL collection: %d" (mc/count db coll {:type "signup"}))) + (is (< (mc/count db coll {:type "signup"}) 100)) + (mc/remove db coll)))) From b1e874aa87e373fb6ce48aafda92ce2858f2c78a Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:43:43 -0400 Subject: [PATCH 18/48] monger.fn can go now since we rely on ClojureWerkz Support --- src/clojure/monger/internal/fn.clj | 73 --------------------------- test/monger/test/internal/fn_test.clj | 45 ----------------- 2 files changed, 118 deletions(-) delete mode 100644 src/clojure/monger/internal/fn.clj delete mode 100644 test/monger/test/internal/fn_test.clj diff --git a/src/clojure/monger/internal/fn.clj b/src/clojure/monger/internal/fn.clj deleted file mode 100644 index 8860738..0000000 --- a/src/clojure/monger/internal/fn.clj +++ /dev/null @@ -1,73 +0,0 @@ -;; Copyright (c) 2011-2014 Michael S. Klishin -;; -;; The use and distribution terms for this software are covered by the -;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) -;; which can be found in the file epl-v10.html at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. - -(ns monger.internal.fn) - - -;; -;; Implementation -;; - -(defn- apply-to-values [m f] - "Applies function f to all values in map m" - (into {} (for [[k v] m] - [k (f v)]))) - -;; -;; API -;; - -(defn fpartial - "Like clojure.core/partial but prepopulates last N arguments (first is passed in later)" - [f & args] - (fn [arg & more] (apply f arg (concat args more)))) - -(defprotocol IFNExpansion - (expand-all [x] "Replaces functions with their invocation results, recursively expands maps, evaluates all other values to themselves") - (expand-all-with [x f] "Replaces functions with their invocation results that function f is applied to, recursively expands maps, evaluates all other values to themselves")) - -(extend-protocol IFNExpansion - java.lang.Integer - (expand-all [i] i) - (expand-all-with [i f] i) - - java.lang.Long - (expand-all [l] l) - (expand-all-with [l f] l) - - java.lang.String - (expand-all [s] s) - (expand-all-with [s f] s) - - java.lang.Float - (expand-all [fl] fl) - (expand-all-with [fl f] fl) - - java.lang.Double - (expand-all [d] d) - (expand-all-with [d f] d) - - ;; maps are also functions, so be careful here. MK. - clojure.lang.IPersistentMap - (expand-all [m] (apply-to-values m expand-all)) - (expand-all-with [m f] (apply-to-values m (fpartial expand-all-with f))) - - clojure.lang.PersistentVector - (expand-all [v] (map expand-all v)) - (expand-all-with [v f] (map (fpartial expand-all-with f) v)) - - ;; this distinguishes functions from maps, sets and so on, which are also - ;; clojure.lang.AFn subclasses. MK. - clojure.lang.AFunction - (expand-all [f] (f)) - (expand-all-with [f expander] (expander f)) - - Object - (expand-all [x] x) - (expand-all-with [x f] x)) diff --git a/test/monger/test/internal/fn_test.clj b/test/monger/test/internal/fn_test.clj deleted file mode 100644 index 49bd833..0000000 --- a/test/monger/test/internal/fn_test.clj +++ /dev/null @@ -1,45 +0,0 @@ -(ns monger.test.internal.fn-test - (:require [clojure.test :refer :all] - [monger.internal.fn :refer :all])) - - -(deftest test-expand-all - (are [i o] (is (= (expand-all i) o)) - { :int (fn [] 1) :str "Clojure" :float (Float/valueOf 11.0) } { :int 1 :str "Clojure" :float (Float/valueOf 11.0 )} - { :long (fn [] (Long/valueOf 11)) } { :long (Long/valueOf 11) } - { - :i 1 - :l (Long/valueOf 1111) - :s "Clojure" - :d (Double/valueOf 11.1) - :f (Float/valueOf 2.5) - :v [1 2 3] - :dyn-v [(fn [] 10) (fn [] 20) (fn [] 30)] - :dyn-i (fn [] 1) - :dyn-s (fn [] "Clojure (expanded)") - :m { :nested "String" } - :dyn-m { :abc (fn [] :abc) :nested { :a { :b { :c (fn [] "d") } } } } - } - { - :i 1 - :l (Long/valueOf 1111) - :s "Clojure" - :d (Double/valueOf 11.1) - :f (Float/valueOf 2.5) - :v [1 2 3] - :dyn-v [10 20 30] - :dyn-i 1 - :dyn-s "Clojure (expanded)" - :m { :nested "String" } - :dyn-m { - :abc :abc - :nested { :a { :b { :c "d" } } } - } - })) - -(deftest test-expand-all-with - (let [expander-fn (fn [f] - (* 3 (f)))] - (are [i o] (is (= (expand-all-with i expander-fn) o)) - { :a 1 :int (fn [] 3) } { :a 1 :int 9 } - { :v [(fn [] 1) (fn [] 11)] :m { :inner (fn [] 3) } :s "Clojure" } { :v [3 33] :m { :inner 9 } :s "Clojure" }))) From 5fb665e5eb145590439fbaed30032a6513572fcd Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:49:55 -0400 Subject: [PATCH 19/48] Don't use removed test helper here --- test/monger/test/js_test.clj | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/monger/test/js_test.clj b/test/monger/test/js_test.clj index 0548717..5153ee1 100644 --- a/test/monger/test/js_test.clj +++ b/test/monger/test/js_test.clj @@ -1,10 +1,7 @@ (ns monger.test.js-test (:require monger.js - [monger.test.helper :as helper] [clojure.test :refer :all])) -(helper/connect!) - (deftest load-js-resource-using-path-on-the-classpath (are [c path] (= c (count (monger.js/load-resource path))) 62 "resources/mongo/js/mapfun1.js" From 58d426d6aafd171853a8eef308322b543dc7f748 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:50:03 -0400 Subject: [PATCH 20/48] Map/Reduce tests now pass --- test/monger/test/map_reduce_test.clj | 102 +++++++++++++-------------- 1 file changed, 49 insertions(+), 53 deletions(-) diff --git a/test/monger/test/map_reduce_test.clj b/test/monger/test/map_reduce_test.clj index 7228fa4..be3f460 100644 --- a/test/monger/test/map_reduce_test.clj +++ b/test/monger/test/map_reduce_test.clj @@ -2,69 +2,65 @@ (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType] org.bson.types.ObjectId java.util.Date) - (:require [monger core util] - [monger.collection :as mc] + (:require [monger.collection :as mc] + [monger.core :as mg] [monger.result :as mgres] [clojurewerkz.support.js :as js] - [monger.test.helper :as helper] [clojure.test :refer :all] [monger.operators :refer :all] - [monger.conversion :refer :all] - [monger.test.fixtures :refer :all])) + [monger.conversion :refer :all])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (use-fixtures :each (fn [f] + (mc/remove db "widgets") + (f) + (mc/remove db "widgets"))) -(use-fixtures :each purge-people purge-docs purge-things purge-libraries) - - -;; -;; Map/Reduce -;; - -(let [collection "widgets" - mapper (js/load-resource "resources/mongo/js/mapfun1.js") - reducer "function(key, values) { + (let [collection "widgets" + mapper (js/load-resource "resources/mongo/js/mapfun1.js") + reducer "function(key, values) { var result = 0; values.forEach(function(v) { result += v }); return result; }" - batch [{ :state "CA" :quantity 1 :price 199.00 } - { :state "NY" :quantity 2 :price 199.00 } - { :state "NY" :quantity 1 :price 299.00 } - { :state "IL" :quantity 2 :price 11.50 } - { :state "CA" :quantity 2 :price 2.95 } - { :state "IL" :quantity 3 :price 5.50 }] - expected [{:_id "CA", :value 204.9} {:_id "IL", :value 39.5} {:_id "NY", :value 697.0}]] - (deftest test-basic-inline-map-reduce-example - (mc/remove monger.core/*mongodb-database* collection {}) - (is (mgres/ok? (mc/insert-batch collection batch))) - (let [output (mc/map-reduce collection mapper reducer nil MapReduceCommand$OutputType/INLINE {}) - results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)] - (mgres/ok? output) - (is (= expected results)))) + batch [{ :state "CA" :quantity 1 :price 199.00 } + { :state "NY" :quantity 2 :price 199.00 } + { :state "NY" :quantity 1 :price 299.00 } + { :state "IL" :quantity 2 :price 11.50 } + { :state "CA" :quantity 2 :price 2.95 } + { :state "IL" :quantity 3 :price 5.50 }] + expected [{:_id "CA", :value 204.9} {:_id "IL", :value 39.5} {:_id "NY", :value 697.0}]] + (deftest test-basic-inline-map-reduce-example + (mc/remove db collection) + (is (mgres/ok? (mc/insert-batch db collection batch))) + (let [output (mc/map-reduce db collection mapper reducer nil MapReduceCommand$OutputType/INLINE {}) + results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)] + (mgres/ok? output) + (is (= expected results)))) - (deftest test-basic-map-reduce-example-that-replaces-named-collection - (mc/remove monger.core/*mongodb-database* collection {}) - (is (mgres/ok? (mc/insert-batch collection batch))) - (let [output (mc/map-reduce collection mapper reducer "mr_outputs" {}) - results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)] - (mgres/ok? output) - (is (= 3 (monger.core/count results))) - (is (= expected - (map #(from-db-object % true) (seq results)))) - (is (= expected - (map #(from-db-object % true) (mc/find "mr_outputs")))) - (.drop ^MapReduceOutput output))) + (deftest test-basic-map-reduce-example-that-replaces-named-collection + (mc/remove db collection) + (is (mgres/ok? (mc/insert-batch db collection batch))) + (let [output (mc/map-reduce db collection mapper reducer "mr_outputs" {}) + results (from-db-object ^DBObject (.results ^MapReduceOutput output) true)] + (mgres/ok? output) + (is (= 3 (mg/count results))) + (is (= expected + (map #(from-db-object % true) (seq results)))) + (is (= expected + (map #(from-db-object % true) (mc/find db "mr_outputs")))) + (.drop ^MapReduceOutput output))) - (deftest test-basic-map-reduce-example-that-merged-results-into-named-collection - (mc/remove monger.core/*mongodb-database* collection {}) - (is (mgres/ok? (mc/insert-batch collection batch))) - (mc/map-reduce collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {}) - (is (mgres/ok? (mc/insert collection { :state "OR" :price 17.95 :quantity 4 }))) - (let [^MapReduceOutput output (mc/map-reduce collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})] - (mgres/ok? output) - (is (= 4 (monger.core/count output))) - (is (= ["CA" "IL" "NY" "OR"] - (map :_id (mc/find-maps "merged_mr_outputs")))) - (.drop ^MapReduceOutput output)))) + (deftest test-basic-map-reduce-example-that-merged-results-into-named-collection + (mc/remove db collection) + (is (mgres/ok? (mc/insert-batch db collection batch))) + (mc/map-reduce db collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {}) + (is (mgres/ok? (mc/insert db collection { :state "OR" :price 17.95 :quantity 4 }))) + (let [^MapReduceOutput output (mc/map-reduce db collection mapper reducer "merged_mr_outputs" MapReduceCommand$OutputType/MERGE {})] + (mgres/ok? output) + (is (= 4 (mg/count output))) + (is (= ["CA" "IL" "NY" "OR"] + (map :_id (mc/find-maps db "merged_mr_outputs")))) + (.drop ^MapReduceOutput output))))) From a3954f3847d029ebe9bdd4362e00645c9f1dfd9c Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:55:28 -0400 Subject: [PATCH 21/48] Require options in monger.collection to be maps (pseudo-kwargs are no longer supported) --- src/clojure/monger/collection.clj | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/clojure/monger/collection.clj b/src/clojure/monger/collection.clj index e25283a..2166ec2 100644 --- a/src/clojure/monger/collection.clj +++ b/src/clojure/monger/collection.clj @@ -212,28 +212,28 @@ (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 db 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 db 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 db 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 db 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 db collection {:language \"Factor\"} {:language \"Clojure\"} :upsert true) + (mgcol/find-and-modify db collection {:language \"Factor\"} {:language \"Clojure\"} {:upsert true}) " - ([^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}}] + ([^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))] @@ -349,13 +349,13 @@ (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 db \"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." - [^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*}}] + [^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) @@ -370,16 +370,16 @@ sets :upsert to true. See monger.collection/update documentation" - [^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)) + [^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" - [^DB db ^String coll 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 db (name coll)) (to-db-object {:_id id}) From 353df3b8410985275ec45db4da5078071bcba54e Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 17:55:38 -0400 Subject: [PATCH 22/48] monger.result tests now pass --- test/monger/test/result_test.clj | 49 +++++++++++++++----------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/test/monger/test/result_test.clj b/test/monger/test/result_test.clj index 535dc6c..ab19f12 100644 --- a/test/monger/test/result_test.clj +++ b/test/monger/test/result_test.clj @@ -1,16 +1,11 @@ (ns monger.test.result-test (:import [com.mongodb BasicDBObject WriteResult WriteConcern] java.util.Date) - (:require [monger core collection conversion] - [monger.test.helper :as helper] + (:require [monger.core :as mg] + [monger.collection :as mc] + monger.result + monger.util [clojure.test :refer :all])) -(helper/connect!) - -;; -;; MongoCommandResult -;; - - (deftest test-ok? (let [result-that-is-not-ok-1 (doto (BasicDBObject.) (.put "ok" 0)) result-that-is-not-ok-2 (doto (BasicDBObject.) (.put "ok" "false")) @@ -28,27 +23,29 @@ (let [result-that-has-no-error1 (doto (BasicDBObject.) (.put "ok" 0)) result-that-has-no-error2 (doto (BasicDBObject.) (.put "err" "")) result-that-has-error1 (doto (BasicDBObject.) (.put "err" (BasicDBObject.)))] - (is (not (monger.result/has-error? result-that-has-no-error1))) - (is (not (monger.result/has-error? result-that-has-no-error2))) - (is (monger.result/has-error? result-that-has-error1)))) + (is (not (monger.result/has-error? result-that-has-no-error1))) + (is (not (monger.result/has-error? result-that-has-no-error2))) + (is (monger.result/has-error? result-that-has-error1)))) (deftest test-updated-existing?-with-db-object (let [input1 (doto (BasicDBObject.) (.put "updatedExisting" true)) input2 (doto (BasicDBObject.) (.put "updatedExisting" false)) input3 (BasicDBObject.)] - (is (monger.result/updated-existing? input1)) - (is (not (monger.result/updated-existing? input2))) - (is (not (monger.result/updated-existing? input3))))) + (is (monger.result/updated-existing? input1)) + (is (not (monger.result/updated-existing? input2))) + (is (not (monger.result/updated-existing? input3))))) -(deftest test-updated-existing?-with-write-result - (monger.collection/remove "libraries") - (let [collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } - modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] - (is (not (monger.result/updated-existing? (monger.collection/update collection { :language "Clojure" } doc :upsert true)))) - (is (monger.result/updated-existing? (monger.collection/update collection { :language "Clojure" } doc :upsert true))) - (monger.result/updated-existing? (monger.collection/update collection { :language "Clojure" } modified-doc :multi false :upsert true)) - (monger.collection/remove collection))) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (deftest test-updated-existing?-with-write-result + (mc/remove db "libraries") + (let [collection "libraries" + doc-id (monger.util/random-uuid) + date (Date.) + doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } + modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] + (is (not (monger.result/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true})))) + (is (monger.result/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true}))) + (monger.result/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true})) + (mc/remove db collection)))) From eddc8b20bdb605b697d32359f07393a0634afded Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 10 May 2014 18:05:25 -0400 Subject: [PATCH 23/48] Regular finders tests now pass --- test/monger/test/regular_finders_test.clj | 453 +++++++++++----------- 1 file changed, 230 insertions(+), 223 deletions(-) diff --git a/test/monger/test/regular_finders_test.clj b/test/monger/test/regular_finders_test.clj index 18104cd..e537dfb 100644 --- a/test/monger/test/regular_finders_test.clj +++ b/test/monger/test/regular_finders_test.clj @@ -2,276 +2,283 @@ (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject] org.bson.types.ObjectId java.util.Date) - (:require [monger core util] - [monger.collection :as mgcol] + (:require [monger.core :as mg] + [monger.collection :as mc] + [monger.util :as mu] [monger.result :as mgres] [monger.conversion :as mgcnv] - [monger.test.helper :as helper] [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) + [monger.operators :refer :all])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (use-fixtures :each (fn [f] + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "regular_finders_docs") + (mc/remove db "things") + (mc/remove db "libraries") + (f) + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "regular_finders_docs") + (mc/remove db "things") + (mc/remove db "libraries"))) -(use-fixtures :each purge-people purge-docs purge-things purge-libraries - purge-finder-docs) + ;; + ;; find-one + ;; + + (deftest find-one-full-document-when-collection-is-empty + (let [collection "regular_finders_docs"] + (is (nil? (mc/find-one db collection {}))))) + + (deftest find-one-full-document-as-map-when-collection-is-empty + (let [collection "regular_finders_docs"] + (mc/remove db collection) + (is (nil? (mc/find-one-as-map db collection {}))))) -;; -;; find-one -;; + (deftest find-one-full-document-when-collection-has-matches + (let [collection "regular_finders_docs" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } + _ (mc/insert db collection doc) + found-one (mc/find-one db collection { :language "Clojure" })] + (is found-one) + (is (= (:_id doc) (mu/get-id found-one))) + (is (= (mgcnv/from-db-object found-one true) doc)) + (is (= (mgcnv/to-db-object doc) found-one)))) -(deftest find-one-full-document-when-collection-is-empty - (let [collection "regular_finders_docs"] - (is (nil? (mgcol/find-one collection {}))))) - -(deftest find-one-full-document-as-map-when-collection-is-empty - (let [collection "regular_finders_docs"] - (mgcol/remove collection) - (is (nil? (mgcol/find-one-as-map collection {}))))) - - -(deftest find-one-full-document-when-collection-has-matches - (let [collection "regular_finders_docs" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } - _ (mgcol/insert collection doc) - found-one (mgcol/find-one collection { :language "Clojure" })] - (is found-one) - (is (= (:_id doc) (monger.util/get-id found-one))) - (is (= (mgcnv/from-db-object found-one true) doc)) - (is (= (mgcnv/to-db-object doc) found-one)))) - -(deftest find-one-full-document-as-map-when-collection-has-matches - (let [collection "regular_finders_docs" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] - (mgcol/insert collection doc) - (is (= doc (mgcol/find-one-as-map collection { :language "Clojure" }))))) + (deftest find-one-full-document-as-map-when-collection-has-matches + (let [collection "regular_finders_docs" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] + (mc/insert db collection doc) + (is (= doc (mc/find-one-as-map db collection { :language "Clojure" }))))) -(deftest find-one-partial-document-when-collection-has-matches - (let [collection "regular_finders_docs" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } - _ (mgcol/insert collection doc) - loaded (mgcol/find-one collection { :language "Clojure" } [:language])] - (is (nil? (.get ^DBObject loaded "data-store"))) - (is (= doc-id (monger.util/get-id loaded))) - (is (= "Clojure" (.get ^DBObject loaded "language"))))) + (deftest find-one-partial-document-when-collection-has-matches + (let [collection "regular_finders_docs" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } + _ (mc/insert db collection doc) + loaded (mc/find-one db collection { :language "Clojure" } [:language])] + (is (nil? (.get ^DBObject loaded "data-store"))) + (is (= doc-id (mu/get-id loaded))) + (is (= "Clojure" (.get ^DBObject loaded "language"))))) -(deftest find-one-partial-document-using-field-negation-when-collection-has-matches - (let [collection "regular_finders_docs" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } - _ (mgcol/insert collection doc) - ^DBObject loaded (mgcol/find-one collection { :language "Clojure" } {:data-store 0 :_id 0})] - (is (nil? (.get loaded "data-store"))) - (is (nil? (.get loaded "_id"))) - (is (nil? (monger.util/get-id loaded))) - (is (= "Clojure" (.get loaded "language"))))) + (deftest find-one-partial-document-using-field-negation-when-collection-has-matches + (let [collection "regular_finders_docs" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } + _ (mc/insert db collection doc) + ^DBObject loaded (mc/find-one db collection { :language "Clojure" } {:data-store 0 :_id 0})] + (is (nil? (.get loaded "data-store"))) + (is (nil? (.get loaded "_id"))) + (is (nil? (mu/get-id loaded))) + (is (= "Clojure" (.get loaded "language"))))) -(deftest find-one-partial-document-as-map-when-collection-has-matches - (let [collection "regular_finders_docs" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] - (mgcol/insert collection doc) - (is (= { :data-store "MongoDB", :_id doc-id } (mgcol/find-one-as-map collection { :language "Clojure" } [:data-store]))))) + (deftest find-one-partial-document-as-map-when-collection-has-matches + (let [collection "regular_finders_docs" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] + (mc/insert db collection doc) + (is (= { :data-store "MongoDB", :_id doc-id } + (mc/find-one-as-map db collection { :language "Clojure" } [:data-store]))))) -(deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize - (let [collection "regular_finders_docs" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } - fields [:data-store] - _id (mgcol/insert collection doc) - loaded (mgcol/find-one-as-map collection { :language "Clojure" } fields true) - ] - (is (= { :data-store "MongoDB", :_id doc-id } loaded )))) + (deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize + (let [collection "regular_finders_docs" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } + fields [:data-store] + _id (mc/insert db collection doc) + loaded (mc/find-one-as-map db collection { :language "Clojure" } fields true) + ] + (is (= { :data-store "MongoDB", :_id doc-id } loaded )))) -(deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize-false - (let [collection "regular_finders_docs" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } - fields [:data-store] - _id (mgcol/insert collection doc) - loaded (mgcol/find-one-as-map collection { :language "Clojure" } fields false) - ] - (is (= { "_id" doc-id, "data-store" "MongoDB" } loaded )))) + (deftest find-one-partial-document-as-map-when-collection-has-matches-with-keywordize-false + (let [collection "regular_finders_docs" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } + fields [:data-store] + _id (mc/insert db collection doc) + loaded (mc/find-one-as-map db collection { :language "Clojure" } fields false)] + (is (= { "_id" doc-id, "data-store" "MongoDB" } loaded )))) -;; -;; find-by-id -;; + ;; + ;; find-by-id + ;; -(deftest find-full-document-by-string-id-when-that-document-does-not-exist - (let [collection "libraries" - doc-id (monger.util/random-uuid)] - (is (nil? (mgcol/find-by-id collection doc-id))))) + (deftest find-full-document-by-string-id-when-that-document-does-not-exist + (let [collection "libraries" + doc-id (mu/random-uuid)] + (is (nil? (mc/find-by-id db collection doc-id))))) -(deftest find-full-document-by-string-id-when-id-is-nil - (let [collection "libraries" - doc-id nil] - (is (thrown? IllegalArgumentException (mgcol/find-by-id collection doc-id))))) + (deftest find-full-document-by-string-id-when-id-is-nil + (let [collection "libraries" + doc-id nil] + (is (thrown? IllegalArgumentException (mc/find-by-id db collection doc-id))))) -(deftest find-full-document-by-object-id-when-that-document-does-not-exist - (let [collection "libraries" - doc-id (ObjectId.)] - (is (nil? (mgcol/find-by-id collection doc-id))))) + (deftest find-full-document-by-object-id-when-that-document-does-not-exist + (let [collection "libraries" + doc-id (ObjectId.)] + (is (nil? (mc/find-by-id db collection doc-id))))) -(deftest find-full-document-by-id-as-map-when-that-document-does-not-exist - (let [collection "libraries" - doc-id (monger.util/random-uuid)] - (is (nil? (mgcol/find-map-by-id collection doc-id))))) + (deftest find-full-document-by-id-as-map-when-that-document-does-not-exist + (let [collection "libraries" + doc-id (mu/random-uuid)] + (is (nil? (mc/find-map-by-id db collection doc-id))))) -(deftest find-full-document-by-id-as-map-when-id-is-nil - (let [collection "libraries" - doc-id nil] - (is (thrown? IllegalArgumentException - (mgcol/find-map-by-id collection doc-id))))) + (deftest find-full-document-by-id-as-map-when-id-is-nil + (let [collection "libraries" + doc-id nil] + (is (thrown? IllegalArgumentException + (mc/find-map-by-id db collection doc-id))))) -(deftest find-full-document-by-string-id-when-document-does-exist - (let [collection "libraries" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] - (mgcol/insert collection doc) - (is (= (doc (mgcol/find-by-id collection doc-id)))))) + (deftest find-full-document-by-string-id-when-document-does-exist + (let [collection "libraries" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] + (mc/insert db collection doc) + (is (= (doc (mc/find-by-id db collection doc-id)))))) -(deftest find-full-document-by-object-id-when-document-does-exist - (let [collection "libraries" - doc-id (ObjectId.) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] - (mgcol/insert collection doc) - (is (= (doc (mgcol/find-by-id collection doc-id)))))) + (deftest find-full-document-by-object-id-when-document-does-exist + (let [collection "libraries" + doc-id (ObjectId.) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] + (mc/insert db collection doc) + (is (= (doc (mc/find-by-id db collection doc-id)))))) -(deftest find-full-document-map-by-string-id-when-document-does-exist - (let [collection "libraries" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] - (mgcol/insert collection doc) - (is (= (doc (mgcol/find-map-by-id collection doc-id)))))) + (deftest find-full-document-map-by-string-id-when-document-does-exist + (let [collection "libraries" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] + (mc/insert db collection doc) + (is (= (doc (mc/find-map-by-id db collection doc-id)))))) -(deftest find-full-document-map-by-object-id-when-document-does-exist - (let [collection "libraries" - doc-id (ObjectId.) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] - (mgcol/insert collection doc) - (is (= (doc (mgcol/find-map-by-id collection doc-id)))))) + (deftest find-full-document-map-by-object-id-when-document-does-exist + (let [collection "libraries" + doc-id (ObjectId.) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] + (mc/insert db collection doc) + (is (= (doc (mc/find-map-by-id db collection doc-id)))))) -(deftest find-partial-document-by-id-when-document-does-exist - (let [collection "libraries" - doc-id (monger.util/random-uuid) - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] - (mgcol/insert collection doc) - (is (= ({ :language "Clojure" } (mgcol/find-by-id collection doc-id [ :language ])))))) + (deftest find-partial-document-by-id-when-document-does-exist + (let [collection "libraries" + doc-id (mu/random-uuid) + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id }] + (mc/insert db collection doc) + (is (= ({ :language "Clojure" } + (mc/find-by-id db collection doc-id [ :language ])))))) -(deftest find-partial-document-as-map-by-id-when-document-does-exist - (let [collection "libraries" - doc-id (monger.util/random-uuid) - fields [:data-store] - doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } - _ (mgcol/insert collection doc) - loaded (mgcol/find-map-by-id collection doc-id [ :language ])] - (is (= { :language "Clojure", :_id doc-id } loaded )) - ) -) + (deftest find-partial-document-as-map-by-id-when-document-does-exist + (let [collection "libraries" + doc-id (mu/random-uuid) + fields [:data-store] + doc { :data-store "MongoDB", :language "Clojure", :_id doc-id } + _ (mc/insert db collection doc) + loaded (mc/find-map-by-id db collection doc-id [ :language ])] + (is (= { :language "Clojure", :_id doc-id } loaded )))) -;; -;; find -;; + ;; + ;; find + ;; -(deftest find-full-document-when-collection-is-empty - (let [collection "regular_finders_docs" - cursor (mgcol/find collection)] - (is (empty? (iterator-seq cursor))))) + (deftest find-full-document-when-collection-is-empty + (let [collection "regular_finders_docs" + cursor (mc/find db collection)] + (is (empty? (iterator-seq cursor))))) -(deftest find-document-seq-when-collection-is-empty - (let [collection "regular_finders_docs"] - (is (empty? (mgcol/find-seq collection))))) + (deftest find-document-seq-when-collection-is-empty + (let [collection "regular_finders_docs"] + (is (empty? (mc/find-seq db collection))))) -(deftest find-multiple-documents-when-collection-is-empty - (let [collection "libraries"] - (is (empty? (mgcol/find collection { :language "Scala" }))))) + (deftest find-multiple-documents-when-collection-is-empty + (let [collection "libraries"] + (is (empty? (mc/find db collection { :language "Scala" }))))) -(deftest find-multiple-maps-when-collection-is-empty - (let [collection "libraries"] - (is (empty? (mgcol/find-maps collection { :language "Scala" }))))) + (deftest find-multiple-maps-when-collection-is-empty + (let [collection "libraries"] + (is (empty? (mc/find-maps db collection { :language "Scala" }))))) -(deftest find-multiple-documents-by-regex - (let [collection "libraries"] - (mgcol/insert-batch collection [{ :language "Clojure", :name "monger" } - { :language "Java", :name "nhibernate" } - { :language "JavaScript", :name "sprout-core" }]) - (is (= 2 (monger.core/count (mgcol/find collection { :language #"Java*" })))))) + (deftest find-multiple-documents-by-regex + (let [collection "libraries"] + (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } + { :language "Java", :name "nhibernate" } + { :language "JavaScript", :name "sprout-core" }]) + (is (= 2 (monger.core/count (mc/find db collection { :language #"Java*" })))))) -(deftest find-multiple-documents - (let [collection "libraries"] - (mgcol/insert-batch collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (is (= 1 (monger.core/count (mgcol/find collection { :language "Scala" })))) - (is (= 3 (.count (mgcol/find collection { :language "Clojure" })))) - (is (empty? (mgcol/find collection { :language "Java" }))))) + (deftest find-multiple-documents + (let [collection "libraries"] + (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } + { :language "Clojure", :name "langohr" } + { :language "Clojure", :name "incanter" } + { :language "Scala", :name "akka" }]) + (is (= 1 (monger.core/count (mc/find db collection { :language "Scala" })))) + (is (= 3 (.count (mc/find db collection { :language "Clojure" })))) + (is (empty? (mc/find db collection { :language "Java" }))))) -(deftest find-document-specify-fields - (let [collection "libraries" - _ (mgcol/insert collection { :language "Clojure", :name "monger" }) - result (mgcol/find collection { :language "Clojure"} [:language])] - (is (= (seq [:_id :language]) (keys (mgcnv/from-db-object (.next result) true)))))) + (deftest find-document-specify-fields + (let [collection "libraries" + _ (mc/insert db collection { :language "Clojure", :name "monger" }) + result (mc/find db collection { :language "Clojure"} [:language])] + (is (= (seq [:_id :language]) (keys (mgcnv/from-db-object (.next result) true)))))) -(deftest find-and-iterate-over-multiple-documents-the-hard-way - (let [collection "libraries"] - (mgcol/insert-batch collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (doseq [doc (take 3 (map (fn [dbo] - (mgcnv/from-db-object dbo true)) - (mgcol/find-seq collection { :language "Clojure" })))] - (is (= "Clojure" (:language doc)))))) + (deftest find-and-iterate-over-multiple-documents-the-hard-way + (let [collection "libraries"] + (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } + { :language "Clojure", :name "langohr" } + { :language "Clojure", :name "incanter" } + { :language "Scala", :name "akka" }]) + (doseq [doc (take 3 (map (fn [dbo] + (mgcnv/from-db-object dbo true)) + (mc/find-seq db collection { :language "Clojure" })))] + (is (= "Clojure" (:language doc)))))) -(deftest find-and-iterate-over-multiple-documents - (let [collection "libraries"] - (mgcol/insert-batch collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (doseq [doc (take 3 (mgcol/find-maps collection { :language "Clojure" }))] - (is (= "Clojure" (:language doc)))))) + (deftest find-and-iterate-over-multiple-documents + (let [collection "libraries"] + (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } + { :language "Clojure", :name "langohr" } + { :language "Clojure", :name "incanter" } + { :language "Scala", :name "akka" }]) + (doseq [doc (take 3 (mc/find-maps db collection { :language "Clojure" }))] + (is (= "Clojure" (:language doc)))))) -(deftest find-multiple-maps - (let [collection "libraries"] - (mgcol/insert-batch collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (is (= 1 (clojure.core/count (mgcol/find-maps collection { :language "Scala" })))) - (is (= 3 (.count (mgcol/find-maps collection { :language "Clojure" })))) - (is (empty? (mgcol/find-maps collection { :language "Java" }))) - (is (empty? (mgcol/find-maps monger.core/*mongodb-database* collection { :language "Java" } [:language :name]))))) + (deftest find-multiple-maps + (let [collection "libraries"] + (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } + { :language "Clojure", :name "langohr" } + { :language "Clojure", :name "incanter" } + { :language "Scala", :name "akka" }]) + (is (= 1 (clojure.core/count (mc/find-maps db collection { :language "Scala" })))) + (is (= 3 (.count (mc/find-maps db collection { :language "Clojure" })))) + (is (empty? (mc/find-maps db collection { :language "Java" }))) + (is (empty? (mc/find-maps db collection { :language "Java" } [:language :name]))))) -(deftest find-multiple-partial-documents - (let [collection "libraries"] - (mgcol/insert-batch collection [{ :language "Clojure", :name "monger" } - { :language "Clojure", :name "langohr" } - { :language "Clojure", :name "incanter" } - { :language "Scala", :name "akka" }]) - (let [scala-libs (mgcol/find collection { :language "Scala" } [:name]) - clojure-libs (mgcol/find collection { :language "Clojure"} [:language])] - (is (= 1 (.count scala-libs))) - (is (= 3 (.count clojure-libs))) - (doseq [i clojure-libs] - (let [doc (mgcnv/from-db-object i true)] - (is (= (:language doc) "Clojure")))) - (is (empty? (mgcol/find collection { :language "Erlang" } [:name])))))) + (deftest find-multiple-partial-documents + (let [collection "libraries"] + (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } + { :language "Clojure", :name "langohr" } + { :language "Clojure", :name "incanter" } + { :language "Scala", :name "akka" }]) + (let [scala-libs (mc/find db collection { :language "Scala" } [:name]) + clojure-libs (mc/find db collection { :language "Clojure"} [:language])] + (is (= 1 (.count scala-libs))) + (is (= 3 (.count clojure-libs))) + (doseq [i clojure-libs] + (let [doc (mgcnv/from-db-object i true)] + (is (= (:language doc) "Clojure")))) + (is (empty? (mc/find db collection { :language "Erlang" } [:name]))))))) From c75b02814d0c1310c28b7cd89779ce249873df16 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 12:36:14 -0400 Subject: [PATCH 24/48] Stress test now passes --- test/monger/test/stress_test.clj | 63 ++++++++++++++------------------ 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/test/monger/test/stress_test.clj b/test/monger/test/stress_test.clj index 6aae96b..075fe17 100644 --- a/test/monger/test/stress_test.clj +++ b/test/monger/test/stress_test.clj @@ -1,42 +1,35 @@ (ns monger.test.stress-test - (:import [com.mongodb Mongo DB DBCollection WriteResult DBObject WriteConcern DBCursor] - java.util.Date) - (:require monger.core - [monger.test.helper :as helper] - [clojure.test :refer :all])) + (:require [monger.core :as mg] + [monger.collection :as mc] + [monger.conversion :refer [to-db-object]] + [clojure.test :refer :all]) + (:import [com.mongodb WriteConcern] + java.util.Date)) -;; -;; Fixture functions -;; +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (defn purge-collection + [coll f] + (mc/remove db coll) + (f) + (mc/remove db coll)) -(defn purge-collection - [collection-name, f] - (monger.collection/remove collection-name) - (f) - (monger.collection/remove collection-name)) + (defn purge-things-collection + [f] + (purge-collection "things" f)) -(defn purge-things-collection - [f] - (purge-collection "things" f)) + (use-fixtures :each purge-things-collection) -(use-fixtures :each purge-things-collection) + (monger.core/set-default-write-concern! WriteConcern/NORMAL) - - -;; -;; Tests -;; - -(monger.core/set-default-write-concern! WriteConcern/NORMAL) - -(deftest ^{:performance true} insert-large-batches-of-documents-without-object-ids - (doseq [n [1000 10000 100000]] - (let [collection "things" - docs (map (fn [i] - (monger.conversion/to-db-object { :title "Untitled" :created-at (Date.) :number i })) - (take n (iterate inc 1)))] - (monger.collection/remove collection) - (println "Inserting " n " documents...") - (time (monger.collection/insert-batch collection docs)) - (is (= n (monger.collection/count collection)))))) + (deftest ^{:performance true} insert-large-batches-of-documents-without-object-ids + (doseq [n [1000 10000 100000]] + (let [collection "things" + docs (map (fn [i] + (to-db-object { :title "Untitled" :created-at (Date.) :number i })) + (take n (iterate inc 1)))] + (mc/remove db collection) + (println "Inserting " n " documents...") + (time (mc/insert-batch db collection docs)) + (is (= n (mc/count db collection))))))) From f0722561c304eeca2538db3eb83a74c2f6632d49 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 12:42:23 -0400 Subject: [PATCH 25/48] Run fewer cycles Saves laptop batter while I'm on this flight, yo. --- test/monger/test/stress_test.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/monger/test/stress_test.clj b/test/monger/test/stress_test.clj index 075fe17..0b57882 100644 --- a/test/monger/test/stress_test.clj +++ b/test/monger/test/stress_test.clj @@ -24,7 +24,7 @@ (monger.core/set-default-write-concern! WriteConcern/NORMAL) (deftest ^{:performance true} insert-large-batches-of-documents-without-object-ids - (doseq [n [1000 10000 100000]] + (doseq [n [10 100 1000 10000 20000 30000]] (let [collection "things" docs (map (fn [i] (to-db-object { :title "Untitled" :created-at (Date.) :number i })) From 37e8df83006460253cd72a27b9ac88e0db24b596 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 12:42:33 -0400 Subject: [PATCH 26/48] And even fewer --- test/monger/test/stress_test.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/monger/test/stress_test.clj b/test/monger/test/stress_test.clj index 0b57882..344f4b2 100644 --- a/test/monger/test/stress_test.clj +++ b/test/monger/test/stress_test.clj @@ -24,7 +24,7 @@ (monger.core/set-default-write-concern! WriteConcern/NORMAL) (deftest ^{:performance true} insert-large-batches-of-documents-without-object-ids - (doseq [n [10 100 1000 10000 20000 30000]] + (doseq [n [10 100 1000 10000 20000]] (let [collection "things" docs (map (fn [i] (to-db-object { :title "Untitled" :created-at (Date.) :number i })) From 9752950d8220a6e0e6454e23c7234cb57cabc6cb Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 12:50:15 -0400 Subject: [PATCH 27/48] Add extra arities to several update functions --- src/clojure/monger/collection.clj | 54 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/clojure/monger/collection.clj b/src/clojure/monger/collection.clj index 2166ec2..35b5708 100644 --- a/src/clojure/monger/collection.clj +++ b/src/clojure/monger/collection.clj @@ -352,16 +352,18 @@ (monger.collection/update db \"people\" {:first_name \"Yoko\"} {:first_name \"Yoko\" :last_name \"Ono\"} {:upsert true) By default :upsert and :multi are false." - [^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)) + ([^DB db ^String coll ^Map conditions ^Map document] + (update db coll conditions document {})) + ([^DB db ^String coll ^Map conditions ^Map document {:keys [upsert multi write-concern] + :or {upsert false + multi false + write-concern monger.core/*mongodb-write-concern*}}] + (.update (.getCollection db (name coll)) + (to-db-object conditions) + (to-db-object document) + upsert + multi + write-concern))) (defn ^WriteResult upsert "Performs an upsert. @@ -370,23 +372,27 @@ sets :upsert to true. See monger.collection/update documentation" - [^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})) + ([^DB db ^String coll ^Map conditions ^Map document] + (upsert db coll conditions document {})) + ([^DB db ^String coll ^Map conditions ^Map document {:keys [multi write-concern] + :or {multi false + write-concern monger.core/*mongodb-write-concern*}}] + (update db coll conditions document {:multi multi :write-concern write-concern :upsert true}))) (defn ^WriteResult update-by-id "Update a document with given id" - [^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 db (name coll)) - (to-db-object {:_id id}) - (to-db-object document) - upsert - false - write-concern)) + ([^DB db ^String coll id ^Map document] + (update-by-id db coll id document {})) + ([^DB db ^String coll id ^Map document {:keys [upsert write-concern] + :or {upsert false + write-concern monger.core/*mongodb-write-concern*}}] + (check-not-nil! id "id must not be nil") + (.update (.getCollection db (name coll)) + (to-db-object {:_id id}) + (to-db-object document) + upsert + false + write-concern))) ;; monger.collection/save From c64f5a66d9bf61070456e95df18a1c2cd28a55ef Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 12:50:21 -0400 Subject: [PATCH 28/48] Updating test now passes --- test/monger/test/updating_test.clj | 274 +++++++++++++++-------------- 1 file changed, 140 insertions(+), 134 deletions(-) diff --git a/test/monger/test/updating_test.clj b/test/monger/test/updating_test.clj index 2bf6f79..b7557a5 100644 --- a/test/monger/test/updating_test.clj +++ b/test/monger/test/updating_test.clj @@ -2,162 +2,168 @@ (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject] org.bson.types.ObjectId java.util.Date) - (:require [monger core util] + (:require [monger.core :as mg] [monger.collection :as mc] + [monger.util :as mu] [monger.result :as mr] - [monger.test.helper :as helper] [clojure.test :refer :all] [monger.operators :refer :all] - [monger.test.fixtures :refer :all] [monger.conversion :refer [to-db-object]])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (defn purge-collections + [f] + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "libraries") + (f) + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "libraries")) -(use-fixtures :each purge-people purge-docs purge-things purge-libraries) + (use-fixtures :each purge-collections) + + (deftest ^{:updating true} update-document-by-id-without-upsert + (let [collection "libraries" + doc-id (mu/random-uuid) + date (Date.) + doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } + modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] + (mc/insert db collection doc) + (is (= (doc (mc/find-by-id db collection doc-id)))) + (mc/update db collection { :_id doc-id } { :language "Erlang" }) + (is (= (modified-doc (mc/find-by-id db collection doc-id)))))) + + (deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id + (let [collection "libraries" + doc-id (mu/random-uuid) + date (Date.) + doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } + modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] + (mc/insert db collection doc) + (is (= (doc (mc/find-by-id db collection doc-id)))) + (mc/update-by-id db collection doc-id { :language "Erlang" }) + (is (= (modified-doc (mc/find-by-id db collection doc-id)))))) + + (deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id + (let [collection "libraries" + doc-id (ObjectId.) + date (Date.) + doc { :created-at date :data-store "MongoDB" :language { :primary "Clojure" } :_id doc-id } + modified-doc { :created-at date :data-store "MongoDB" :language { :primary "Erlang" } :_id doc-id }] + (mc/insert db collection doc) + (is (= (doc (mc/find-by-id db collection doc-id)))) + (mc/update-by-id db collection doc-id { $set { "language.primary" "Erlang" }}) + (is (= (modified-doc (mc/find-by-id db collection doc-id)))))) -;; -;; update, save -;; - -(deftest ^{:updating true} update-document-by-id-without-upsert - (let [collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } - modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] - (mc/insert collection doc) - (is (= (doc (mc/find-by-id collection doc-id)))) - (mc/update collection { :_id doc-id } { :language "Erlang" }) - (is (= (modified-doc (mc/find-by-id collection doc-id)))))) - -(deftest ^{:updating true} update-document-by-id-without-upsert-using-update-by-id - (let [collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } - modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] - (mc/insert collection doc) - (is (= (doc (mc/find-by-id collection doc-id)))) - (mc/update-by-id collection doc-id { :language "Erlang" }) - (is (= (modified-doc (mc/find-by-id collection doc-id)))))) - -(deftest ^{:updating true} update-nested-document-fields-without-upsert-using-update-by-id - (let [collection "libraries" - doc-id (ObjectId.) - date (Date.) - doc { :created-at date :data-store "MongoDB" :language { :primary "Clojure" } :_id doc-id } - modified-doc { :created-at date :data-store "MongoDB" :language { :primary "Erlang" } :_id doc-id }] - (mc/insert collection doc) - (is (= (doc (mc/find-by-id collection doc-id)))) - (mc/update-by-id collection doc-id { $set { "language.primary" "Erlang" }}) - (is (= (modified-doc (mc/find-by-id collection doc-id)))))) + (deftest ^{:updating true} update-multiple-documents + (let [collection "libraries"] + (mc/insert-batch db collection [{ :language "Clojure", :name "monger" } + { :language "Clojure", :name "langohr" } + { :language "Clojure", :name "incanter" } + { :language "Scala", :name "akka" }]) + (is (= 3 (mc/count db collection { :language "Clojure" }))) + (is (= 1 (mc/count db collection { :language "Scala" }))) + (is (= 0 (mc/count db collection { :language "Python" }))) + (mc/update db collection { :language "Clojure" } { $set { :language "Python" } } {:multi true}) + (is (= 0 (mc/count db collection { :language "Clojure" }))) + (is (= 1 (mc/count db collection { :language "Scala" }))) + (is (= 3 (mc/count db collection { :language "Python" }))))) -(deftest ^{:updating true} update-multiple-documents - (let [collection "libraries"] - (mc/insert collection { :language "Clojure", :name "monger" }) - (mc/insert collection { :language "Clojure", :name "langohr" }) - (mc/insert collection { :language "Clojure", :name "incanter" }) - (mc/insert collection { :language "Scala", :name "akka" }) - (is (= 3 (mc/count collection { :language "Clojure" }))) - (is (= 1 (mc/count collection { :language "Scala" }))) - (is (= 0 (mc/count collection { :language "Python" }))) - (mc/update collection { :language "Clojure" } { $set { :language "Python" } } :multi true) - (is (= 0 (mc/count collection { :language "Clojure" }))) - (is (= 1 (mc/count collection { :language "Scala" }))) - (is (= 3 (mc/count collection { :language "Python" }))))) + (deftest ^{:updating true} save-a-new-document + (let [collection "people" + document {:name "Joe" :age 30}] + (is (mr/ok? (mc/save db "people" document))) + (is (= 1 (mc/count db collection))))) + + (deftest ^{:updating true} save-and-return-a-new-document + (let [collection "people" + document {:name "Joe" :age 30} + returned (mc/save-and-return db "people" document)] + (is (:_id returned)) + (is (= document (dissoc returned :_id))) + (is (= 1 (mc/count db collection))))) -(deftest ^{:updating true} save-a-new-document - (let [collection "people" - document {:name "Joe" :age 30}] - (is (mr/ok? (mc/save "people" document))) - (is (= 1 (mc/count collection))))) - -(deftest ^{:updating true} save-and-return-a-new-document - (let [collection "people" - document {:name "Joe" :age 30} - returned (mc/save-and-return "people" document)] - (is (:_id returned)) - (is (= document (dissoc returned :_id))) - (is (= 1 (mc/count collection))))) - - -(deftest ^{:updating true} save-a-new-basic-db-object - (let [collection "people" - doc (to-db-object {:name "Joe" :age 30})] - (is (nil? (monger.util/get-id doc))) - (mc/save monger.core/*mongodb-database* "people" doc WriteConcern/SAFE) - (is (not (nil? (monger.util/get-id doc)))))) + (deftest ^{:updating true} save-a-new-basic-db-object + (let [collection "people" + doc (to-db-object {:name "Joe" :age 30})] + (is (nil? (mu/get-id doc))) + (mc/save db "people" doc WriteConcern/SAFE) + (is (not (nil? (mu/get-id doc)))))) -(deftest ^{:updating true} update-an-existing-document-using-save - (let [collection "people" - doc-id "people-1" - document { :_id doc-id, :name "Joe", :age 30 }] - (is (mr/ok? (mc/insert "people" document))) - (is (= 1 (mc/count collection))) - (mc/save collection { :_id doc-id, :name "Alan", :age 40 }) - (is (= 1 (mc/count collection { :name "Alan", :age 40 }))))) + (deftest ^{:updating true} update-an-existing-document-using-save + (let [collection "people" + doc-id "people-1" + document { :_id doc-id, :name "Joe", :age 30 }] + (is (mr/ok? (mc/insert db collection document))) + (is (= 1 (mc/count db collection))) + (mc/save db collection { :_id doc-id, :name "Alan", :age 40 }) + (is (= 1 (mc/count db collection { :name "Alan", :age 40 }))))) -(deftest ^{:updating true} update-an-existing-document-using-save-and-return - (let [collection "people" - document (mc/insert-and-return "people" {:name "Joe" :age 30}) - doc-id (:_id document) - updated (mc/save-and-return collection {:_id doc-id :name "Alan" :age 40})] - (is (= {:_id doc-id :name "Alan" :age 40} updated)) - (is (= 1 (mc/count collection))) - (is (= 1 (mc/count collection {:name "Alan" :age 40}))))) + (deftest ^{:updating true} update-an-existing-document-using-save-and-return + (let [collection "people" + document (mc/insert-and-return db collection {:name "Joe" :age 30}) + doc-id (:_id document) + updated (mc/save-and-return db collection {:_id doc-id :name "Alan" :age 40})] + (is (= {:_id doc-id :name "Alan" :age 40} updated)) + (is (= 1 (mc/count db collection))) + (is (= 1 (mc/count db collection {:name "Alan" :age 40}))))) -(deftest ^{:updating true} set-an-attribute-on-existing-document-using-update - (let [collection "people" - doc-id (monger.util/object-id) - document { :_id doc-id, :name "Joe", :age 30 }] - (is (mr/ok? (mc/insert "people" document))) - (is (= 1 (mc/count collection))) - (is (= 0 (mc/count collection { :has_kids true }))) - (mc/update collection { :_id doc-id } { $set { :has_kids true } }) - (is (= 1 (mc/count collection { :has_kids true }))))) + (deftest ^{:updating true} set-an-attribute-on-existing-document-using-update + (let [collection "people" + doc-id (mu/object-id) + document { :_id doc-id, :name "Joe", :age 30 }] + (is (mr/ok? (mc/insert db collection document))) + (is (= 1 (mc/count db collection))) + (is (= 0 (mc/count db collection { :has_kids true }))) + (mc/update db collection { :_id doc-id } { $set { :has_kids true } }) + (is (= 1 (mc/count db collection { :has_kids true }))))) -(deftest ^{:updating true} increment-multiple-fields-using-exists-operator-and-update - (let [collection "matches" - doc-id (monger.util/object-id) - document { :_id doc-id :abc 0 :def 10 }] - (mc/remove collection) - (is (mr/ok? (mc/insert collection document))) - (is (= 1 (mc/count collection {:abc {$exists true} :def {$exists true}}))) - (mc/update collection {:abc {$exists true} :def {$exists true}} {$inc {:abc 1 :def 0}}) - (is (= 1 (mc/count collection { :abc 1 }))))) + (deftest ^{:updating true} increment-multiple-fields-using-exists-operator-and-update + (let [collection "matches" + doc-id (mu/object-id) + document { :_id doc-id :abc 0 :def 10 }] + (mc/remove db collection) + (is (mr/ok? (mc/insert db collection document))) + (is (= 1 (mc/count db collection {:abc {$exists true} :def {$exists true}}))) + (mc/update db collection {:abc {$exists true} :def {$exists true}} {$inc {:abc 1 :def 0}}) + (is (= 1 (mc/count db collection { :abc 1 }))))) -(deftest ^{:updating true} upsert-a-document-using-update - (let [collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } - modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] - (is (not (mr/updated-existing? (mc/update collection { :language "Clojure" } doc :upsert true)))) - (is (= 1 (mc/count collection))) - (is (mr/updated-existing? (mc/update collection { :language "Clojure" } modified-doc :multi false :upsert true))) - (is (= 1 (mc/count collection))) - (is (= (modified-doc (mc/find-by-id collection doc-id)))) - (mc/remove collection))) + (deftest ^{:updating true} upsert-a-document-using-update + (let [collection "libraries" + doc-id (mu/random-uuid) + date (Date.) + doc { :created-at date, :data-store "MongoDB", :language "Clojure", :_id doc-id } + modified-doc { :created-at date, :data-store "MongoDB", :language "Erlang", :_id doc-id }] + (is (not (mr/updated-existing? (mc/update db collection { :language "Clojure" } doc {:upsert true})))) + (is (= 1 (mc/count db collection))) + (is (mr/updated-existing? (mc/update db collection { :language "Clojure" } modified-doc {:multi false :upsert true}))) + (is (= 1 (mc/count db collection))) + (is (= (modified-doc (mc/find-by-id db collection doc-id)))) + (mc/remove db collection))) -(deftest ^{:updating true} upsert-a-document-using-upsert - (let [collection "libraries" - doc-id (monger.util/random-uuid) - date (Date.) - doc {:created-at date :data-store "MongoDB" :language "Clojure" :_id doc-id} - modified-doc {:created-at date :data-store "MongoDB" :language "Erlang" :_id doc-id}] - (mc/remove collection) - (is (not (mr/updated-existing? (mc/upsert collection {:language "Clojure"} doc)))) - (is (= 1 (mc/count collection))) - (is (mr/updated-existing? (mc/upsert collection {:language "Clojure"} modified-doc :multi false))) - (is (= 1 (mc/count collection))) - (is (= (modified-doc (mc/find-by-id collection doc-id)))) - (mc/remove collection))) + (deftest ^{:updating true} upsert-a-document-using-upsert + (let [collection "libraries" + doc-id (mu/random-uuid) + date (Date.) + doc {:created-at date :data-store "MongoDB" :language "Clojure" :_id doc-id} + modified-doc {:created-at date :data-store "MongoDB" :language "Erlang" :_id doc-id}] + (mc/remove db collection) + (is (not (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} doc)))) + (is (= 1 (mc/count db collection))) + (is (mr/updated-existing? (mc/upsert db collection {:language "Clojure"} modified-doc {:multi false}))) + (is (= 1 (mc/count db collection))) + (is (= (modified-doc (mc/find-by-id db collection doc-id)))) + (mc/remove db collection)))) From 60a419953f9343534ef4af5bdc6caf5af6de38b9 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 12:59:08 -0400 Subject: [PATCH 29/48] Remove an unused import --- test/monger/test/updating_test.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/monger/test/updating_test.clj b/test/monger/test/updating_test.clj index b7557a5..e33b5ad 100644 --- a/test/monger/test/updating_test.clj +++ b/test/monger/test/updating_test.clj @@ -1,5 +1,5 @@ (ns monger.test.updating-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject] + (:import [com.mongodb WriteResult WriteConcern DBObject] org.bson.types.ObjectId java.util.Date) (:require [monger.core :as mg] From 565ec43398842bf66117964cfcda08f3a0fb6adf Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 12:59:15 -0400 Subject: [PATCH 30/48] Atomic modifiers tests now pass --- test/monger/test/atomic_modifiers_test.clj | 749 +++++++++++---------- 1 file changed, 392 insertions(+), 357 deletions(-) diff --git a/test/monger/test/atomic_modifiers_test.clj b/test/monger/test/atomic_modifiers_test.clj index 937c1b1..8c156d8 100644 --- a/test/monger/test/atomic_modifiers_test.clj +++ b/test/monger/test/atomic_modifiers_test.clj @@ -1,365 +1,400 @@ (ns monger.test.atomic-modifiers-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject] + (:import [com.mongodb WriteResult WriteConcern DBObject] [org.bson.types ObjectId] - [java.util Date]) - (:require [monger core util] - [monger.collection :as mgcol] + java.util.Date) + (:require [monger.core :as mg] + [monger.collection :as mc] [monger.result :as mgres] - [monger.test.helper :as helper] [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) - -(helper/connect!) - -(use-fixtures :each purge-docs purge-things purge-scores) - - -;; -;; $inc -;; - -(deftest increment-a-single-existing-field-using-$inc-modifier - (let [coll "scores" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :username "l33r0y" :score 100 }) - (mgcol/update coll { :_id oid } { $inc { :score 20 } }) - (is (= 120 (:score (mgcol/find-map-by-id coll oid)))))) - -(deftest set-a-single-non-existing-field-using-$inc-modifier - (let [coll "scores" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :username "l33r0y" }) - (mgcol/update coll { :_id oid } { $inc { :score 30 } }) - (is (= 30 (:score (mgcol/find-map-by-id coll oid)))))) - - -(deftest increment-multiple-existing-fields-using-$inc-modifier - (let [coll "scores" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :username "l33r0y" :score 100 :bonus 0 }) - (mgcol/update coll { :_id oid } {$inc { :score 20 :bonus 10 } }) - (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mgcol/find-map-by-id coll oid))))) - - -(deftest increment-and-set-multiple-existing-fields-using-$inc-modifier - (let [coll "scores" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :username "l33r0y" :score 100 }) - (mgcol/update coll { :_id oid } { $inc { :score 20 :bonus 10 } }) - (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } (mgcol/find-map-by-id coll oid))))) - - - -;; -;; $set -;; - -(deftest update-a-single-existing-field-using-$set-modifier - (let [coll "things" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :weight 10.0 }) - (mgcol/update coll { :_id oid } { $set { :weight 20.5 } }) - (is (= 20.5 (:weight (mgcol/find-map-by-id coll oid [:weight])))))) - -(deftest set-a-single-non-existing-field-using-$set-modifier - (let [coll "things" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :weight 10.0 }) - (mgcol/update coll { :_id oid } { $set { :height 17.2 } }) - (is (= 17.2 (:height (mgcol/find-map-by-id coll oid [:height])))))) - -(deftest update-multiple-existing-fields-using-$set-modifier - (let [coll "things" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :weight 10.0 :height 15.2 }) - (mgcol/update coll { :_id oid } { $set { :weight 20.5 :height 25.6 } }) - (is (= { :_id oid :weight 20.5 :height 25.6 } (mgcol/find-map-by-id coll oid [:weight :height]))))) - - -(deftest update-and-set-multiple-fields-using-$set-modifier - (let [coll "things" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :weight 10.0 }) - (mgcol/update coll { :_id oid } {$set { :weight 20.5 :height 25.6 } }) - (is (= { :_id oid :weight 20.5 :height 25.6 } (mgcol/find-map-by-id coll oid [:weight :height]))))) - - -;; -;; $unset -;; - -(deftest unset-a-single-existing-field-using-$unset-modifier - (let [coll "docs" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :title "Document 1" :published true }) - (mgcol/update coll { :_id oid } { $unset { :published 1 } }) - (is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid))))) - - -(deftest unset-multiple-existing-fields-using-$unset-modifier - (let [coll "docs" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :title "Document 1" :published true :featured true }) - (mgcol/update coll { :_id oid } { $unset { :published 1 :featured true } }) - (is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid))))) - - -(deftest unsetting-an-unexisting-field-using-$unset-modifier-is-not-considered-an-issue - (let [coll "docs" - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :title "Document 1" :published true }) - (is (mgres/ok? (mgcol/update coll { :_id oid } { $unset { :published 1 :featured true } }))) - (is (= { :_id oid :title "Document 1" } (mgcol/find-map-by-id coll oid))))) - -;; -;; $setOnInsert -;; - -(deftest setOnInsert-in-upsert-for-non-existing-document - (let [coll "docs" - now 456 - oid (ObjectId.)] - (mgcol/find-and-modify coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true) - (is (= { :_id oid :lastseen now :firstseen now} (mgcol/find-map-by-id coll oid))))) - -(deftest setOnInsert-in-upsert-for-existing-document - (let [coll "docs" - before 123 - now 456 - oid (ObjectId.)] - (mgcol/insert coll { :_id oid :firstseen before :lastseen before}) - (mgcol/find-and-modify coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} :upsert true) - (is (= { :_id oid :lastseen now :firstseen before} (mgcol/find-map-by-id coll oid))))) - -;; -;; $push -;; - -(deftest initialize-an-array-using-$push-modifier - (let [coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mgcol/insert coll { :_id oid :title title }) - (mgcol/update coll { :_id oid } { $push { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["modifiers"] } (mgcol/find-map-by-id coll oid))))) - -(deftest add-value-to-an-existing-array-using-$push-modifier - (let [coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mgcol/insert coll { :_id oid :title title :tags ["mongodb"] }) - (mgcol/update coll { :_id oid } { $push { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mgcol/find-map-by-id coll oid))))) - - -;; this is a common mistake, I leave it here to demonstrate it. You almost never -;; actually want to do this! What you really want is to use $pushAll instead of $push. MK. -(deftest add-array-value-to-an-existing-array-using-$push-modifier - (let [coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mgcol/insert coll { :_id oid :title title :tags ["mongodb"] }) - (mgcol/update coll { :_id oid } { $push { :tags ["modifiers" "operators"] } }) - (is (= { :_id oid :title title :tags ["mongodb" ["modifiers" "operators"]] } (mgcol/find-map-by-id coll oid))))) - - - -(deftest double-add-value-to-an-existing-array-using-$push-modifier - (let [coll "docs" - oid (ObjectId.) - title "$push modifier appends value to field"] - (mgcol/insert coll { :_id oid :title title :tags ["mongodb"] }) - (mgcol/update coll { :_id oid } { $push { :tags "modifiers" } }) - (mgcol/update coll { :_id oid } { $push { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers" "modifiers"] } (mgcol/find-map-by-id coll oid))))) - -;; -;; $pushAll -;; - -(deftest initialize-an-array-using-$pushAll-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pushAll modifier appends multiple values to field"] - (mgcol/insert coll { :_id oid :title title }) - (mgcol/update coll { :_id oid } { $pushAll { :tags ["mongodb" "docs"] } }) - (is (= { :_id oid :title title :tags ["mongodb" "docs"] } (mgcol/find-map-by-id coll oid))))) - -(deftest add-value-to-an-existing-array-using-$pushAll-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pushAll modifier appends multiple values to field"] - (mgcol/insert coll { :_id oid :title title :tags ["mongodb"] }) - (mgcol/update coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers" "docs"] } (mgcol/find-map-by-id coll oid))))) - - -(deftest double-add-value-to-an-existing-array-using-$pushAll-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pushAll modifier appends multiple values to field"] - (mgcol/insert coll { :_id oid :title title :tags ["mongodb" "docs"] }) - (mgcol/update coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } }) - (is (= { :_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"] } (mgcol/find-map-by-id coll oid))))) - - -;; -;; $addToSet -;; - -(deftest initialize-an-array-using-$addToSet-modifier - (let [coll "docs" - oid (ObjectId.) - title "$addToSet modifier appends value to field unless it is already there"] - (mgcol/insert coll { :_id oid :title title }) - (mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["modifiers"] } (mgcol/find-map-by-id coll oid))))) - -(deftest add-value-to-an-existing-array-using-$addToSet-modifier - (let [coll "docs" - oid (ObjectId.) - title "$addToSet modifier appends value to field unless it is already there"] - (mgcol/insert coll { :_id oid :title title :tags ["mongodb"] }) - (mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mgcol/find-map-by-id coll oid))))) - - -(deftest double-add-value-to-an-existing-array-using-$addToSet-modifier - (let [coll "docs" - oid (ObjectId.) - title "$addToSet modifier appends value to field unless it is already there"] - (mgcol/insert coll { :_id oid :title title :tags ["mongodb"] }) - (mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (mgcol/update coll { :_id oid } { $addToSet { :tags "modifiers" } }) - (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } (mgcol/find-map-by-id coll oid))))) - - -;; -;; $pop -;; - -(deftest pop-last-value-in-the-array-using-$pop-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pop modifier removes last or first value in the array"] - (mgcol/insert coll { :_id oid :title title :tags ["products" "apple" "reviews"] }) - (mgcol/update coll { :_id oid } { $pop { :tags 1 } }) - (is (= { :_id oid :title title :tags ["products" "apple"] } (mgcol/find-map-by-id coll oid))))) - -(deftest unshift-first-value-in-the-array-using-$pop-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pop modifier removes last or first value in the array"] - (mgcol/insert coll { :_id oid :title title :tags ["products" "apple" "reviews"] }) - (mgcol/update coll { :_id oid } { $pop { :tags -1 } }) - (is (= { :_id oid :title title :tags ["apple" "reviews"] } (mgcol/find-map-by-id coll oid))))) - -(deftest pop-last-values-from-multiple-arrays-using-$pop-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pop modifier removes last or first value in the array"] - (mgcol/insert coll { :_id oid :title title :tags ["products" "apple" "reviews"] :categories ["apple" "reviews" "drafts"] }) - (mgcol/update coll { :_id oid } { $pop { :tags 1 :categories 1 } }) - (is (= { :_id oid :title title :tags ["products" "apple"] :categories ["apple" "reviews"] } (mgcol/find-map-by-id coll oid))))) - - -;; -;; $pull -;; - -(deftest remove-all-value-entries-from-array-using-$pull-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pull modifier removes all value entries in the array"] - (mgcol/insert coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) - (mgcol/update coll { :_id oid } { $pull { :measurements 1.2 } }) - (is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.3 1.0] } (mgcol/find-map-by-id coll oid))))) - -(deftest remove-all-value-entries-from-array-using-$pull-modifier-based-on-a-condition - (let [coll "docs" - oid (ObjectId.) - title "$pull modifier removes all value entries in the array"] - (mgcol/insert coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) - (mgcol/update coll { :_id oid } { $pull { :measurements { $gte 1.2 } } }) - (is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.0] } (mgcol/find-map-by-id coll oid))))) -;; -;; $pullAll -;; - -(deftest remove-all-value-entries-from-array-using-$pullAll-modifier - (let [coll "docs" - oid (ObjectId.) - title "$pullAll modifier removes entries of multiple values in the array"] - (mgcol/insert coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) - (mgcol/update coll { :_id oid } { $pullAll { :measurements [1.0 1.1 1.2] } }) - (is (= { :_id oid :title title :measurements [1.3] } (mgcol/find-map-by-id coll oid))))) - - -;; -;; $rename -;; - -(deftest rename-a-single-field-using-$rename-modifier - (let [coll "docs" - oid (ObjectId.) - title "$rename renames fields" - v [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0]] - (mgcol/insert coll { :_id oid :title title :measurements v }) - (mgcol/update coll { :_id oid } { $rename { :measurements "results" } }) - (is (= { :_id oid :title title :results v } (mgcol/find-map-by-id coll oid))))) - - -;; -;; find-and-modify -;; - -(deftest find-and-modify-a-single-document - (let [coll "docs" - oid (ObjectId.) - doc {:_id oid :name "Sophie Bangs" :level 42} - conditions {:name "Sophie Bangs"} - update {$inc {:level 1}}] - (mgcol/insert coll doc) - (let [res (mgcol/find-and-modify coll conditions update :return-new true)] - (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 43}))))) - - -(deftest find-and-modify-remove-a-document - (let [coll "docs" - oid (ObjectId.) - doc {:_id oid :name "Sophie Bangs" :level 42} - conditions {:name "Sophie Bangs"}] - (mgcol/insert coll doc) - (let [res (mgcol/find-and-modify coll conditions {} :remove true)] - (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42})) - (is (empty? (mgcol/find-maps coll conditions)))))) - - -(deftest find-and-modify-upsert-a-document - (testing "case 1" + [monger.operators :refer :all])) + + +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + + (defn purge-collections + [f] + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "scores") + (f) + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "scores")) + + (use-fixtures :each purge-collections) + + ;; + ;; $inc + ;; + + (deftest increment-a-single-existing-field-using-$inc-modifier + (let [coll "scores" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :username "l33r0y" :score 100 }) + (mc/update db coll { :_id oid } { $inc { :score 20 } }) + (is (= 120 (:score (mc/find-map-by-id db coll oid)))))) + + (deftest set-a-single-non-existing-field-using-$inc-modifier + (let [coll "scores" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :username "l33r0y" }) + (mc/update db coll { :_id oid } { $inc { :score 30 } }) + (is (= 30 (:score (mc/find-map-by-id db coll oid)))))) + + + (deftest increment-multiple-existing-fields-using-$inc-modifier + (let [coll "scores" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :username "l33r0y" :score 100 :bonus 0 }) + (mc/update db coll { :_id oid } {$inc { :score 20 :bonus 10 } }) + (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } + (mc/find-map-by-id db coll oid))))) + + + (deftest increment-and-set-multiple-existing-fields-using-$inc-modifier + (let [coll "scores" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :username "l33r0y" :score 100 }) + (mc/update db coll { :_id oid } { $inc { :score 20 :bonus 10 } }) + (is (= { :_id oid :score 120 :bonus 10 :username "l33r0y" } + (mc/find-map-by-id db coll oid))))) + + + + ;; + ;; $set + ;; + + (deftest update-a-single-existing-field-using-$set-modifier + (let [coll "things" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :weight 10.0 }) + (mc/update db coll { :_id oid } { $set { :weight 20.5 } }) + (is (= 20.5 (:weight (mc/find-map-by-id db coll oid [:weight])))))) + + (deftest set-a-single-non-existing-field-using-$set-modifier + (let [coll "things" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :weight 10.0 }) + (mc/update db coll { :_id oid } { $set { :height 17.2 } }) + (is (= 17.2 (:height (mc/find-map-by-id db coll oid [:height])))))) + + (deftest update-multiple-existing-fields-using-$set-modifier + (let [coll "things" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :weight 10.0 :height 15.2 }) + (mc/update db coll { :_id oid } { $set { :weight 20.5 :height 25.6 } }) + (is (= { :_id oid :weight 20.5 :height 25.6 } + (mc/find-map-by-id db coll oid [:weight :height]))))) + + + (deftest update-and-set-multiple-fields-using-$set-modifier + (let [coll "things" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :weight 10.0 }) + (mc/update db coll { :_id oid } {$set { :weight 20.5 :height 25.6 } }) + (is (= { :_id oid :weight 20.5 :height 25.6 } + (mc/find-map-by-id db coll oid [:weight :height]))))) + + + ;; + ;; $unset + ;; + + (deftest unset-a-single-existing-field-using-$unset-modifier (let [coll "docs" - oid (ObjectId.) - doc {:_id oid :name "Sophie Bangs" :level 42}] - (let [res (mgcol/find-and-modify coll doc doc :upsert true)] - (is (empty? res)) - (is (select-keys (mgcol/find-map-by-id coll oid) [:name :level]) (dissoc doc :_id))))) - (testing "case 2" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :title "Document 1" :published true }) + (mc/update db coll { :_id oid } { $unset { :published 1 } }) + (is (= { :_id oid :title "Document 1" } + (mc/find-map-by-id db coll oid))))) + + + (deftest unset-multiple-existing-fields-using-$unset-modifier + (let [coll "docs" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :title "Document 1" :published true :featured true }) + (mc/update db coll { :_id oid } { $unset { :published 1 :featured true } }) + (is (= { :_id oid :title "Document 1" } + (mc/find-map-by-id db coll oid))))) + + + (deftest unsetting-an-unexisting-field-using-$unset-modifier-is-not-considered-an-issue + (let [coll "docs" + oid (ObjectId.)] + (mc/insert db coll { :_id oid :title "Document 1" :published true }) + (is (mgres/ok? (mc/update db coll { :_id oid } { $unset { :published 1 :featured true } }))) + (is (= { :_id oid :title "Document 1" } + (mc/find-map-by-id db coll oid))))) + + ;; + ;; $setOnInsert + ;; + + (deftest setOnInsert-in-upsert-for-non-existing-document + (let [coll "docs" + now 456 + oid (ObjectId.)] + (mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} {:upsert true}) + (is (= { :_id oid :lastseen now :firstseen now} + (mc/find-map-by-id db coll oid))))) + + (deftest setOnInsert-in-upsert-for-existing-document + (let [coll "docs" + before 123 + now 456 + oid (ObjectId.)] + (mc/insert db coll { :_id oid :firstseen before :lastseen before}) + (mc/find-and-modify db coll {:_id oid} {$set {:lastseen now} $setOnInsert {:firstseen now}} {:upsert true}) + (is (= { :_id oid :lastseen now :firstseen before} + (mc/find-map-by-id db coll oid))))) + + ;; + ;; $push + ;; + + (deftest initialize-an-array-using-$push-modifier (let [coll "docs" - query {:name "Sophie Bangs"} - doc (merge query {:level 42})] - (let [res (mgcol/find-and-modify coll query doc :upsert true :return-new true)] - (is (:_id res)) - (is (select-keys (mgcol/find-map-by-id coll (:_id res)) [:name :level]) doc))))) + oid (ObjectId.) + title "$push modifier appends value to field"] + (mc/insert db coll { :_id oid :title title }) + (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) + (is (= { :_id oid :title title :tags ["modifiers"] } + (mc/find-map-by-id db coll oid))))) + + (deftest add-value-to-an-existing-array-using-$push-modifier + (let [coll "docs" + oid (ObjectId.) + title "$push modifier appends value to field"] + (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) + (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) + (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } + (mc/find-map-by-id db coll oid))))) -(deftest find-and-modify-after-sort - (let [coll "docs" - oid (ObjectId.) - oid2 (ObjectId.) - doc {:name "Sophie Bangs"} - doc1 (assoc doc :_id oid :level 42) - doc2 (assoc doc :_id oid2 :level 0)] - (mgcol/insert-batch coll [doc1 doc2]) - (let [res (mgcol/find-and-modify coll doc {$inc {:level 1}} :sort {:level -1})] - (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42}))))) + ;; this is a common mistake, I leave it here to demonstrate it. You almost never + ;; actually want to do this! What you really want is to use $pushAll instead of $push. MK. + (deftest add-array-value-to-an-existing-array-using-$push-modifier + (let [coll "docs" + oid (ObjectId.) + title "$push modifier appends value to field"] + (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) + (mc/update db coll { :_id oid } { $push { :tags ["modifiers" "operators"] } }) + (is (= { :_id oid :title title :tags ["mongodb" ["modifiers" "operators"]] } + (mc/find-map-by-id db coll oid))))) + + + + (deftest double-add-value-to-an-existing-array-using-$push-modifier + (let [coll "docs" + oid (ObjectId.) + title "$push modifier appends value to field"] + (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) + (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) + (mc/update db coll { :_id oid } { $push { :tags "modifiers" } }) + (is (= { :_id oid :title title :tags ["mongodb" "modifiers" "modifiers"] } + (mc/find-map-by-id db coll oid))))) + + ;; + ;; $pushAll + ;; + + (deftest initialize-an-array-using-$pushAll-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pushAll modifier appends multiple values to field"] + (mc/insert db coll { :_id oid :title title }) + (mc/update db coll { :_id oid } { $pushAll { :tags ["mongodb" "docs"] } }) + (is (= { :_id oid :title title :tags ["mongodb" "docs"] } + (mc/find-map-by-id db coll oid))))) + + (deftest add-value-to-an-existing-array-using-$pushAll-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pushAll modifier appends multiple values to field"] + (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) + (mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } }) + (is (= { :_id oid :title title :tags ["mongodb" "modifiers" "docs"] } + (mc/find-map-by-id db coll oid))))) + + + (deftest double-add-value-to-an-existing-array-using-$pushAll-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pushAll modifier appends multiple values to field"] + (mc/insert db coll { :_id oid :title title :tags ["mongodb" "docs"] }) + (mc/update db coll { :_id oid } { $pushAll { :tags ["modifiers" "docs"] } }) + (is (= { :_id oid :title title :tags ["mongodb" "docs" "modifiers" "docs"] } + (mc/find-map-by-id db coll oid))))) + + + ;; + ;; $addToSet + ;; + + (deftest initialize-an-array-using-$addToSet-modifier + (let [coll "docs" + oid (ObjectId.) + title "$addToSet modifier appends value to field unless it is already there"] + (mc/insert db coll { :_id oid :title title }) + (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) + (is (= { :_id oid :title title :tags ["modifiers"] } + (mc/find-map-by-id db coll oid))))) + + (deftest add-value-to-an-existing-array-using-$addToSet-modifier + (let [coll "docs" + oid (ObjectId.) + title "$addToSet modifier appends value to field unless it is already there"] + (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) + (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) + (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } + (mc/find-map-by-id db coll oid))))) + + + (deftest double-add-value-to-an-existing-array-using-$addToSet-modifier + (let [coll "docs" + oid (ObjectId.) + title "$addToSet modifier appends value to field unless it is already there"] + (mc/insert db coll { :_id oid :title title :tags ["mongodb"] }) + (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) + (mc/update db coll { :_id oid } { $addToSet { :tags "modifiers" } }) + (is (= { :_id oid :title title :tags ["mongodb" "modifiers"] } + (mc/find-map-by-id db coll oid))))) + + + ;; + ;; $pop + ;; + + (deftest pop-last-value-in-the-array-using-$pop-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pop modifier removes last or first value in the array"] + (mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] }) + (mc/update db coll { :_id oid } { $pop { :tags 1 } }) + (is (= { :_id oid :title title :tags ["products" "apple"] } + (mc/find-map-by-id db coll oid))))) + + (deftest unshift-first-value-in-the-array-using-$pop-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pop modifier removes last or first value in the array"] + (mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] }) + (mc/update db coll { :_id oid } { $pop { :tags -1 } }) + (is (= { :_id oid :title title :tags ["apple" "reviews"] } + (mc/find-map-by-id db coll oid))))) + + (deftest pop-last-values-from-multiple-arrays-using-$pop-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pop modifier removes last or first value in the array"] + (mc/insert db coll { :_id oid :title title :tags ["products" "apple" "reviews"] :categories ["apple" "reviews" "drafts"] }) + (mc/update db coll { :_id oid } { $pop { :tags 1 :categories 1 } }) + (is (= { :_id oid :title title :tags ["products" "apple"] :categories ["apple" "reviews"] } + (mc/find-map-by-id db coll oid))))) + + + ;; + ;; $pull + ;; + + (deftest remove-all-value-entries-from-array-using-$pull-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pull modifier removes all value entries in the array"] + (mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) + (mc/update db coll { :_id oid } { $pull { :measurements 1.2 } }) + (is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.3 1.0] } + (mc/find-map-by-id db coll oid))))) + + (deftest remove-all-value-entries-from-array-using-$pull-modifier-based-on-a-condition + (let [coll "docs" + oid (ObjectId.) + title "$pull modifier removes all value entries in the array"] + (mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) + (mc/update db coll { :_id oid } { $pull { :measurements { $gte 1.2 } } }) + (is (= { :_id oid :title title :measurements [1.0 1.1 1.1 1.0] } + (mc/find-map-by-id db coll oid))))) + ;; + ;; $pullAll + ;; + + (deftest remove-all-value-entries-from-array-using-$pullAll-modifier + (let [coll "docs" + oid (ObjectId.) + title "$pullAll modifier removes entries of multiple values in the array"] + (mc/insert db coll { :_id oid :title title :measurements [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0] }) + (mc/update db coll { :_id oid } { $pullAll { :measurements [1.0 1.1 1.2] } }) + (is (= { :_id oid :title title :measurements [1.3] } + (mc/find-map-by-id db coll oid))))) + + + ;; + ;; $rename + ;; + + (deftest rename-a-single-field-using-$rename-modifier + (let [coll "docs" + oid (ObjectId.) + title "$rename renames fields" + v [1.0 1.2 1.2 1.2 1.1 1.1 1.2 1.3 1.0]] + (mc/insert db coll { :_id oid :title title :measurements v }) + (mc/update db coll { :_id oid } { $rename { :measurements "results" } }) + (is (= { :_id oid :title title :results v } + (mc/find-map-by-id db coll oid))))) + + + ;; + ;; find-and-modify + ;; + + (deftest find-and-modify-a-single-document + (let [coll "docs" + oid (ObjectId.) + doc {:_id oid :name "Sophie Bangs" :level 42} + conditions {:name "Sophie Bangs"} + update {$inc {:level 1}}] + (mc/insert db coll doc) + (let [res (mc/find-and-modify db coll conditions update {:return-new true})] + (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 43}))))) + + + (deftest find-and-modify-remove-a-document + (let [coll "docs" + oid (ObjectId.) + doc {:_id oid :name "Sophie Bangs" :level 42} + conditions {:name "Sophie Bangs"}] + (mc/insert db coll doc) + (let [res (mc/find-and-modify db coll conditions {} {:remove true})] + (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42})) + (is (empty? (mc/find-maps db coll conditions)))))) + + + (deftest find-and-modify-upsert-a-document + (testing "case 1" + (let [coll "docs" + oid (ObjectId.) + doc {:_id oid :name "Sophie Bangs" :level 42}] + (let [res (mc/find-and-modify db coll doc doc {:upsert true})] + (is (empty? res)) + (is (select-keys (mc/find-map-by-id db coll oid) [:name :level]) (dissoc doc :_id))))) + (testing "case 2" + (let [coll "docs" + query {:name "Sophie Bangs"} + doc (merge query {:level 42})] + (let [res (mc/find-and-modify db coll query doc {:upsert true :return-new true})] + (is (:_id res)) + (is (select-keys (mc/find-map-by-id db coll (:_id res)) [:name :level]) doc))))) + + + (deftest find-and-modify-after-sort + (let [coll "docs" + oid (ObjectId.) + oid2 (ObjectId.) + doc {:name "Sophie Bangs"} + doc1 (assoc doc :_id oid :level 42) + doc2 (assoc doc :_id oid2 :level 0)] + (mc/insert-batch db coll [doc1 doc2]) + (let [res (mc/find-and-modify db coll doc {$inc {:level 1}} {:sort {:level -1}})] + (is (= (select-keys res [:name :level]) {:name "Sophie Bangs" :level 42})))))) From d7902c961895fa2064ec705134cfa910799ac09e Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:10:56 -0400 Subject: [PATCH 31/48] Query DSL tests now pass --- src/clojure/monger/query.clj | 16 +- test/monger/test/querying_test.clj | 560 +++++++++++++++-------------- 2 files changed, 299 insertions(+), 277 deletions(-) diff --git a/src/clojure/monger/query.clj b/src/clojure/monger/query.clj index aa49fb4..3132d89 100644 --- a/src/clojure/monger/query.clj +++ b/src/clojure/monger/query.clj @@ -63,7 +63,19 @@ (merge (empty-query) { :collection coll }))) (defn exec - [{ :keys [^DBCollection collection query fields skip limit sort batch-size hint snapshot read-preference keywordize-fields options] :or { limit 0 batch-size 256 skip 0 } }] + [{:keys [^DBCollection collection + query + fields + skip + limit + sort + batch-size + hint + snapshot + read-preference + keywordize-fields + options] + :or { limit 0 batch-size 256 skip 0 } }] (with-open [cursor (doto (.find collection (to-db-object query) (as-field-selector fields)) (.limit limit) (.skip skip) @@ -135,7 +147,7 @@ [^DB db ^String coll & body] `(let [coll# ~coll db-coll# (if (string? coll#) - (.getCollection db ^String coll#) + (.getCollection ~db ^String coll#) coll#) query# (-> (empty-query db-coll#) ~@body)] (exec query#))) diff --git a/test/monger/test/querying_test.clj b/test/monger/test/querying_test.clj index 8437ab0..b395efb 100644 --- a/test/monger/test/querying_test.clj +++ b/test/monger/test/querying_test.clj @@ -1,315 +1,325 @@ (ns monger.test.querying-test (:refer-clojure :exclude [select find sort]) - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject ReadPreference] + (:import [com.mongodb WriteResult WriteConcern DBObject ReadPreference] org.bson.types.ObjectId java.util.Date) - (:require [monger core util] - [monger.collection :as mgcol] + (:require [monger.core :as mg] + [monger.collection :as mc] + monger.joda-time [monger.result :as mgres] - [monger.test.helper :as helper] [clojure.test :refer :all] - [monger.test.fixtures :refer :all] - [monger.conversion :refer :all] - [monger.query :refer :all] - [monger.operators :refer :all] - [clj-time.core :refer [date-time]])) + [monger.conversion :refer :all] + [monger.query :refer :all] + [monger.operators :refer :all] + [clj-time.core :refer [date-time]])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] -(use-fixtures :each purge-docs purge-things purge-locations - purge-querying-docs) + (defn purge-collections + [f] + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "locations") + (mc/remove db "querying_docs") + (f) + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "locations") + (mc/remove db "querying_docs")) + + (use-fixtures :each purge-collections) + + ;; + ;; monger.collection/* finders ("low-level API") + ;; + + ;; by ObjectId + + (deftest query-full-document-by-object-id + (let [coll "querying_docs" + oid (ObjectId.) + doc { :_id oid :title "Introducing Monger" }] + (mc/insert db coll doc) + (is (= doc (mc/find-map-by-id db coll oid))) + (is (= doc (mc/find-one-as-map db coll { :_id oid }))))) -;; -;; monger.collection/* finders ("low-level API") -;; + ;; exact match over string field -;; by ObjectId - -(deftest query-full-document-by-object-id - (let [coll "querying_docs" - oid (ObjectId.) - doc { :_id oid :title "Introducing Monger" }] - (mgcol/insert coll doc) - (is (= doc (mgcol/find-map-by-id coll oid))) - (is (= doc (mgcol/find-one-as-map coll { :_id oid }))))) + (deftest query-full-document-using-exact-matching-over-string-field + (let [coll "querying_docs" + doc { :title "monger" :language "Clojure" :_id (ObjectId.) }] + (mc/insert db coll doc) + (is (= [doc] (mc/find-maps db coll { :title "monger" }))) + (is (= doc (from-db-object (first (mc/find db coll { :title "monger" })) true))))) -;; exact match over string field + ;; exact match over string field with limit -(deftest query-full-document-using-exact-matching-over-string-field - (let [coll "querying_docs" - doc { :title "monger" :language "Clojure" :_id (ObjectId.) }] - (mgcol/insert coll doc) - (is (= [doc] (mgcol/find-maps coll { :title "monger" }))) - (is (= doc (from-db-object (first (mgcol/find coll { :title "monger" })) true))))) + (deftest query-full-document-using-exact-matching-over-string-with-field-with-limit + (let [coll "querying_docs" + doc1 { :title "monger" :language "Clojure" :_id (ObjectId.) } + doc2 { :title "langohr" :language "Clojure" :_id (ObjectId.) } + doc3 { :title "netty" :language "Java" :_id (ObjectId.) } + _ (mc/insert-batch db coll [doc1 doc2 doc3]) + result (with-collection db coll + (find { :title "monger" }) + (fields [:title, :language, :_id]) + (skip 0) + (limit 1))] + (is (= 1 (count result))) + (is (= [doc1] result)))) -;; exact match over string field with limit + (deftest query-full-document-using-exact-matching-over-string-field-with-limit-and-offset + (let [coll "querying_docs" + doc1 { :title "lucene" :language "Java" :_id (ObjectId.) } + doc2 { :title "joda-time" :language "Java" :_id (ObjectId.) } + doc3 { :title "netty" :language "Java" :_id (ObjectId.) } + _ (mc/insert-batch db coll [doc1 doc2 doc3]) + result (with-collection db coll + (find { :language "Java" }) + (skip 1) + (limit 2) + (sort { :title 1 }))] + (is (= 2 (count result))) + (is (= [doc1 doc3] result)))) -(deftest query-full-document-using-exact-matching-over-string-with-field-with-limit - (let [coll "querying_docs" - doc1 { :title "monger" :language "Clojure" :_id (ObjectId.) } - doc2 { :title "langohr" :language "Clojure" :_id (ObjectId.) } - doc3 { :title "netty" :language "Java" :_id (ObjectId.) } - _ (mgcol/insert-batch coll [doc1 doc2 doc3]) - result (with-collection coll - (find { :title "monger" }) - (fields [:title, :language, :_id]) - (skip 0) - (limit 1))] - (is (= 1 (count result))) - (is (= [doc1] result)))) + (deftest query-with-sorting-on-multiple-fields + (let [coll "querying_docs" + doc1 { :a 1 :b 2 :c 3 :text "Whatever" :_id (ObjectId.) } + doc2 { :a 1 :b 1 :c 4 :text "Blah " :_id (ObjectId.) } + doc3 { :a 10 :b 3 :c 1 :text "Abc" :_id (ObjectId.) } + doc4 { :a 10 :b 3 :c 3 :text "Abc" :_id (ObjectId.) } + _ (mc/insert-batch db coll [doc1 doc2 doc3 doc4]) + result1 (with-collection db coll + (find {}) + (limit 2) + (fields [:a :b :c :text]) + (sort (sorted-map :a 1 :b 1 :text -1))) + result2 (with-collection db coll + (find {}) + (limit 2) + (fields [:a :b :c :text]) + (sort (array-map :c 1 :text -1))) + result3 (with-collection db coll + (find {}) + (limit 2) + (fields [:a :b :c :text]) + (sort (array-map :c -1 :text 1)))] + (is (= [doc2 doc1] result1)) + (is (= [doc3 doc1] result2)) + (is (= [doc2 doc4] result3)))) -(deftest query-full-document-using-exact-matching-over-string-field-with-limit-and-offset - (let [coll "querying_docs" - doc1 { :title "lucene" :language "Java" :_id (ObjectId.) } - doc2 { :title "joda-time" :language "Java" :_id (ObjectId.) } - doc3 { :title "netty" :language "Java" :_id (ObjectId.) } - _ (mgcol/insert-batch coll [doc1 doc2 doc3]) - result (with-collection coll - (find { :language "Java" }) - (skip 1) - (limit 2) - (sort { :title 1 }))] - (is (= 2 (count result))) - (is (= [doc1 doc3] result)))) + ;; < ($lt), <= ($lte), > ($gt), >= ($gte) -(deftest query-with-sorting-on-multiple-fields - (let [coll "querying_docs" - doc1 { :a 1 :b 2 :c 3 :text "Whatever" :_id (ObjectId.) } - doc2 { :a 1 :b 1 :c 4 :text "Blah " :_id (ObjectId.) } - doc3 { :a 10 :b 3 :c 1 :text "Abc" :_id (ObjectId.) } - doc4 { :a 10 :b 3 :c 3 :text "Abc" :_id (ObjectId.) } - _ (mgcol/insert-batch coll [doc1 doc2 doc3 doc4]) - result1 (with-collection coll - (find {}) - (limit 2) - (fields [:a :b :c :text]) - (sort (sorted-map :a 1 :b 1 :text -1))) - result2 (with-collection coll - (find {}) - (limit 2) - (fields [:a :b :c :text]) - (sort (array-map :c 1 :text -1))) - result3 (with-collection coll - (find {}) - (limit 2) - (fields [:a :b :c :text]) - (sort (array-map :c -1 :text 1)))] - (is (= [doc2 doc1] result1)) - (is (= [doc3 doc1] result2)) - (is (= [doc2 doc4] result3)))) + (deftest query-using-dsl-and-$lt-operator-with-integers + (let [coll "querying_docs" + doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 } + doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 } + doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 } + _ (mc/insert-batch db coll [doc1 doc2]) + lt-result (with-collection db coll + (find { :inception_year { $lt 2000 } }) + (limit 2))] + (is (= [doc2] (vec lt-result))))) -;; < ($lt), <= ($lte), > ($gt), >= ($gte) + (deftest query-using-dsl-and-$lt-operator-with-dates + (let [coll "querying_docs" + ;; these rely on monger.joda-time being loaded. MK. + doc1 { :language "Clojure" :_id (ObjectId.) :inception_year (date-time 2006 1 1) } + doc2 { :language "Java" :_id (ObjectId.) :inception_year (date-time 1992 1 2) } + doc3 { :language "Scala" :_id (ObjectId.) :inception_year (date-time 2003 3 3) } + _ (mc/insert-batch db coll [doc1 doc2]) + lt-result (with-collection db coll + (find { :inception_year { $lt (date-time 2000 1 2) } }) + (limit 2))] + (is (= (map :_id [doc2]) + (map :_id (vec lt-result)))))) -(deftest query-using-dsl-and-$lt-operator-with-integers - (let [coll "querying_docs" - doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 } - doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 } - doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 } - _ (mgcol/insert-batch coll [doc1 doc2]) - lt-result (with-collection "querying_docs" - (find { :inception_year { $lt 2000 } }) - (limit 2))] - (is (= [doc2] (vec lt-result))))) + (deftest query-using-both-$lte-and-$gte-operators-with-dates + (let [coll "querying_docs" + ;; these rely on monger.joda-time being loaded. MK. + doc1 { :language "Clojure" :_id (ObjectId.) :inception_year (date-time 2006 1 1) } + doc2 { :language "Java" :_id (ObjectId.) :inception_year (date-time 1992 1 2) } + doc3 { :language "Scala" :_id (ObjectId.) :inception_year (date-time 2003 3 3) } + _ (mc/insert-batch db coll [doc1 doc2 doc3]) + lt-result (with-collection db coll + (find { :inception_year { $gt (date-time 2000 1 2) $lte (date-time 2007 2 2) } }) + (sort { :inception_year 1 }))] + (is (= (map :_id [doc3 doc1]) + (map :_id (vec lt-result)))))) -(deftest query-using-dsl-and-$lt-operator-with-dates - (let [coll "querying_docs" - ;; these rely on monger.joda-time being loaded. MK. - doc1 { :language "Clojure" :_id (ObjectId.) :inception_year (date-time 2006 1 1) } - doc2 { :language "Java" :_id (ObjectId.) :inception_year (date-time 1992 1 2) } - doc3 { :language "Scala" :_id (ObjectId.) :inception_year (date-time 2003 3 3) } - _ (mgcol/insert-batch coll [doc1 doc2]) - lt-result (with-collection "querying_docs" - (find { :inception_year { $lt (date-time 2000 1 2) } }) - (limit 2))] - (is (= (map :_id [doc2]) - (map :_id (vec lt-result)))))) - -(deftest query-using-both-$lte-and-$gte-operators-with-dates - (let [coll "querying_docs" - ;; these rely on monger.joda-time being loaded. MK. - doc1 { :language "Clojure" :_id (ObjectId.) :inception_year (date-time 2006 1 1) } - doc2 { :language "Java" :_id (ObjectId.) :inception_year (date-time 1992 1 2) } - doc3 { :language "Scala" :_id (ObjectId.) :inception_year (date-time 2003 3 3) } - _ (mgcol/insert-batch coll [doc1 doc2 doc3]) - lt-result (with-collection "querying_docs" - (find { :inception_year { $gt (date-time 2000 1 2) $lte (date-time 2007 2 2) } }) - (sort { :inception_year 1 }))] - (is (= (map :_id [doc3 doc1]) - (map :_id (vec lt-result)))))) + (deftest query-using-$gt-$lt-$gte-$lte-operators-as-strings + (let [coll "querying_docs" + doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 } + doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 } + doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 } + _ (mc/insert-batch db coll [doc1 doc2 doc3])] + (are [doc, result] + (= doc, result) + (doc2 (with-collection db coll + (find { :inception_year { "$lt" 2000 } }))) + (doc2 (with-collection db coll + (find { :inception_year { "$lte" 1992 } }))) + (doc1 (with-collection db coll + (find { :inception_year { "$gt" 2002 } }) + (limit 1) + (sort { :inception_year -1 }))) + (doc1 (with-collection db coll + (find { :inception_year { "$gte" 2006 } })))))) -(deftest query-using-$gt-$lt-$gte-$lte-operators-as-strings - (let [coll "querying_docs" - doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 } - doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 } - doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 } - _ (mgcol/insert-batch coll [doc1 doc2 doc3])] - (are [doc, result] - (= doc, result) - (doc2 (with-collection coll - (find { :inception_year { "$lt" 2000 } }))) - (doc2 (with-collection coll - (find { :inception_year { "$lte" 1992 } }))) - (doc1 (with-collection coll - (find { :inception_year { "$gt" 2002 } }) - (limit 1) - (sort { :inception_year -1 }))) - (doc1 (with-collection coll - (find { :inception_year { "$gte" 2006 } })))))) + (deftest query-using-$gt-$lt-$gte-$lte-operators-using-dsl-composition + (let [coll "querying_docs" + doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 } + doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 } + doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 } + srt (-> {} + (limit 1) + (sort { :inception_year -1 })) + _ (mc/insert-batch db coll [doc1 doc2 doc3])] + (is (= [doc1] (with-collection db coll + (find { :inception_year { "$gt" 2002 } }) + (merge srt)))))) -(deftest query-using-$gt-$lt-$gte-$lte-operators-using-dsl-composition - (let [coll "querying_docs" - doc1 { :language "Clojure" :_id (ObjectId.) :inception_year 2006 } - doc2 { :language "Java" :_id (ObjectId.) :inception_year 1992 } - doc3 { :language "Scala" :_id (ObjectId.) :inception_year 2003 } - srt (-> {} - (limit 1) - (sort { :inception_year -1 })) - _ (mgcol/insert-batch coll [doc1 doc2 doc3])] - (is (= [doc1] (with-collection coll - (find { :inception_year { "$gt" 2002 } }) - (merge srt)))))) + ;; $all + + (deftest query-with-using-$all + (let [coll "querying_docs" + doc1 { :_id (ObjectId.) :title "Clojure" :tags ["functional" "homoiconic" "syntax-oriented" "dsls" "concurrency features" "jvm"] } + doc2 { :_id (ObjectId.) :title "Java" :tags ["object-oriented" "jvm"] } + doc3 { :_id (ObjectId.) :title "Scala" :tags ["functional" "object-oriented" "dsls" "concurrency features" "jvm"] } + - (mc/insert-batch db coll [doc1 doc2 doc3]) + result1 (with-collection db coll + (find { :tags { "$all" ["functional" "jvm" "homoiconic"] } })) + result2 (with-collection db coll + (find { :tags { "$all" ["functional" "native" "homoiconic"] } })) + result3 (with-collection db coll + (find { :tags { "$all" ["functional" "jvm" "dsls"] } }) + (sort { :title 1 }))] + (is (= [doc1] result1)) + (is (empty? result2)) + (is (= 2 (count result3))) + (is (= doc1 (first result3))))) -;; $all + ;; $exists -(deftest query-with-using-$all - (let [coll "querying_docs" - doc1 { :_id (ObjectId.) :title "Clojure" :tags ["functional" "homoiconic" "syntax-oriented" "dsls" "concurrency features" "jvm"] } - doc2 { :_id (ObjectId.) :title "Java" :tags ["object-oriented" "jvm"] } - doc3 { :_id (ObjectId.) :title "Scala" :tags ["functional" "object-oriented" "dsls" "concurrency features" "jvm"] } - - (mgcol/insert-batch coll [doc1 doc2 doc3]) - result1 (with-collection coll - (find { :tags { "$all" ["functional" "jvm" "homoiconic"] } })) - result2 (with-collection coll - (find { :tags { "$all" ["functional" "native" "homoiconic"] } })) - result3 (with-collection coll - (find { :tags { "$all" ["functional" "jvm" "dsls"] } }) - (sort { :title 1 }))] - (is (= [doc1] result1)) - (is (empty? result2)) - (is (= 2 (count result3))) - (is (= doc1 (first result3))))) + (deftest query-with-find-one-as-map-using-$exists + (let [coll "querying_docs" + doc1 { :_id (ObjectId.) :published-by "Jill The Blogger" :draft false :title "X announces another Y" } + doc2 { :_id (ObjectId.) :draft true :title "Z announces a Y competitor" } + _ (mc/insert-batch db coll [doc1 doc2]) + result1 (mc/find-one-as-map db coll { :published-by { "$exists" true } }) + result2 (mc/find-one-as-map db coll { :published-by { "$exists" false } })] + (is (= doc1 result1)) + (is (= doc2 result2)))) + + ;; $mod + + (deftest query-with-find-one-as-map-using-$mod + (let [coll "querying_docs" + doc1 { :_id (ObjectId.) :counter 25 } + doc2 { :_id (ObjectId.) :counter 32 } + doc3 { :_id (ObjectId.) :counter 63 } + _ (mc/insert-batch db coll [doc1 doc2 doc3]) + result1 (mc/find-one-as-map db coll { :counter { "$mod" [10, 5] } }) + result2 (mc/find-one-as-map db coll { :counter { "$mod" [10, 2] } }) + result3 (mc/find-one-as-map db coll { :counter { "$mod" [11, 1] } })] + (is (= doc1 result1)) + (is (= doc2 result2)) + (is (empty? result3)))) -;; $exists + ;; $ne -(deftest query-with-find-one-as-map-using-$exists - (let [coll "querying_docs" - doc1 { :_id (ObjectId.) :published-by "Jill The Blogger" :draft false :title "X announces another Y" } - doc2 { :_id (ObjectId.) :draft true :title "Z announces a Y competitor" } - _ (mgcol/insert-batch coll [doc1 doc2]) - result1 (mgcol/find-one-as-map coll { :published-by { "$exists" true } }) - result2 (mgcol/find-one-as-map coll { :published-by { "$exists" false } })] - (is (= doc1 result1)) - (is (= doc2 result2)))) + (deftest query-with-find-one-as-map-using-$ne + (let [coll "querying_docs" + doc1 { :_id (ObjectId.) :counter 25 } + doc2 { :_id (ObjectId.) :counter 32 } + _ (mc/insert-batch db coll [doc1 doc2]) + result1 (mc/find-one-as-map db coll { :counter { "$ne" 25 } }) + result2 (mc/find-one-as-map db coll { :counter { "$ne" 32 } })] + (is (= doc2 result1)) + (is (= doc1 result2)))) -;; $mod + ;; + ;; monger.query DSL features + ;; -(deftest query-with-find-one-as-map-using-$mod - (let [coll "querying_docs" - doc1 { :_id (ObjectId.) :counter 25 } - doc2 { :_id (ObjectId.) :counter 32 } - doc3 { :_id (ObjectId.) :counter 63 } - _ (mgcol/insert-batch coll [doc1 doc2 doc3]) - result1 (mgcol/find-one-as-map coll { :counter { "$mod" [10, 5] } }) - result2 (mgcol/find-one-as-map coll { :counter { "$mod" [10, 2] } }) - result3 (mgcol/find-one-as-map coll { :counter { "$mod" [11, 1] } })] - (is (= doc1 result1)) - (is (= doc2 result2)) - (is (empty? result3)))) + ;; pagination + (deftest query-using-pagination-dsl + (let [coll "querying_docs" + doc1 { :_id (ObjectId.) :title "Clojure" :tags ["functional" "homoiconic" "syntax-oriented" "dsls" "concurrency features" "jvm"] } + doc2 { :_id (ObjectId.) :title "Java" :tags ["object-oriented" "jvm"] } + doc3 { :_id (ObjectId.) :title "Scala" :tags ["functional" "object-oriented" "dsls" "concurrency features" "jvm"] } + doc4 { :_id (ObjectId.) :title "Ruby" :tags ["dynamic" "object-oriented" "dsls" "jvm"] } + doc5 { :_id (ObjectId.) :title "Groovy" :tags ["dynamic" "object-oriented" "dsls" "jvm"] } + doc6 { :_id (ObjectId.) :title "OCaml" :tags ["functional" "static" "dsls"] } + doc7 { :_id (ObjectId.) :title "Haskell" :tags ["functional" "static" "dsls" "concurrency features"] } + - (mc/insert-batch db coll [doc1 doc2 doc3 doc4 doc5 doc6 doc7]) + result1 (with-collection db coll + (find {}) + (paginate :page 1 :per-page 3) + (sort { :title 1 }) + (read-preference (ReadPreference/primary)) + (options com.mongodb.Bytes/QUERYOPTION_NOTIMEOUT)) + result2 (with-collection db coll + (find {}) + (paginate :page 2 :per-page 3) + (sort { :title 1 })) + result3 (with-collection db coll + (find {}) + (paginate :page 3 :per-page 3) + (sort { :title 1 })) + result4 (with-collection db coll + (find {}) + (paginate :page 10 :per-page 3) + (sort { :title 1 }))] + (is (= [doc1 doc5 doc7] result1)) + (is (= [doc2 doc6 doc4] result2)) + (is (= [doc3] result3)) + (is (empty? result4)))) -;; $ne + (deftest combined-querying-dsl-example1 + (let [coll "querying_docs" + ma-doc { :_id (ObjectId.) :name "Massachusetts" :iso "MA" :population 6547629 :joined_in 1788 :capital "Boston" } + de-doc { :_id (ObjectId.) :name "Delaware" :iso "DE" :population 897934 :joined_in 1787 :capital "Dover" } + ny-doc { :_id (ObjectId.) :name "New York" :iso "NY" :population 19378102 :joined_in 1788 :capital "Albany" } + ca-doc { :_id (ObjectId.) :name "California" :iso "CA" :population 37253956 :joined_in 1850 :capital "Sacramento" } + tx-doc { :_id (ObjectId.) :name "Texas" :iso "TX" :population 25145561 :joined_in 1845 :capital "Austin" } + top3 (partial-query (limit 3)) + by-population-desc (partial-query (sort { :population -1 })) + _ (mc/insert-batch db coll [ma-doc de-doc ny-doc ca-doc tx-doc]) + result (with-collection db coll + (find {}) + (merge top3) + (merge by-population-desc))] + (is (= result [ca-doc tx-doc ny-doc])))) -(deftest query-with-find-one-as-map-using-$ne - (let [coll "querying_docs" - doc1 { :_id (ObjectId.) :counter 25 } - doc2 { :_id (ObjectId.) :counter 32 } - _ (mgcol/insert-batch coll [doc1 doc2]) - result1 (mgcol/find-one-as-map coll { :counter { "$ne" 25 } }) - result2 (mgcol/find-one-as-map coll { :counter { "$ne" 32 } })] - (is (= doc2 result1)) - (is (= doc1 result2)))) - -;; -;; monger.query DSL features -;; - -;; pagination -(deftest query-using-pagination-dsl - (let [coll "querying_docs" - doc1 { :_id (ObjectId.) :title "Clojure" :tags ["functional" "homoiconic" "syntax-oriented" "dsls" "concurrency features" "jvm"] } - doc2 { :_id (ObjectId.) :title "Java" :tags ["object-oriented" "jvm"] } - doc3 { :_id (ObjectId.) :title "Scala" :tags ["functional" "object-oriented" "dsls" "concurrency features" "jvm"] } - doc4 { :_id (ObjectId.) :title "Ruby" :tags ["dynamic" "object-oriented" "dsls" "jvm"] } - doc5 { :_id (ObjectId.) :title "Groovy" :tags ["dynamic" "object-oriented" "dsls" "jvm"] } - doc6 { :_id (ObjectId.) :title "OCaml" :tags ["functional" "static" "dsls"] } - doc7 { :_id (ObjectId.) :title "Haskell" :tags ["functional" "static" "dsls" "concurrency features"] } - - (mgcol/insert-batch coll [doc1 doc2 doc3 doc4 doc5 doc6 doc7]) - result1 (with-collection coll - (find {}) - (paginate :page 1 :per-page 3) - (sort { :title 1 }) - (read-preference (ReadPreference/primary)) - (options com.mongodb.Bytes/QUERYOPTION_NOTIMEOUT)) - result2 (with-collection coll - (find {}) - (paginate :page 2 :per-page 3) - (sort { :title 1 })) - result3 (with-collection coll - (find {}) - (paginate :page 3 :per-page 3) - (sort { :title 1 })) - result4 (with-collection coll - (find {}) - (paginate :page 10 :per-page 3) - (sort { :title 1 }))] - (is (= [doc1 doc5 doc7] result1)) - (is (= [doc2 doc6 doc4] result2)) - (is (= [doc3] result3)) - (is (empty? result4)))) - - -(deftest combined-querying-dsl-example1 - (let [coll "querying_docs" - ma-doc { :_id (ObjectId.) :name "Massachusetts" :iso "MA" :population 6547629 :joined_in 1788 :capital "Boston" } - de-doc { :_id (ObjectId.) :name "Delaware" :iso "DE" :population 897934 :joined_in 1787 :capital "Dover" } - ny-doc { :_id (ObjectId.) :name "New York" :iso "NY" :population 19378102 :joined_in 1788 :capital "Albany" } - ca-doc { :_id (ObjectId.) :name "California" :iso "CA" :population 37253956 :joined_in 1850 :capital "Sacramento" } - tx-doc { :_id (ObjectId.) :name "Texas" :iso "TX" :population 25145561 :joined_in 1845 :capital "Austin" } - top3 (partial-query (limit 3)) - by-population-desc (partial-query (sort { :population -1 })) - _ (mgcol/insert-batch coll [ma-doc de-doc ny-doc ca-doc tx-doc]) - result (with-collection coll - (find {}) - (merge top3) - (merge by-population-desc))] - (is (= result [ca-doc tx-doc ny-doc])))) - -(deftest combined-querying-dsl-example2 - (let [coll "querying_docs" - ma-doc { :_id (ObjectId.) :name "Massachusetts" :iso "MA" :population 6547629 :joined_in 1788 :capital "Boston" } - de-doc { :_id (ObjectId.) :name "Delaware" :iso "DE" :population 897934 :joined_in 1787 :capital "Dover" } - ny-doc { :_id (ObjectId.) :name "New York" :iso "NY" :population 19378102 :joined_in 1788 :capital "Albany" } - ca-doc { :_id (ObjectId.) :name "California" :iso "CA" :population 37253956 :joined_in 1850 :capital "Sacramento" } - tx-doc { :_id (ObjectId.) :name "Texas" :iso "TX" :population 25145561 :joined_in 1845 :capital "Austin" } - top3 (partial-query (limit 3)) - by-population-desc (partial-query (sort { :population -1 })) - _ (mgcol/insert-batch coll [ma-doc de-doc ny-doc ca-doc tx-doc]) - result (with-collection coll - (find {}) - (merge top3) - (merge by-population-desc) - (keywordize-fields false))] - ;; documents have fields as strings, - ;; not keywords - (is (= (map #(% "name") result) - (map #(% :name) [ca-doc tx-doc ny-doc]))))) + (deftest combined-querying-dsl-example2 + (let [coll "querying_docs" + ma-doc { :_id (ObjectId.) :name "Massachusetts" :iso "MA" :population 6547629 :joined_in 1788 :capital "Boston" } + de-doc { :_id (ObjectId.) :name "Delaware" :iso "DE" :population 897934 :joined_in 1787 :capital "Dover" } + ny-doc { :_id (ObjectId.) :name "New York" :iso "NY" :population 19378102 :joined_in 1788 :capital "Albany" } + ca-doc { :_id (ObjectId.) :name "California" :iso "CA" :population 37253956 :joined_in 1850 :capital "Sacramento" } + tx-doc { :_id (ObjectId.) :name "Texas" :iso "TX" :population 25145561 :joined_in 1845 :capital "Austin" } + top3 (partial-query (limit 3)) + by-population-desc (partial-query (sort { :population -1 })) + _ (mc/insert-batch db coll [ma-doc de-doc ny-doc ca-doc tx-doc]) + result (with-collection db coll + (find {}) + (merge top3) + (merge by-population-desc) + (keywordize-fields false))] + ;; documents have fields as strings, + ;; not keywords + (is (= (map #(% "name") result) + (map #(% :name) [ca-doc tx-doc ny-doc])))))) From f02a2b0afc2610bc5b41ea890c46da0061184d55 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:12:30 -0400 Subject: [PATCH 32/48] Capped collection tests now pass --- test/monger/test/capped_collections_test.clj | 42 ++++++++------------ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/test/monger/test/capped_collections_test.clj b/test/monger/test/capped_collections_test.clj index 0797825..f8041ed 100644 --- a/test/monger/test/capped_collections_test.clj +++ b/test/monger/test/capped_collections_test.clj @@ -1,33 +1,25 @@ (ns monger.test.capped-collections-test - (:require [monger core util] + (:require [monger.core :as mg] [monger.collection :as mc] - [monger.result :as mres] - [monger.test.helper :as helper] [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) - -(helper/connect!) + [monger.operators :refer :all])) (defn- megabytes [^long n] (* n 1024 1024)) - -;; -;; Tests -;; - -(deftest test-inserting-into-capped-collection - (let [n 1000 - cname "cached" - _ (mc/drop cname) - coll (mc/create cname {:capped true :size (-> 16 megabytes) :max n})] - (is (= cname (.getName coll))) - (mc/insert-batch cname (for [i (range 0 (+ n 100))] {:i i})) - (is (= n (mc/count cname))) - ;; older elements get replaced by newer ones - (is (not (mc/any? cname {:i 1}))) - (is (not (mc/any? cname {:i 5}))) - (is (not (mc/any? cname {:i 9}))) - (is (mc/any? cname {:i (+ n 80)})))) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (deftest test-inserting-into-capped-collection + (let [n 1000 + cname "cached" + _ (mc/drop db cname) + coll (mc/create db cname {:capped true :size (-> 16 megabytes) :max n})] + (is (= cname (.getName coll))) + (mc/insert-batch db cname (for [i (range 0 (+ n 100))] {:i i})) + (is (= n (mc/count db cname))) + ;; older elements get replaced by newer ones + (is (not (mc/any? db cname {:i 1}))) + (is (not (mc/any? db cname {:i 5}))) + (is (not (mc/any? db cname {:i 9}))) + (is (mc/any? db cname {:i (+ n 80)}))))) From 6acfb43314c57b17583fe333754f4c3b073a6855 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:17:14 -0400 Subject: [PATCH 33/48] Collection op tests now pass --- test/monger/test/collection_test.clj | 268 ++++++++++++++------------- 1 file changed, 137 insertions(+), 131 deletions(-) diff --git a/test/monger/test/collection_test.clj b/test/monger/test/collection_test.clj index 9e99010..eb41e3a 100644 --- a/test/monger/test/collection_test.clj +++ b/test/monger/test/collection_test.clj @@ -1,151 +1,157 @@ (ns monger.test.collection-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType] - org.bson.types.ObjectId + (:import org.bson.types.ObjectId java.util.Date) (:require [monger.core :as mg] [monger.collection :as mc] - [monger.result :as mgres] - [monger.test.helper :as helper] [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) + [monger.operators :refer :all])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] -(use-fixtures :each purge-people purge-docs purge-things purge-libraries) + (defn purge-collections + [f] + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "libraries") + (f) + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "libraries")) + + (use-fixtures :each purge-collections) + + ;; + ;; count, remove + ;; + + (deftest get-collection-size + (let [collection "things"] + (is (= 0 (mc/count db collection))) + (mc/insert-batch db collection [{:language "Clojure" :name "langohr"} + {:language "Clojure" :name "monger"} + {:language "Clojure" :name "incanter"} + {:language "Scala" :name "akka"}]) + (is (= 4 (mc/count db collection))) + (is (mc/any? db collection)) + (is (= 3 (mc/count db collection {:language "Clojure"}))) + (is (mc/any? db collection {:language "Clojure"})) + (is (= 1 (mc/count db collection {:language "Scala" }))) + (is (mc/any? db collection {:language "Scala"})) + (is (= 0 (mc/count db collection {:language "Python" }))) + (is (not (mc/any? db collection {:language "Python"}))))) -;; -;; count, remove -;; - -(deftest get-collection-size - (let [collection "things"] - (is (= 0 (mc/count collection))) - (mc/insert-batch collection [{:language "Clojure" :name "langohr"} - {:language "Clojure" :name "monger"} - {:language "Clojure" :name "incanter"} - {:language "Scala" :name "akka"}]) - (is (= 4 (mc/count collection))) - (is (mc/any? collection)) - (is (= 3 (mc/count mg/*mongodb-database* collection {:language "Clojure"}))) - (is (mc/any? mg/*mongodb-database* collection {:language "Clojure"})) - (is (= 1 (mc/count collection {:language "Scala" }))) - (is (mc/any? collection {:language "Scala"})) - (is (= 0 (mc/count mg/*mongodb-database* collection {:language "Python" }))) - (is (not (mc/any? mg/*mongodb-database* collection {:language "Python"}))))) + (deftest remove-all-documents-from-collection + (let [collection "libraries"] + (mc/insert-batch db collection [{:language "Clojure" :name "monger"} + {:language "Clojure" :name "langohr"} + {:language "Clojure" :name "incanter"} + {:language "Scala" :name "akka"}]) + (is (= 4 (mc/count db collection))) + (mc/remove db collection) + (is (= 0 (mc/count db collection))))) -(deftest remove-all-documents-from-collection - (let [collection "libraries"] - (mc/insert-batch collection [{:language "Clojure" :name "monger"} - {:language "Clojure" :name "langohr"} - {:language "Clojure" :name "incanter"} - {:language "Scala" :name "akka"}]) - (is (= 4 (mc/count collection))) - (mc/remove collection) - (is (= 0 (mc/count collection))))) + (deftest remove-some-documents-from-collection + (let [collection "libraries"] + (mc/insert-batch db collection [{:language "Clojure" :name "monger"} + {:language "Clojure" :name "langohr"} + {:language "Clojure" :name "incanter"} + {:language "Scala" :name "akka"}]) + (is (= 4 (mc/count db collection))) + (mc/remove db collection {:language "Clojure"}) + (is (= 1 (mc/count db collection))))) + + (deftest remove-a-single-document-from-collection + (let [collection "libraries" + oid (ObjectId.)] + (mc/insert-batch db collection [{:language "Clojure" :name "monger" :_id oid}]) + (mc/remove-by-id db collection oid) + (is (= 0 (mc/count db collection))) + (is (nil? (mc/find-by-id db collection oid))))) -(deftest remove-some-documents-from-collection - (let [collection "libraries"] - (mc/insert-batch collection [{:language "Clojure" :name "monger"} - {:language "Clojure" :name "langohr"} - {:language "Clojure" :name "incanter"} - {:language "Scala" :name "akka"}]) - (is (= 4 (mc/count collection))) - (mc/remove collection {:language "Clojure"}) - (is (= 1 (mc/count collection))))) + ;; + ;; exists?, drop, create + ;; -(deftest remove-a-single-document-from-collection - (let [collection "libraries" - oid (ObjectId.)] - (mc/insert-batch collection [{:language "Clojure" :name "monger" :_id oid}]) - (mc/remove-by-id collection oid) - (is (= 0 (mc/count collection))) - (is (nil? (mc/find-by-id collection oid))))) + (deftest checking-for-collection-existence-when-it-does-not-exist + (let [collection "widgets"] + (mc/drop db collection) + (is (false? (mc/exists? db collection))))) + + (deftest checking-for-collection-existence-when-it-does-exist + (let [collection "widgets"] + (mc/drop db collection) + (mc/insert-batch db collection [{:name "widget1"} + {:name "widget2"}]) + (is (mc/exists? db collection)) + (mc/drop db collection) + (is (false? (mc/exists? db collection))) + (mc/create db "widgets" {:capped true :size 100000 :max 10}) + (is (mc/exists? db collection)) + (mc/rename db collection "gadgets") + (is (not (mc/exists? db collection))) + (is (mc/exists? db "gadgets")) + (mc/drop db "gadgets"))) + + ;; + ;; any?, empty? + ;; + + (deftest test-any-on-empty-collection + (let [collection "things"] + (is (not (mc/any? db collection))))) + + (deftest test-any-on-non-empty-collection + (let [collection "things" + _ (mc/insert db collection {:language "Clojure" :name "langohr"})] + (is (mc/any? db "things" {:language "Clojure"})))) + + (deftest test-empty-on-empty-collection + (let [collection "things"] + (is (mc/empty? db collection)))) + + (deftest test-empty-on-non-empty-collection + (let [collection "things" + _ (mc/insert db collection {:language "Clojure" :name "langohr"})] + (is (not (mc/empty? db "things"))))) -;; -;; exists?, drop, create -;; + ;; + ;; distinct + ;; -(deftest checking-for-collection-existence-when-it-does-not-exist - (let [collection "widgets"] - (mc/drop collection) - (is (false? (mc/exists? collection))))) - -(deftest checking-for-collection-existence-when-it-does-exist - (let [collection "widgets"] - (mc/drop collection) - (mc/insert-batch collection [{:name "widget1"} - {:name "widget2"}]) - (is (mc/exists? collection)) - (mc/drop collection) - (is (false? (mc/exists? collection))) - (mc/create "widgets" {:capped true :size 100000 :max 10}) - (is (mc/exists? collection)) - (mc/rename collection "gadgets") - (is (not (mc/exists? collection))) - (is (mc/exists? "gadgets")) - (mc/drop "gadgets"))) - -;; -;; any?, empty? -;; - -(deftest test-any-on-empty-collection - (let [collection "things"] - (is (not (mc/any? collection))))) - -(deftest test-any-on-non-empty-collection - (let [collection "things" - _ (mc/insert collection {:language "Clojure" :name "langohr"})] - (is (mc/any? "things")) - (is (mc/any? mg/*mongodb-database* "things" {:language "Clojure"})))) - -(deftest test-empty-on-empty-collection - (let [collection "things"] - (is (mc/empty? collection)) - (is (mc/empty? mg/*mongodb-database* collection)))) - -(deftest test-empty-on-non-empty-collection - (let [collection "things" - _ (mc/insert collection {:language "Clojure" :name "langohr"})] - (is (not (mc/empty? "things"))))) + (deftest test-distinct-values + (let [collection "widgets" + batch [{:state "CA" :quantity 1 :price 199.00} + {:state "NY" :quantity 2 :price 199.00} + {:state "NY" :quantity 1 :price 299.00} + {:state "IL" :quantity 2 :price 11.50 } + {:state "CA" :quantity 2 :price 2.95 } + {:state "IL" :quantity 3 :price 5.50 }]] + (mc/insert-batch db collection batch) + (is (= ["CA" "IL" "NY"] (sort (mc/distinct db collection :state {})))) + (is (= ["CA" "NY"] (sort (mc/distinct db collection :state {:price {$gt 100.00}})))))) -;; -;; distinct -;; + ;; + ;; miscellenous + ;; -(deftest test-distinct-values - (let [collection "widgets" - batch [{:state "CA" :quantity 1 :price 199.00} - {:state "NY" :quantity 2 :price 199.00} - {:state "NY" :quantity 1 :price 299.00} - {:state "IL" :quantity 2 :price 11.50 } - {:state "CA" :quantity 2 :price 2.95 } - {:state "IL" :quantity 3 :price 5.50 }]] - (mc/insert-batch collection batch) - (is (= ["CA" "IL" "NY"] (sort (mc/distinct mg/*mongodb-database* collection :state {})))) - (is (= ["CA" "NY"] (sort (mc/distinct collection :state {:price {$gt 100.00}})))))) - - -;; -;; miscellenous -;; - -(deftest test-system-collection-predicate - (are [name] (is (mc/system-collection? name)) - "system.indexes" - "system" - ;; we treat default GridFS collections as system ones, - ;; possibly this is a bad idea, time will tell. MK. - "fs.chunks" - "fs.files") - (are [name] (is (not (mc/system-collection? name))) - "events" - "accounts" - "megacorp_account" - "myapp_development")) + (deftest test-system-collection-predicate + (are [name] (is (mc/system-collection? name)) + "system.indexes" + "system" + ;; we treat default GridFS collections as system ones, + ;; possibly this is a bad idea, time will tell. MK. + "fs.chunks" + "fs.files") + (are [name] (is (not (mc/system-collection? name))) + "events" + "accounts" + "megacorp_account" + "myapp_development"))) From c29587f66d9a0dbddc03db0bd5c9c268686bd18f Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:19:19 -0400 Subject: [PATCH 34/48] Cursor tests now pass --- test/monger/test/cursor_test.clj | 199 +++++++++++++++---------------- 1 file changed, 99 insertions(+), 100 deletions(-) diff --git a/test/monger/test/cursor_test.clj b/test/monger/test/cursor_test.clj index 061c7a3..7553af6 100644 --- a/test/monger/test/cursor_test.clj +++ b/test/monger/test/cursor_test.clj @@ -1,110 +1,109 @@ (ns monger.test.cursor-test (:import [com.mongodb DBCursor DBObject Bytes] [java.util List Map]) - (:require [monger.test.helper :as helper] + (:require [monger.core :as mg] [clojure.test :refer :all] - [monger.cursor :refer :all] - [monger.test.fixtures :refer :all])) + [monger.cursor :refer :all])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (deftest make-db-cursor-for-collection + (is (= DBCursor + (class (make-db-cursor db :docs))))) -(deftest make-db-cursor-for-collection - (is (= DBCursor - (class (make-db-cursor :docs))))) - -(deftest getting-cursor-options-value - (let [db-cur (make-db-cursor :docs) - opts (get-options db-cur)] - (is (= true (isa? (class opts) Map))) - (is (= 0 (.getOptions db-cur))) ;;test default value - (is (= false (:notimeout opts))) - (is (= false (:partial opts))) - (is (= false (:awaitdata opts))) - (is (= false (:oplogreplay opts))) - (is (= false (:slaveok opts))) - (is (= false (:tailable opts))))) - -(deftest adding-option-to-cursor - (let [db-cur (make-db-cursor :docs)] - (add-option! db-cur :notimeout) - (is (= (:notimeout cursor-options) - (.getOptions db-cur))) - ;; setting tailable will also set awaitdata in 2.12.x. MK. - (add-option! db-cur :tailable) - (is (= (.getOptions db-cur) - (bit-or (:notimeout cursor-options) - (:tailable cursor-options) - (:awaitdata cursor-options)))))) - -(deftest remove-option-from-cursor - (let [db-cur (make-db-cursor :docs)] - (add-option! db-cur :partial) - (add-option! db-cur :awaitdata) - ;; removing not-set option should not affect result - (remove-option! db-cur :notimeout) - (is (= (.getOptions db-cur) - (bit-or (:partial cursor-options) - (:awaitdata cursor-options)))) - ;; removing active option should remove correct value - (remove-option! db-cur :awaitdata) - (is (= (.getOptions db-cur) - (:partial cursor-options))))) - - -(deftest test-reset-options - (let [db-cur (make-db-cursor :docs)] - (add-option! db-cur :partial) - (is (= (.getOptions db-cur) - (:partial cursor-options))) - (is (= 0 - (int (.getOptions (reset-options db-cur))))))) - -(deftest add-options-with-hashmap - (let [db-cur (make-db-cursor :docs) - _ (add-options db-cur {:notimeout true :slaveok true}) - opts (get-options db-cur)] - (is (= true (:notimeout opts))) - (is (= true (:slaveok opts))) - (is (= false (:tailable opts))) - (is (= false (:oplogreplay opts))))) - -(deftest add-options-with-hashmap-and-remove-option - (let [db-cur (make-db-cursor :docs) - _ (add-options db-cur {:notimeout true :slaveok true}) - opts (get-options db-cur)] - (is (= true (:notimeout opts))) - (is (= true (:slaveok opts))) - ;;remove key and add another option - (add-options db-cur {:partial true :slaveok false}) - (let [opts (get-options db-cur)] - (is (= true (:notimeout opts))) - (is (= true (:partial opts))) + (deftest getting-cursor-options-value + (let [db-cur (make-db-cursor db :docs) + opts (get-options db-cur)] + (is (= true (isa? (class opts) Map))) + (is (= 0 (.getOptions db-cur))) ;;test default value + (is (= false (:notimeout opts))) + (is (= false (:partial opts))) + (is (= false (:awaitdata opts))) + (is (= false (:oplogreplay opts))) (is (= false (:slaveok opts))) - (is (= false (:tailable opts)))))) + (is (= false (:tailable opts))))) -(deftest add-options-with-list - (let [db-cur (make-db-cursor :docs) - _ (add-options db-cur [:notimeout :slaveok]) - opts (get-options db-cur)] - (is (= true (:notimeout opts))) - (is (= true (:slaveok opts))) - (is (= false (:tailable opts))) - (is (= false (:oplogreplay opts))))) + (deftest adding-option-to-cursor + (let [db-cur (make-db-cursor db :docs)] + (add-option! db-cur :notimeout) + (is (= (:notimeout cursor-options) + (.getOptions db-cur))) + ;; setting tailable will also set awaitdata in 2.12.x. MK. + (add-option! db-cur :tailable) + (is (= (.getOptions db-cur) + (bit-or (:notimeout cursor-options) + (:tailable cursor-options) + (:awaitdata cursor-options)))))) -(deftest add-options-with-Bytes - (let [db-cur (make-db-cursor :docs) - _ (add-options db-cur Bytes/QUERYOPTION_NOTIMEOUT) - opts (get-options db-cur)] - (is (= true (:notimeout opts))) - (is (= false (:slaveok opts))) - (is (= false (:tailable opts))) - (is (= false (:oplogreplay opts))))) + (deftest remove-option-from-cursor + (let [db-cur (make-db-cursor db :docs)] + (add-option! db-cur :partial) + (add-option! db-cur :awaitdata) + ;; removing not-set option should not affect result + (remove-option! db-cur :notimeout) + (is (= (.getOptions db-cur) + (bit-or (:partial cursor-options) + (:awaitdata cursor-options)))) + ;; removing active option should remove correct value + (remove-option! db-cur :awaitdata) + (is (= (.getOptions db-cur) + (:partial cursor-options))))) -(deftest add-options-with-one-keyword - (let [db-cur (make-db-cursor :docs) - _ (add-options db-cur :notimeout) - opts (get-options db-cur)] - (is (= true (:notimeout opts))) - (is (= false (:slaveok opts))) - (is (= false (:tailable opts))) - (is (= false (:oplogreplay opts))))) + + (deftest test-reset-options + (let [db-cur (make-db-cursor db :docs)] + (add-option! db-cur :partial) + (is (= (.getOptions db-cur) + (:partial cursor-options))) + (is (= 0 + (int (.getOptions (reset-options db-cur))))))) + + (deftest add-options-with-hashmap + (let [db-cur (make-db-cursor db :docs) + _ (add-options db-cur {:notimeout true :slaveok true}) + opts (get-options db-cur)] + (is (= true (:notimeout opts))) + (is (= true (:slaveok opts))) + (is (= false (:tailable opts))) + (is (= false (:oplogreplay opts))))) + + (deftest add-options-with-hashmap-and-remove-option + (let [db-cur (make-db-cursor db :docs) + _ (add-options db-cur {:notimeout true :slaveok true}) + opts (get-options db-cur)] + (is (= true (:notimeout opts))) + (is (= true (:slaveok opts))) + ;;remove key and add another option + (add-options db-cur {:partial true :slaveok false}) + (let [opts (get-options db-cur)] + (is (= true (:notimeout opts))) + (is (= true (:partial opts))) + (is (= false (:slaveok opts))) + (is (= false (:tailable opts)))))) + + (deftest add-options-with-list + (let [db-cur (make-db-cursor db :docs) + _ (add-options db-cur [:notimeout :slaveok]) + opts (get-options db-cur)] + (is (= true (:notimeout opts))) + (is (= true (:slaveok opts))) + (is (= false (:tailable opts))) + (is (= false (:oplogreplay opts))))) + + (deftest add-options-with-Bytes + (let [db-cur (make-db-cursor db :docs) + _ (add-options db-cur Bytes/QUERYOPTION_NOTIMEOUT) + opts (get-options db-cur)] + (is (= true (:notimeout opts))) + (is (= false (:slaveok opts))) + (is (= false (:tailable opts))) + (is (= false (:oplogreplay opts))))) + + (deftest add-options-with-one-keyword + (let [db-cur (make-db-cursor db :docs) + _ (add-options db-cur :notimeout) + opts (get-options db-cur)] + (is (= true (:notimeout opts))) + (is (= false (:slaveok opts))) + (is (= false (:tailable opts))) + (is (= false (:oplogreplay opts)))))) From b3c501a73a45f2f270b86e2971a85e1951e119e1 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:26:27 -0400 Subject: [PATCH 35/48] Inserting tests now pass --- test/monger/test/inserting_test.clj | 297 ++++++++++++++-------------- 1 file changed, 153 insertions(+), 144 deletions(-) diff --git a/test/monger/test/inserting_test.clj b/test/monger/test/inserting_test.clj index 6213c8c..6bc7ad3 100644 --- a/test/monger/test/inserting_test.clj +++ b/test/monger/test/inserting_test.clj @@ -5,165 +5,174 @@ (:require [monger.core :as mg] [monger.util :as mu] [monger.collection :as mc] - [monger.test.helper :as helper] [clojure.test :refer :all] [monger.operators :refer :all] - [monger.conversion :refer :all] - [monger.test.fixtures :refer :all])) - -(helper/connect!) - -(use-fixtures :each purge-people purge-docs purge-things purge-libraries) - - -;; -;; insert -;; - -(deftest insert-a-basic-document-without-id-and-with-default-write-concern - (let [collection "people" - doc {:name "Joe" :age 30}] - (is (monger.result/ok? (mc/insert "people" doc))) - (is (= 1 (mc/count collection))))) - -(deftest insert-a-basic-document-with-explicitly-passed-database-without-id-and-with-default-write-concern - (let [collection "people" - doc {:name "Joe" :age 30}] - (dotimes [n 5] - (is (monger.result/ok? (mc/insert monger.core/*mongodb-database* "people" doc WriteConcern/SAFE)))) - (is (= 5 (mc/count collection))))) - -(deftest insert-a-basic-document-without-id-and-with-explicit-write-concern - (let [collection "people" - doc {:name "Joe" :age 30}] - (is (monger.result/ok? (mc/insert "people" doc WriteConcern/SAFE))) - (is (= 1 (mc/count collection))))) - -(deftest insert-a-basic-db-object-without-id-and-with-default-write-concern - (let [collection "people" - doc (to-db-object {:name "Joe" :age 30})] - (is (nil? (.get ^DBObject doc "_id"))) - (mc/insert "people" doc) - (is (not (nil? (monger.util/get-id doc)))))) - -(deftest insert-a-map-with-id-and-with-default-write-concern - (let [collection "people" - id (ObjectId.) - doc {:name "Joe" :age 30 "_id" id} - result (mc/insert "people" doc)] - (is (= id (monger.util/get-id doc))))) - -(deftest insert-a-document-with-clojure-ratio-in-it - (let [collection "widgets" - id (ObjectId.) - doc {:ratio 11/2 "_id" id} - result (mc/insert "widgets" doc)] - (is (= 5.5 (:ratio (mc/find-map-by-id collection id)))))) - -(deftest insert-a-document-with-clojure-keyword-in-it - (let [collection "widgets" - id (ObjectId.) - doc {:keyword :kwd "_id" id} - result (mc/insert "widgets" doc)] - (is (= (name :kwd) (:keyword (mc/find-map-by-id collection id)))))) - -(deftest insert-a-document-with-clojure-keyword-in-a-set-in-it - (let [collection "widgets" - id (ObjectId.) - doc {:keyword1 {:keyword2 #{:kw1 :kw2}} "_id" id} - result (mc/insert "widgets" doc)] - (is (= (sort ["kw1" "kw2"]) - (sort (get-in (mc/find-map-by-id collection id) [:keyword1 :keyword2])))))) - + [monger.conversion :refer :all])) (defrecord Metrics [rps eps]) -(deftest insert-a-document-with-clojure-record-in-it - (let [collection "widgets" - id (ObjectId.) - doc {:record (Metrics. 10 20) "_id" id} - result (mc/insert "widgets" doc)] - (is (= {:rps 10 :eps 20} (:record (mc/find-map-by-id collection id)))))) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (defn purge-collections + [f] + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "scores") + (f) + (mc/remove db "people") + (mc/remove db "docs") + (mc/remove db "things") + (mc/remove db "scores")) -(deftest test-insert-a-document-with-dbref - (mc/remove "widgets") - (mc/remove "owners") - (let [coll1 "widgets" - coll2 "owners" - oid (ObjectId.) - joe (mc/insert "owners" {:name "Joe" :_id oid}) - dbref (DBRef. (mg/current-db) coll2 oid)] - (mc/insert coll1 {:type "pentagon" :owner dbref}) - (let [fetched (mc/find-one-as-map coll1 {:type "pentagon"}) - fo (:owner fetched)] - (is (= {:_id oid :name "Joe"} (from-db-object @fo true)))))) + (use-fixtures :each purge-collections) -;; -;; insert-and-return -;; + ;; + ;; insert + ;; -(deftest insert-and-return-a-basic-document-without-id-and-with-default-write-concern - (let [collection "people" - doc {:name "Joe" :age 30} - result (mc/insert-and-return :people doc)] - (is (= (:name doc) - (:name result))) - (is (= (:age doc) - (:age result))) - (is (:_id result)) - (is (= 1 (mc/count collection))))) + (deftest insert-a-basic-document-without-id-and-with-default-write-concern + (let [collection "people" + doc {:name "Joe" :age 30}] + (is (monger.result/ok? (mc/insert db collection doc))) + (is (= 1 (mc/count db collection))))) -(deftest insert-and-return-a-basic-document-without-id-but-with-a-write-concern - (let [collection "people" - doc {:name "Joe" :age 30 :ratio 3/4} - result (mc/insert-and-return "people" doc WriteConcern/FSYNC_SAFE)] - (is (= (:name doc) - (:name result))) - (is (= (:age doc) - (:age result))) - (is (= (:ratio doc) - (:ratio result))) - (is (:_id result)) - (is (= 1 (mc/count collection))))) + (deftest insert-a-basic-document-with-explicitly-passed-database-without-id-and-with-default-write-concern + (let [collection "people" + doc {:name "Joe" :age 30}] + (dotimes [n 5] + (is (monger.result/ok? (mc/insert db collection doc WriteConcern/SAFE)))) + (is (= 5 (mc/count db collection))))) -(deftest insert-and-return-with-a-provided-id - (let [collection "people" - oid (ObjectId.) - doc {:name "Joe" :age 30 :_id oid} - result (mc/insert-and-return :people doc)] - (is (= (:_id result) (:_id doc) oid)) - (is (= 1 (mc/count collection))))) + (deftest insert-a-basic-document-without-id-and-with-explicit-write-concern + (let [collection "people" + doc {:name "Joe" :age 30}] + (is (monger.result/ok? (mc/insert db collection doc WriteConcern/SAFE))) + (is (= 1 (mc/count db collection))))) + + (deftest insert-a-basic-db-object-without-id-and-with-default-write-concern + (let [collection "people" + doc (to-db-object {:name "Joe" :age 30})] + (is (nil? (.get ^DBObject doc "_id"))) + (mc/insert db collection doc) + (is (not (nil? (monger.util/get-id doc)))))) + + (deftest insert-a-map-with-id-and-with-default-write-concern + (let [collection "people" + id (ObjectId.) + doc {:name "Joe" :age 30 "_id" id} + result (mc/insert db collection doc)] + (is (= id (monger.util/get-id doc))))) + + (deftest insert-a-document-with-clojure-ratio-in-it + (let [collection "widgets" + id (ObjectId.) + doc {:ratio 11/2 "_id" id} + result (mc/insert db collection doc)] + (is (= 5.5 (:ratio (mc/find-map-by-id db collection id)))))) + + (deftest insert-a-document-with-clojure-keyword-in-it + (let [collection "widgets" + id (ObjectId.) + doc {:keyword :kwd "_id" id} + result (mc/insert db collection doc)] + (is (= (name :kwd) (:keyword (mc/find-map-by-id db collection id)))))) + + (deftest insert-a-document-with-clojure-keyword-in-a-set-in-it + (let [collection "widgets" + id (ObjectId.) + doc {:keyword1 {:keyword2 #{:kw1 :kw2}} "_id" id} + result (mc/insert db collection doc)] + (is (= (sort ["kw1" "kw2"]) + (sort (get-in (mc/find-map-by-id db collection id) [:keyword1 :keyword2])))))) + + (deftest insert-a-document-with-clojure-record-in-it + (let [collection "widgets" + id (ObjectId.) + doc {:record (Metrics. 10 20) "_id" id} + result (mc/insert db collection doc)] + (is (= {:rps 10 :eps 20} (:record (mc/find-map-by-id db collection id)))))) + + (deftest test-insert-a-document-with-dbref + (mc/remove db "widgets") + (mc/remove db "owners") + (let [coll1 "widgets" + coll2 "owners" + oid (ObjectId.) + joe (mc/insert db coll2 {:name "Joe" :_id oid}) + dbref (DBRef. db coll2 oid)] + (mc/insert db coll1 {:type "pentagon" :owner dbref}) + (let [fetched (mc/find-one-as-map db coll1 {:type "pentagon"}) + fo (:owner fetched)] + (is (= {:_id oid :name "Joe"} (from-db-object @fo true)))))) -;; -;; insert-batch -;; + ;; + ;; insert-and-return + ;; -(deftest insert-a-batch-of-basic-documents-without-ids-and-with-default-write-concern - (let [collection "people" - docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] - (is (monger.result/ok? (mc/insert-batch "people" docs))) - (is (= 2 (mc/count collection))))) + (deftest insert-and-return-a-basic-document-without-id-and-with-default-write-concern + (let [collection "people" + doc {:name "Joe" :age 30} + result (mc/insert-and-return db collection doc)] + (is (= (:name doc) + (:name result))) + (is (= (:age doc) + (:age result))) + (is (:_id result)) + (is (= 1 (mc/count db collection))))) -(deftest insert-a-batch-of-basic-documents-without-ids-and-with-explicit-write-concern - (let [collection "people" - docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] - (is (monger.result/ok? (mc/insert-batch "people" docs WriteConcern/NORMAL))) - (is (= 2 (mc/count collection))))) + (deftest insert-and-return-a-basic-document-without-id-but-with-a-write-concern + (let [collection "people" + doc {:name "Joe" :age 30 :ratio 3/4} + result (mc/insert-and-return db collection doc WriteConcern/FSYNC_SAFE)] + (is (= (:name doc) + (:name result))) + (is (= (:age doc) + (:age result))) + (is (= (:ratio doc) + (:ratio result))) + (is (:_id result)) + (is (= 1 (mc/count db collection))))) -(deftest insert-a-batch-of-basic-documents-with-explicit-database-without-ids-and-with-explicit-write-concern - (let [collection "people" - docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] - (dotimes [n 44] - (is (monger.result/ok? (mc/insert-batch monger.core/*mongodb-database* "people" docs WriteConcern/NORMAL)))) - (is (= 88 (mc/count collection))))) + (deftest insert-and-return-with-a-provided-id + (let [collection "people" + oid (ObjectId.) + doc {:name "Joe" :age 30 :_id oid} + result (mc/insert-and-return db collection doc)] + (is (= (:_id result) (:_id doc) oid)) + (is (= 1 (mc/count db collection))))) -(deftest insert-a-batch-of-basic-documents-from-a-lazy-sequence - (let [collection "people" - numbers (range 0 1000)] - (is (monger.result/ok? (mc/insert-batch "people" (map (fn [^long l] - {:n l}) - numbers)))) - (is (= (count numbers) (mc/count collection))))) + + ;; + ;; insert-batch + ;; + + (deftest insert-a-batch-of-basic-documents-without-ids-and-with-default-write-concern + (let [collection "people" + docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] + (is (monger.result/ok? (mc/insert-batch db collection docs))) + (is (= 2 (mc/count db collection))))) + + (deftest insert-a-batch-of-basic-documents-without-ids-and-with-explicit-write-concern + (let [collection "people" + docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] + (is (monger.result/ok? (mc/insert-batch db collection docs WriteConcern/NORMAL))) + (is (= 2 (mc/count db collection))))) + + (deftest insert-a-batch-of-basic-documents-with-explicit-database-without-ids-and-with-explicit-write-concern + (let [collection "people" + docs [{:name "Joe" :age 30} {:name "Paul" :age 27}]] + (dotimes [n 44] + (is (monger.result/ok? (mc/insert-batch db collection docs WriteConcern/NORMAL)))) + (is (= 88 (mc/count db collection))))) + + (deftest insert-a-batch-of-basic-documents-from-a-lazy-sequence + (let [collection "people" + numbers (range 0 1000)] + (is (monger.result/ok? (mc/insert-batch db collection (map (fn [^long l] + {:n l}) + numbers)))) + (is (= (count numbers) (mc/count db collection)))))) From 431e4495af0ab3649ee9c4efcdd2376b7d4d4afc Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:27:41 -0400 Subject: [PATCH 36/48] Typo --- test/monger/test/inserting_test.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/monger/test/inserting_test.clj b/test/monger/test/inserting_test.clj index 6bc7ad3..c3b04b9 100644 --- a/test/monger/test/inserting_test.clj +++ b/test/monger/test/inserting_test.clj @@ -19,12 +19,12 @@ (mc/remove db "people") (mc/remove db "docs") (mc/remove db "things") - (mc/remove db "scores") + (mc/remove db "widgets") (f) (mc/remove db "people") (mc/remove db "docs") (mc/remove db "things") - (mc/remove db "scores")) + (mc/remove db "widgets")) (use-fixtures :each purge-collections) From 03e7bfa1c7b03be205474b9979f5640d5a0268b6 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:30:12 -0400 Subject: [PATCH 37/48] Query operator tests now pass --- test/monger/test/query_operators_test.clj | 182 +++++++++++----------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/test/monger/test/query_operators_test.clj b/test/monger/test/query_operators_test.clj index 9cd0d9e..c1b5923 100644 --- a/test/monger/test/query_operators_test.clj +++ b/test/monger/test/query_operators_test.clj @@ -1,109 +1,109 @@ (ns monger.test.query-operators-test - (:import [com.mongodb WriteResult WriteConcern DBCursor DBObject MapReduceOutput MapReduceCommand MapReduceCommand$OutputType] - org.bson.types.ObjectId - java.util.Date) - (:require [monger core util] - [clojure stacktrace] - [monger.collection :as mgcol] - [monger.result :as mgres] - [monger.conversion :as mgcnv] + (:require [monger.core :as mg] + [monger.collection :as mc] [monger.js :as js] - [monger.test.helper :as helper] [clojure.test :refer :all] - [monger.operators :refer :all] - [monger.test.fixtures :refer :all])) + [monger.operators :refer :all])) -(monger.core/connect!) -(monger.core/set-db! (monger.core/get-db "monger-test")) +;; (use-fixtures :each purge-people purge-docs purge-things purge-libraries) -(use-fixtures :each purge-people purge-docs purge-things purge-libraries) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (defn purge-collections + [f] + (mc/remove db "people") + (mc/remove db "libraries") + (f) + (mc/remove db "people") + (mc/remove db "libraries")) -;; -;; $gt, $gte, $lt, lte -;; + (use-fixtures :each purge-collections) + ;; + ;; $gt, $gte, $lt, lte + ;; -(deftest find-with-conditional-operators-comparison - (let [collection "libraries"] - (mgcol/insert-batch collection [{:language "Clojure" :name "monger" :users 1} - {:language "Clojure" :name "langohr" :users 5} - {:language "Clojure" :name "incanter" :users 15} - {:language "Scala" :name "akka" :users 150}]) - (are [a b] (= a (.count (mgcol/find collection b))) - 2 {:users {$gt 10}} - 3 {:users {$gte 5}} - 2 {:users {$lt 10}} - 2 {:users {$lte 5}} - 1 {:users {$gt 10 $lt 150}}))) + (deftest find-with-conditional-operators-comparison + (let [collection "libraries"] + (mc/insert-batch db collection [{:language "Clojure" :name "monger" :users 1} + {:language "Clojure" :name "langohr" :users 5} + {:language "Clojure" :name "incanter" :users 15} + {:language "Scala" :name "akka" :users 150}]) + (are [a b] (= a (.count (mc/find db collection b))) + 2 {:users {$gt 10}} + 3 {:users {$gte 5}} + 2 {:users {$lt 10}} + 2 {:users {$lte 5}} + 1 {:users {$gt 10 $lt 150}}))) -;; -;; $ne -;; + ;; + ;; $ne + ;; -(deftest find-with-and-or-operators - (let [collection "libraries"] - (mgcol/insert-batch collection [{:language "Ruby" :name "mongoid" :users 1} - {:language "Clojure" :name "langohr" :users 5} - {:language "Clojure" :name "incanter" :users 15} - {:language "Scala" :name "akka" :users 150}]) - (is (= 2 (.count (mgcol/find collection {$ne {:language "Clojure"}})))))) + (deftest find-with-and-or-operators + (let [collection "libraries"] + (mc/insert-batch db collection [{:language "Ruby" :name "mongoid" :users 1} + {:language "Clojure" :name "langohr" :users 5} + {:language "Clojure" :name "incanter" :users 15} + {:language "Scala" :name "akka" :users 150}]) + (is (= 2 (.count (mc/find db collection {$ne {:language "Clojure"}})))))) -;; -;; $and, $or, $nor -;; + ;; + ;; $and, $or, $nor + ;; -(deftest find-with-and-or-operators - (let [collection "libraries"] - (mgcol/insert-batch collection [{:language "Ruby" :name "mongoid" :users 1} - {:language "Clojure" :name "langohr" :users 5} - {:language "Clojure" :name "incanter" :users 15} - {:language "Scala" :name "akka" :users 150}]) - (is (= 1 (.count (mgcol/find collection {$and [{:language "Clojure"} - {:users {$gt 10}}]})))) - (is (= 3 (.count (mgcol/find collection {$or [{:language "Clojure"} - {:users {$gt 10}} ]})))) - (is (= 1 (.count (mgcol/find collection {$nor [{:language "Clojure"} - {:users {$gt 10}} ]})))))) + (deftest find-with-and-or-operators + (let [collection "libraries"] + (mc/insert-batch db collection [{:language "Ruby" :name "mongoid" :users 1} + {:language "Clojure" :name "langohr" :users 5} + {:language "Clojure" :name "incanter" :users 15} + {:language "Scala" :name "akka" :users 150}]) + (is (= 1 (.count (mc/find db collection {$and [{:language "Clojure"} + {:users {$gt 10}}]})))) + (is (= 3 (.count (mc/find db collection {$or [{:language "Clojure"} + {:users {$gt 10}} ]})))) + (is (= 1 (.count (mc/find db collection {$nor [{:language "Clojure"} + {:users {$gt 10}} ]})))))) -;; -;; $all, $in, $nin -;; + ;; + ;; $all, $in, $nin + ;; -(deftest find-on-embedded-arrays - (let [collection "libraries"] - (mgcol/insert-batch collection [{:language "Clojure" :tags [ "functional" ]} - {:language "Scala" :tags [ "functional" "object-oriented" ]} - {:language "Ruby" :tags [ "object-oriented" "dynamic" ]}]) + (deftest find-on-embedded-arrays + (let [collection "libraries"] + (mc/insert-batch db collection [{:language "Clojure" :tags [ "functional" ]} + {:language "Scala" :tags [ "functional" "object-oriented" ]} + {:language "Ruby" :tags [ "object-oriented" "dynamic" ]}]) - (is (= "Scala" (:language (first (mgcol/find-maps collection {:tags {$all [ "functional" "object-oriented" ]}} ))))) - (is (= 3 (.count (mgcol/find-maps collection {:tags {$in [ "functional" "object-oriented" ]}} )))) - (is (= 2 (.count (mgcol/find-maps collection {:language {$in [ "Scala" "Ruby" ]}} )))) - (is (= 1 (.count (mgcol/find-maps collection {:tags {$nin [ "dynamic" "object-oriented" ]}} )))) - (is (= 3 (.count (mgcol/find-maps collection {:language {$nin [ "C#" ]}} )))))) + (is (= "Scala" (:language (first (mc/find-maps db collection {:tags {$all [ "functional" "object-oriented" ]}} ))))) + (is (= 3 (.count (mc/find-maps db collection {:tags {$in [ "functional" "object-oriented" ]}} )))) + (is (= 2 (.count (mc/find-maps db collection {:language {$in [ "Scala" "Ruby" ]}} )))) + (is (= 1 (.count (mc/find-maps db collection {:tags {$nin [ "dynamic" "object-oriented" ]}} )))) + (is (= 3 (.count (mc/find-maps db collection {:language {$nin [ "C#" ]}} )))))) -(deftest find-with-conditional-operators-on-embedded-documents - (let [collection "people"] - (mgcol/insert-batch collection [{:name "Bob" :comments [{:text "Nice!" :rating 1} - {:text "Love it" :rating 4} - {:text "What?":rating -5} ]} - {:name "Alice" :comments [{:text "Yeah" :rating 2} - {:text "Doh" :rating 1} - {:text "Agreed" :rating 3}]}]) - (are [a b] (= a (.count (mgcol/find collection b))) - 1 {:comments {$elemMatch {:text "Nice!" :rating {$gte 1}}}} - 2 {"comments.rating" 1} - 1 {"comments.rating" {$gt 3}}))) + (deftest find-with-conditional-operators-on-embedded-documents + (let [collection "people"] + (mc/insert-batch db collection [{:name "Bob" :comments [{:text "Nice!" :rating 1} + {:text "Love it" :rating 4} + {:text "What?":rating -5} ]} + {:name "Alice" :comments [{:text "Yeah" :rating 2} + {:text "Doh" :rating 1} + {:text "Agreed" :rating 3}]}]) + (are [a b] (= a (.count (mc/find db collection b))) + 1 {:comments {$elemMatch {:text "Nice!" :rating {$gte 1}}}} + 2 {"comments.rating" 1} + 1 {"comments.rating" {$gt 3}}))) -(deftest find-with-regex-operator - (let [collection "libraries"] - (mgcol/insert-batch collection [{:language "Ruby" :name "Mongoid" :users 1} - {:language "Clojure" :name "Langohr" :users 5} - {:language "Clojure" :name "Incanter" :users 15} - {:language "Scala" :name "Akka" :users 150}]) - (are [query results] (is (= results (.count (mgcol/find collection query)))) - {:language {$regex "Clo.*"}} 2 - {:language {$regex "clo.*" $options "i"}} 2 - {:name {$regex "aK.*" $options "i"}} 1 - {:language {$regex ".*by"}} 1 - {:language {$regex ".*ala.*"}} 1))) + (deftest find-with-regex-operator + (let [collection "libraries"] + (mc/insert-batch db collection [{:language "Ruby" :name "Mongoid" :users 1} + {:language "Clojure" :name "Langohr" :users 5} + {:language "Clojure" :name "Incanter" :users 15} + {:language "Scala" :name "Akka" :users 150}]) + (are [query results] (is (= results (.count (mc/find db collection query)))) + {:language {$regex "Clo.*"}} 2 + {:language {$regex "clo.*" $options "i"}} 2 + {:name {$regex "aK.*" $options "i"}} 1 + {:language {$regex ".*by"}} 1 + {:language {$regex ".*ala.*"}} 1)))) From eaa66edc939f87a6abc85ef3806ed9f0b03c7c3b Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:30:36 -0400 Subject: [PATCH 38/48] Cosmetics --- test/monger/test/query_operators_test.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/test/monger/test/query_operators_test.clj b/test/monger/test/query_operators_test.clj index c1b5923..bb09997 100644 --- a/test/monger/test/query_operators_test.clj +++ b/test/monger/test/query_operators_test.clj @@ -18,6 +18,7 @@ (mc/remove db "libraries")) (use-fixtures :each purge-collections) + ;; ;; $gt, $gte, $lt, lte ;; From 31ebc18c128629898d69e9419395cfb89ce8f36e Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:32:22 -0400 Subject: [PATCH 39/48] Ragtime integration tests now pass --- test/monger/test/ragtime_test.clj | 90 +++++++++++++++---------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/test/monger/test/ragtime_test.clj b/test/monger/test/ragtime_test.clj index 69844c3..c972396 100644 --- a/test/monger/test/ragtime_test.clj +++ b/test/monger/test/ragtime_test.clj @@ -1,55 +1,55 @@ (ns monger.test.ragtime-test (:require [monger.core :as mg] [monger.collection :as mc] - [monger.test.helper :as helper] monger.ragtime - [clojure.test :refer :all] - [monger.test.fixtures :refer [purge-migrations]] - [ragtime.core :refer :all])) + [ragtime.core :refer :all] + [clojure.test :refer :all])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (defn purge-collections + [f] + (mc/remove db "meta.migrations") + (f) + (mc/remove db "meta.migrations")) -(use-fixtures :each purge-migrations) + (use-fixtures :each purge-collections) - -(when-not (get (System/getenv) "CI") - (deftest test-add-migration-id - (let [db (mg/get-db "monger-test") - coll "meta.migrations" - key "1"] - (mc/remove db coll {}) - (is (not (mc/any? db coll {:_id key}))) - (is (not (some #{key} (applied-migration-ids db)))) - (add-migration-id db key) - (is (mc/any? db coll {:_id key})) - (is (some #{key} (applied-migration-ids db))))) - - - (deftest test-remove-migration-id - (let [db (mg/get-db "monger-test") - coll "meta.migrations" - key "1"] - (mc/remove db coll {}) - (add-migration-id db key) - (is (mc/any? db coll {:_id key})) - (is (some #{key} (applied-migration-ids db))) - (remove-migration-id db key) - (is (not (some #{key} (applied-migration-ids db)))))) - - - (deftest test-migrations-ordering - (let [db (mg/get-db "monger-test") - coll "meta.migrations" - all-keys [ "9" "4" "7" "1" "5" "3" "6" "2" "8"]] - (mc/remove db coll {}) - - (doseq [key all-keys] - (add-migration-id db key)) - - (doseq [key all-keys] + (when-not (get (System/getenv) "CI") + (deftest test-add-migration-id + (let [coll "meta.migrations" + key "1"] + (mc/remove db coll {}) + (is (not (mc/any? db coll {:_id key}))) + (is (not (some #{key} (applied-migration-ids db)))) + (add-migration-id db key) (is (mc/any? db coll {:_id key})) - (is (some #{key} (applied-migration-ids db)))) + (is (some #{key} (applied-migration-ids db))))) - (testing "Applied migrations must come out in creation order" - (is (= all-keys (applied-migration-ids db))))))) + + (deftest test-remove-migration-id + (let [coll "meta.migrations" + key "1"] + (mc/remove db coll {}) + (add-migration-id db key) + (is (mc/any? db coll {:_id key})) + (is (some #{key} (applied-migration-ids db))) + (remove-migration-id db key) + (is (not (some #{key} (applied-migration-ids db)))))) + + + (deftest test-migrations-ordering + (let [coll "meta.migrations" + all-keys [ "9" "4" "7" "1" "5" "3" "6" "2" "8"]] + (mc/remove db coll {}) + + (doseq [key all-keys] + (add-migration-id db key)) + + (doseq [key all-keys] + (is (mc/any? db coll {:_id key})) + (is (some #{key} (applied-migration-ids db)))) + + (testing "Applied migrations must come out in creation order" + (is (= all-keys (applied-migration-ids db)))))))) From 9a185596acff86ef1740ecae26bf27180fb35fcd Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:35:53 -0400 Subject: [PATCH 40/48] Clojure [Ring] session store tests now pass --- .../test/ring/clojure_session_store_test.clj | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/test/monger/test/ring/clojure_session_store_test.clj b/test/monger/test/ring/clojure_session_store_test.clj index a067672..43871ee 100644 --- a/test/monger/test/ring/clojure_session_store_test.clj +++ b/test/monger/test/ring/clojure_session_store_test.clj @@ -1,38 +1,34 @@ (ns monger.test.ring.clojure-session-store-test - (:require [monger core util] + (:require [monger.core :as mg] [monger.collection :as mc] - [monger.test.helper :as helper] [clojure.test :refer :all] [ring.middleware.session.store :refer :all] [monger.ring.session-store :refer :all])) -(helper/connect!) - -(defn purge-sessions +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (defn purge-sessions [f] - (mc/remove "web_sessions") - (mc/remove "sessions") + (mc/remove db "sessions") (f) - (mc/remove "web_sessions") - (mc/remove "sessions")) + (mc/remove db "sessions")) (use-fixtures :each purge-sessions) (deftest test-reading-a-session-that-does-not-exist - (let [store (session-store)] + (let [store (session-store db "sessions")] (is (= {} (read-session store "a-missing-key-1228277"))))) (deftest test-reading-a-session-that-does-not-exist-given-db - (let [db (monger.core/get-db) - store (session-store db "sessions")] + (let [store (session-store db "sessions")] (is (= {} (read-session store "a-missing-key-1228277"))))) (deftest test-reading-a-session-that-does-exist - (let [store (session-store) + (let [store (session-store db "sessions") sk (write-session store nil {:library "Monger"}) m (read-session store sk)] (is sk) @@ -42,8 +38,7 @@ (deftest test-reading-a-session-that-does-exist-given-db - (let [db (monger.core/get-db) - store (session-store db "sessions") + (let [store (session-store db "sessions") sk (write-session store nil {:library "Monger"}) m (read-session store sk)] (is sk) @@ -53,7 +48,7 @@ (deftest test-updating-a-session - (let [store (session-store "sessions") + (let [store (session-store db "sessions") sk1 (write-session store nil {:library "Monger"}) sk2 (write-session store sk1 {:library "Ring"}) m (read-session store sk2)] @@ -65,8 +60,7 @@ (deftest test-updating-a-session-given-db - (let [db (monger.core/get-db) - store (session-store db "sessions") + (let [store (session-store db "sessions") sk1 (write-session store nil {:library "Monger"}) sk2 (write-session store sk1 {:library "Ring"}) m (read-session store sk2)] @@ -78,15 +72,14 @@ (deftest test-deleting-a-session - (let [store (session-store "sessions") + (let [store (session-store db "sessions") sk (write-session store nil {:library "Monger"})] (is (nil? (delete-session store sk))) (is (= {} (read-session store sk))))) (deftest test-deleting-a-session - (let [db (monger.core/get-db) - store (session-store db "sessions") + (let [store (session-store db "sessions") sk (write-session store nil {:library "Monger"})] (is (nil? (delete-session store sk))) - (is (= {} (read-session store sk))))) + (is (= {} (read-session store sk)))))) From d7965adb86d1d294043967f1bcb1db6202f9796e Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:37:18 -0400 Subject: [PATCH 41/48] Remove tests that are now duplicates --- .../test/ring/clojure_session_store_test.clj | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/test/monger/test/ring/clojure_session_store_test.clj b/test/monger/test/ring/clojure_session_store_test.clj index 43871ee..587673c 100644 --- a/test/monger/test/ring/clojure_session_store_test.clj +++ b/test/monger/test/ring/clojure_session_store_test.clj @@ -22,11 +22,6 @@ (is (= {} (read-session store "a-missing-key-1228277"))))) -(deftest test-reading-a-session-that-does-not-exist-given-db - (let [store (session-store db "sessions")] - (is (= {} (read-session store "a-missing-key-1228277"))))) - - (deftest test-reading-a-session-that-does-exist (let [store (session-store db "sessions") sk (write-session store nil {:library "Monger"}) @@ -37,16 +32,6 @@ {:library "Monger"})))) -(deftest test-reading-a-session-that-does-exist-given-db - (let [store (session-store db "sessions") - sk (write-session store nil {:library "Monger"}) - m (read-session store sk)] - (is sk) - (is (and (:_id m))) - (is (= (dissoc m :_id) - {:library "Monger"})))) - - (deftest test-updating-a-session (let [store (session-store db "sessions") sk1 (write-session store nil {:library "Monger"}) @@ -58,28 +43,8 @@ (is (= (dissoc m :_id) {:library "Ring"})))) - -(deftest test-updating-a-session-given-db - (let [store (session-store db "sessions") - sk1 (write-session store nil {:library "Monger"}) - sk2 (write-session store sk1 {:library "Ring"}) - m (read-session store sk2)] - (is (and sk1 sk2)) - (is (and (:_id m))) - (is (= sk1 sk2)) - (is (= (dissoc m :_id) - {:library "Ring"})))) - - (deftest test-deleting-a-session (let [store (session-store db "sessions") sk (write-session store nil {:library "Monger"})] (is (nil? (delete-session store sk))) (is (= {} (read-session store sk))))) - - -(deftest test-deleting-a-session - (let [store (session-store db "sessions") - sk (write-session store nil {:library "Monger"})] - (is (nil? (delete-session store sk))) - (is (= {} (read-session store sk)))))) From 6f93043eab7939fe54661411c9e9eb0d964e78b5 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:38:44 -0400 Subject: [PATCH 42/48] Another session store test suite now passes --- test/monger/test/ring/session_store_test.clj | 128 ++++++------------- 1 file changed, 41 insertions(+), 87 deletions(-) diff --git a/test/monger/test/ring/session_store_test.clj b/test/monger/test/ring/session_store_test.clj index b23f05f..28a4c77 100644 --- a/test/monger/test/ring/session_store_test.clj +++ b/test/monger/test/ring/session_store_test.clj @@ -1,100 +1,54 @@ (ns monger.test.ring.session-store-test - (:require [monger core util] + (:require [monger.core :as mg] [monger.collection :as mc] - [monger.test.helper :as helper] [clojure.test :refer :all] [ring.middleware.session.store :refer :all] [monger.ring.session-store :refer :all])) -(helper/connect!) +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")] + (defn purge-sessions + [f] + (mc/remove db "sessions") + (f) + (mc/remove db "sessions")) -(defn purge-sessions - [f] - (mc/remove "web_sessions") - (mc/remove "sessions") - (f) - (mc/remove "web_sessions") - (mc/remove "sessions")) + (use-fixtures :each purge-sessions) -(use-fixtures :each purge-sessions) + (deftest test-reading-a-session-that-does-not-exist + (let [store (monger-store db "sessions")] + (is (= {} (read-session store "a-missing-key-1228277"))))) + (deftest test-reading-a-session-that-does-exist + (let [store (monger-store db "sessions") + sk (write-session store nil {:library "Monger"}) + m (read-session store sk)] + (is sk) + (is (and (:_id m) (:date m))) + (is (= (dissoc m :_id :date) + {:library "Monger"})))) -(deftest test-reading-a-session-that-does-not-exist - (let [store (monger-store)] - (is (= {} (read-session store "a-missing-key-1228277"))))) + (deftest test-updating-a-session + (let [store (monger-store db "sessions") + sk1 (write-session store nil {:library "Monger"}) + sk2 (write-session store sk1 {:library "Ring"}) + m (read-session store sk2)] + (is (and sk1 sk2)) + (is (and (:_id m) (:date m))) + (is (= sk1 sk2)) + (is (= (dissoc m :_id :date) + {:library "Ring"})))) + (deftest test-deleting-a-session + (let [store (monger-store db "sessions") + sk (write-session store nil {:library "Monger"})] + (is (nil? (delete-session store sk))) + (is (= {} (read-session store sk))))) -(deftest test-reading-a-session-that-does-not-exist-given-db - (let [db (monger.core/get-db) - store (monger-store db "sessions")] - (is (= {} (read-session store "a-missing-key-1228277"))))) - - -(deftest test-reading-a-session-that-does-exist - (let [store (monger-store) - sk (write-session store nil {:library "Monger"}) - m (read-session store sk)] - (is sk) - (is (and (:_id m) (:date m))) - (is (= (dissoc m :_id :date) - {:library "Monger"})))) - - -(deftest test-reading-a-session-that-does-exist-given-db - (let [db (monger.core/get-db) - store (monger-store db "sessions") - sk (write-session store nil {:library "Monger"}) - m (read-session store sk)] - (is sk) - (is (and (:_id m) (:date m))) - (is (= (dissoc m :_id :date) - {:library "Monger"})))) - - -(deftest test-updating-a-session - (let [store (monger-store "sessions") - sk1 (write-session store nil {:library "Monger"}) - sk2 (write-session store sk1 {:library "Ring"}) - m (read-session store sk2)] - (is (and sk1 sk2)) - (is (and (:_id m) (:date m))) - (is (= sk1 sk2)) - (is (= (dissoc m :_id :date) - {:library "Ring"})))) - - -(deftest test-updating-a-session-given-db - (let [db (monger.core/get-db) - store (monger-store db "sessions") - sk1 (write-session store nil {:library "Monger"}) - sk2 (write-session store sk1 {:library "Ring"}) - m (read-session store sk2)] - (is (and sk1 sk2)) - (is (and (:_id m) (:date m))) - (is (= sk1 sk2)) - (is (= (dissoc m :_id :date) - {:library "Ring"})))) - - -(deftest test-deleting-a-session - (let [store (monger-store "sessions") - sk (write-session store nil {:library "Monger"})] - (is (nil? (delete-session store sk))) - (is (= {} (read-session store sk))))) - - -(deftest test-deleting-a-session-given-db - (let [db (monger.core/get-db) - store (monger-store db "sessions") - sk (write-session store nil {:library "Monger"})] - (is (nil? (delete-session store sk))) - (is (= {} (read-session store sk))))) - - -(deftest test-reader-extensions - (let [d (java.util.Date.) - oid (org.bson.types.ObjectId.)] - (binding [*print-dup* true] - (pr-str d) - (pr-str oid)))) + (deftest test-reader-extensions + (let [d (java.util.Date.) + oid (org.bson.types.ObjectId.)] + (binding [*print-dup* true] + (pr-str d) + (pr-str oid))))) From 3fda07999d02da1056e63ea99e676d920386352d Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:39:37 -0400 Subject: [PATCH 43/48] An typo --- .../test/ring/clojure_session_store_test.clj | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/test/monger/test/ring/clojure_session_store_test.clj b/test/monger/test/ring/clojure_session_store_test.clj index 587673c..71df33e 100644 --- a/test/monger/test/ring/clojure_session_store_test.clj +++ b/test/monger/test/ring/clojure_session_store_test.clj @@ -9,42 +9,42 @@ (let [conn (mg/connect) db (mg/get-db conn "monger-test")] (defn purge-sessions - [f] - (mc/remove db "sessions") - (f) - (mc/remove db "sessions")) + [f] + (mc/remove db "sessions") + (f) + (mc/remove db "sessions")) -(use-fixtures :each purge-sessions) + (use-fixtures :each purge-sessions) -(deftest test-reading-a-session-that-does-not-exist - (let [store (session-store db "sessions")] - (is (= {} (read-session store "a-missing-key-1228277"))))) + (deftest test-reading-a-session-that-does-not-exist + (let [store (session-store db "sessions")] + (is (= {} (read-session store "a-missing-key-1228277"))))) -(deftest test-reading-a-session-that-does-exist - (let [store (session-store db "sessions") - sk (write-session store nil {:library "Monger"}) - m (read-session store sk)] - (is sk) - (is (and (:_id m))) - (is (= (dissoc m :_id) - {:library "Monger"})))) + (deftest test-reading-a-session-that-does-exist + (let [store (session-store db "sessions") + sk (write-session store nil {:library "Monger"}) + m (read-session store sk)] + (is sk) + (is (and (:_id m))) + (is (= (dissoc m :_id) + {:library "Monger"})))) -(deftest test-updating-a-session - (let [store (session-store db "sessions") - sk1 (write-session store nil {:library "Monger"}) - sk2 (write-session store sk1 {:library "Ring"}) - m (read-session store sk2)] - (is (and sk1 sk2)) - (is (and (:_id m))) - (is (= sk1 sk2)) - (is (= (dissoc m :_id) - {:library "Ring"})))) + (deftest test-updating-a-session + (let [store (session-store db "sessions") + sk1 (write-session store nil {:library "Monger"}) + sk2 (write-session store sk1 {:library "Ring"}) + m (read-session store sk2)] + (is (and sk1 sk2)) + (is (and (:_id m))) + (is (= sk1 sk2)) + (is (= (dissoc m :_id) + {:library "Ring"})))) -(deftest test-deleting-a-session - (let [store (session-store db "sessions") - sk (write-session store nil {:library "Monger"})] - (is (nil? (delete-session store sk))) - (is (= {} (read-session store sk))))) + (deftest test-deleting-a-session + (let [store (session-store db "sessions") + sk (write-session store nil {:library "Monger"})] + (is (nil? (delete-session store sk))) + (is (= {} (read-session store sk)))))) From 25f6dcf88d8d736157e8552f2adcba562a7bfd1e Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:40:19 -0400 Subject: [PATCH 44/48] Bump clj-time --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index fdf8d87..66874d3 100644 --- a/project.clj +++ b/project.clj @@ -54,7 +54,7 @@ monger.ring.session-store]}} ;; only clj-time/JodaTime available, used to test monger.joda-time w/o clojure.data.json :dev2 {:resource-paths ["test/resources"] - :dependencies [[clj-time "0.6.0" :exclusions [org.clojure/clojure]]]}} + :dependencies [[clj-time "0.7.0" :exclusions [org.clojure/clojure]]]}} :aliases {"all" ["with-profile" "dev:dev,1.4:dev,dj01x:dev,dj02x:dev,1.5"]} :repositories {"sonatype" {:url "http://oss.sonatype.org/content/repositories/releases" :snapshots false From 52155743771b0a834cab43161434597f66142866 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:40:43 -0400 Subject: [PATCH 45/48] Use 0.6 for now --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 66874d3..fdf8d87 100644 --- a/project.clj +++ b/project.clj @@ -54,7 +54,7 @@ monger.ring.session-store]}} ;; only clj-time/JodaTime available, used to test monger.joda-time w/o clojure.data.json :dev2 {:resource-paths ["test/resources"] - :dependencies [[clj-time "0.7.0" :exclusions [org.clojure/clojure]]]}} + :dependencies [[clj-time "0.6.0" :exclusions [org.clojure/clojure]]]}} :aliases {"all" ["with-profile" "dev:dev,1.4:dev,dj01x:dev,dj02x:dev,1.5"]} :repositories {"sonatype" {:url "http://oss.sonatype.org/content/repositories/releases" :snapshots false From b86ecb548709e0cf720b00eb279efd4e39a35139 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:42:15 -0400 Subject: [PATCH 46/48] More exclusions --- project.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project.clj b/project.clj index fdf8d87..0c4d9dd 100644 --- a/project.clj +++ b/project.clj @@ -40,9 +40,9 @@ [cheshire "5.3.1" :exclusions [org.clojure/clojure]] [org.clojure/tools.cli "0.3.1" :exclusions [org.clojure/clojure]] [org.clojure/core.cache "0.6.3" :exclusions [org.clojure/clojure]] - [ring/ring-core "1.2.1"] + [ring/ring-core "1.2.1" :exclusions [org.clojure/clojure]] [com.novemberain/validateur "2.1.0"] - [ragtime/ragtime.core "0.3.4"]] + [ragtime/ragtime.core "0.3.4" :exclusions [org.clojure/clojure]]] :plugins [[codox "0.6.6"]] :codox {:sources ["src/clojure"] :output-dir "doc/api" From ad25fba0f018c233ce603b666665092604eb441b Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:43:18 -0400 Subject: [PATCH 47/48] Exclusion for Validateur, too --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 0c4d9dd..96ac036 100644 --- a/project.clj +++ b/project.clj @@ -41,7 +41,7 @@ [org.clojure/tools.cli "0.3.1" :exclusions [org.clojure/clojure]] [org.clojure/core.cache "0.6.3" :exclusions [org.clojure/clojure]] [ring/ring-core "1.2.1" :exclusions [org.clojure/clojure]] - [com.novemberain/validateur "2.1.0"] + [com.novemberain/validateur "2.1.0" :exclusions [org.clojure/clojure]] [ragtime/ragtime.core "0.3.4" :exclusions [org.clojure/clojure]]] :plugins [[codox "0.6.6"]] :codox {:sources ["src/clojure"] From 31ee101d5ddb6d97d244d56306b58778d818f7d8 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 11 May 2014 13:51:48 -0400 Subject: [PATCH 48/48] Begin updating change log for 2.0 --- ChangeLog.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 148a3af..7151bed 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,62 @@ ## Changes between 1.8.0 and 2.0.0 -No changes yet. +`2.0` is a major release that has **breaking public API changes**. + +### Explicit Connection/DB/GridFS Argument + +In Monger 2.0, all key public API functions require an explicit +DB/connection/GridFS object to be provided instead of relying on +a shared dynamic var. This makes Monger much easier to use with +systems such as Component and Jig, as well as concurrent +applications that need to work with multiple connections, database, +or GridFS filesystems. + +In other words, instead of + +``` clojure +(require '[monger.collection :as mc]) + +(mc/insert "libraries" {:name "Monger"}) +``` + +it is now necessary to do + +``` clojure +(require '[monger.collection :as mc]) + +(mc/insert db "libraries" {:name "Monger"}) +``` + +This also means that `monger.core/connect!` and +`monger.core/connect-via-uri!` were removed, as was +`monger.multi` namespaces. + +To connect to MongoDB, use `monger.core/connect`: + +``` clojure +(require '[monger.core :as mg]) + +(let [conn (mg/connect)]) +``` + +or `monger.core/connect-via-uri`: + +``` clojure +(require '[monger.core :as mg]) + +(let [{:keys [conn db]} (mg/connect-via-uri "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")]) +``` + +To get a database reference, use `monger.core/get-db`, which now requires a connection +object: + +``` clojure +(require '[monger.core :as mg]) + +(let [conn (mg/connect) + db (mg/get-db conn "monger-test")]) +``` + ## Changes between 1.8.0-beta2 and 1.8.0