diff --git a/.travis.yml b/.travis.yml index 58485c3..d9e866d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,14 @@ language: clojure -lein: lein2 +sudo: required +lein: lein before_script: - - ./bin/ci/install_mongodb.sh + - ./bin/ci/install_mongodb.sh - mongod --version - ./bin/ci/before_script.sh -script: lein2 do clean, javac, test +script: lein do clean, javac, test jdk: - - openjdk7 - - oraclejdk7 - oraclejdk8 + - oraclejdk9 services: - mongodb branches: diff --git a/README.md b/README.md index 5a8ac8a..7b717aa 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Monger, a modern Clojure MongoDB Driver - +[![Build Status](https://travis-ci.org/xingzhefeng/monger.svg?branch=master)](https://travis-ci.org/xingzhefeng/monger) Monger is an idiomatic [Clojure MongoDB driver](http://clojuremongodb.info) for a more civilized age. It has batteries included, offers powerful expressive query DSL, strives to support every MongoDB 2.0+ feature and has sane defaults. Monger is built from for modern Clojure versions and sits on top of the official MongoDB Java driver. @@ -24,7 +24,7 @@ wanted a client that will ## Project Maturity -Monger is not a young project: started in July 2011, it is over 3 +Monger is not a young project: started in July 2011, it is over 7 years old with active production use from week 1. diff --git a/bin/ci/install_mongodb.sh b/bin/ci/install_mongodb.sh index 74c671b..6645e06 100755 --- a/bin/ci/install_mongodb.sh +++ b/bin/ci/install_mongodb.sh @@ -1,7 +1,8 @@ #!/bin/sh -sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 -echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/3.0 main" | sudo tee /etc/apt/sources.list.d/mongodb-org.list +#sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 +sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com --recv 0C49F3730359A14518585931BC711F9BA15703C6 +echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org.list sudo apt-get update sudo apt-get install -y mongodb-org diff --git a/project.clj b/project.clj index f24d283..4c92739 100644 --- a/project.clj +++ b/project.clj @@ -5,7 +5,7 @@ :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.8.0"] - [org.mongodb/mongodb-driver "3.4.2"] + [org.mongodb/mongodb-driver "3.6.0-beta2"] [clojurewerkz/support "1.1.0"]] :test-selectors {:default (fn [m] (and (not (:performance m)) diff --git a/src/clojure/monger/collection.clj b/src/clojure/monger/collection.clj index 2c3addd..0a50e97 100644 --- a/src/clojure/monger/collection.clj +++ b/src/clojure/monger/collection.clj @@ -541,13 +541,17 @@ is supported, for specifying a limit on the execution time of the query in milliseconds. + :keywordize option that control if resulting map keys will be turned into keywords, default is true. + See http://docs.mongodb.org/manual/applications/aggregation/ to learn more." [^DB db ^String coll stages & opts] (let [coll (.getCollection db coll) agg-opts (build-aggregation-options opts) pipe (into-array-list (to-db-object stages)) - res (.aggregate coll pipe agg-opts)] - (map #(from-db-object % true) (iterator-seq res)))) + res (.aggregate coll pipe agg-opts) + {:keys [^Boolean keywordize] + :or {keywordize true}} opts] + (map #(from-db-object % keywordize) (iterator-seq res)))) (defn explain-aggregate "Returns the explain plan for an aggregation query. MongoDB 2.2+ only. diff --git a/src/clojure/monger/conversion.clj b/src/clojure/monger/conversion.clj index 8ed2c5f..02e97a5 100644 --- a/src/clojure/monger/conversion.clj +++ b/src/clojure/monger/conversion.clj @@ -46,7 +46,8 @@ (:import [com.mongodb DBObject BasicDBObject BasicDBList DBCursor] [clojure.lang IPersistentMap Named Keyword Ratio] [java.util List Map Date Set] - org.bson.types.ObjectId)) + org.bson.types.ObjectId + (org.bson.types Decimal128))) (defprotocol ConvertToDBObject (^com.mongodb.DBObject to-db-object [input] "Converts given piece of Clojure data to BasicDBObject MongoDB Java driver uses")) @@ -104,7 +105,6 @@ - (defprotocol ConvertFromDBObject (from-db-object [input keywordize] "Converts given DBObject instance to a piece of Clojure data")) @@ -115,6 +115,11 @@ Object (from-db-object [input keywordize] input) + Decimal128 + (from-db-object [^Decimal128 input keywordize] + (.bigDecimalValue input) + ) + List (from-db-object [^List input keywordize] (vec (map #(from-db-object % keywordize) input))) @@ -140,7 +145,6 @@ {} (.keySet input)))) - (defprotocol ConvertToObjectId (^org.bson.types.ObjectId to-object-id [input] "Instantiates ObjectId from input unless the input itself is an ObjectId instance. In that case, returns input as is.")) diff --git a/src/clojure/monger/operators.clj b/src/clojure/monger/operators.clj index 31cff42..ae4a828 100644 --- a/src/clojure/monger/operators.clj +++ b/src/clojure/monger/operators.clj @@ -320,3 +320,6 @@ ;; EXAMPLES: ;; (mgcol/update "libraries" { :language "Clojure", $isolated 1 } { $inc { :popularity 1 } } {:multi true}) (defoperator $isolated) + +(defoperator $count) +(defoperator $dateToString) diff --git a/test/monger/test/aggregation_framework_test.clj b/test/monger/test/aggregation_framework_test.clj index b243168..76abf9c 100644 --- a/test/monger/test/aggregation_framework_test.clj +++ b/test/monger/test/aggregation_framework_test.clj @@ -15,6 +15,27 @@ (use-fixtures :each purge-collections) + (deftest test-basic-single-stage-$project-aggregation-no-keywordize + (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 (->> + (mc/aggregate db coll [{$project {"state" 1 "quantity" 1}}] :keywordize false) + (map #(select-keys % ["state" "quantity"])) + (set))] + (is (= expected result))))) + (deftest test-basic-single-stage-$project-aggregation (let [batch [{:state "CA" :quantity 1 :price 199.00} {:state "NY" :quantity 2 :price 199.00} diff --git a/test/monger/test/conversion_test.clj b/test/monger/test/conversion_test.clj index c989574..7e3e49a 100644 --- a/test/monger/test/conversion_test.clj +++ b/test/monger/test/conversion_test.clj @@ -4,7 +4,8 @@ [monger.conversion :refer :all]) (:import [com.mongodb DBObject BasicDBObject BasicDBList] [java.util Date Calendar List ArrayList] - org.bson.types.ObjectId)) + org.bson.types.ObjectId + (org.bson.types Decimal128))) ;; @@ -101,6 +102,13 @@ (is (= 2 (from-db-object 2 false))) (is (= 2 (from-db-object 2 true)))) +(deftest convert-decimal-from-dbobject + (is (= 2.3M (from-db-object (Decimal128. 2.3M) false))) + (is (= 2.3M (from-db-object (Decimal128. 2.3M) true))) + (is (= 2.3M (from-db-object (Decimal128/parse "2.3") true))) + (is (not= 2.32M (from-db-object (Decimal128/parse "2.3") true))) + ) + (deftest convert-float-from-dbobject (is (= 3.3 (from-db-object 3.3 false))) (is (= 3.3 (from-db-object 3.3 true))))