From 49a672946d75585cbb5361b3e6b8fa7c3996adb3 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 30 Mar 2013 00:29:28 +0400 Subject: [PATCH 01/14] 1.5.0 --- project.clj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/project.clj b/project.clj index 4c4340f..3a3a486 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject com.novemberain/monger "1.5.0-rc2-SNAPSHOT" +(defproject com.novemberain/monger "1.5.0" :description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included" :url "http://clojuremongodb.info" :min-lein-version "2.0.0" @@ -39,11 +39,11 @@ :1.6 {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]} :master {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]} :dev {:resource-paths ["test/resources"] - :dependencies [[clj-time "0.4.4" :exclusions [org.clojure/clojure]] + :dependencies [[clj-time "0.5.0" :exclusions [org.clojure/clojure]] [cheshire "5.0.2" :exclusions [org.clojure/clojure]] [org.clojure/tools.cli "0.2.1" :exclusions [org.clojure/clojure]] - [org.clojure/core.cache "0.6.1" :exclusions [org.clojure/clojure]] - [ring/ring-core "1.1.2"]] + [org.clojure/core.cache "0.6.2" :exclusions [org.clojure/clojure]] + [ring/ring-core "1.1.8"]] :plugins [[codox "0.6.4"]] :codox {:sources ["src/clojure"] :output-dir "doc/api" @@ -55,7 +55,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.4.2" :exclusions [org.clojure/clojure]]]}} + :dependencies [[clj-time "0.5.0" :exclusions [org.clojure/clojure]]]}} :aliases {"all" ["with-profile" "dev:dev,1.3:dev,1.4:dev,dj01x:dev,dj02x:dev,1.6"]} :repositories {"sonatype" {:url "http://oss.sonatype.org/content/repositories/releases" :snapshots false From aff15fdf9ab941e30a421b360deac782a2b1ab80 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 30 Mar 2013 00:31:48 +0400 Subject: [PATCH 02/14] Back to snapshot --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 3a3a486..1842a2f 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject com.novemberain/monger "1.5.0" +(defproject com.novemberain/monger "1.6.0-SNAPSHOT" :description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included" :url "http://clojuremongodb.info" :min-lein-version "2.0.0" From 9373550439d14baf009b876279c26fa0218ebb50 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 30 Mar 2013 00:32:20 +0400 Subject: [PATCH 03/14] Ignore all .lein-* files --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 376e79a..5449b79 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,7 @@ pom.xml *jar /lib/ /classes/ -.lein-failures -.lein-deps-sum +.lein-* TAGS checkouts/* doc/* From 51bb05593688d77e25581494d3ff563ad81c39a2 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 30 Mar 2013 00:32:30 +0400 Subject: [PATCH 04/14] Update README --- ChangeLog.md | 5 +++++ README.md | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index f71b995..745b76b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,8 @@ +## Changes between 1.5.0 and 1.6.0 + +No changes yet. + + ## Changes between 1.4.0 and 1.5.0 ### Full Text Search Support diff --git a/README.md b/README.md index 7b2e4b6..f537bed 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ definition to your `pom.xml`: With Leiningen: - [com.novemberain/monger "1.5.0-rc1"] + [com.novemberain/monger "1.5.0"] With Maven: @@ -60,7 +60,7 @@ With Maven: com.novemberain monger - 1.5.0-rc1 + 1.5.0 From 496325a417b1f413a3ff8b180b726d98241dc180 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Thu, 4 Apr 2013 23:44:56 +0400 Subject: [PATCH 05/14] Use clojure.core/array-map with ensure-index in all examples To preserve ordering which is important. References #50 --- src/clojure/monger/collection.clj | 5 +++-- test/monger/test/full_text_search_test.clj | 2 +- test/monger/test/indexing_test.clj | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/clojure/monger/collection.clj b/src/clojure/monger/collection.clj index 0b9a73a..ec2c98d 100644 --- a/src/clojure/monger/collection.clj +++ b/src/clojure/monger/collection.clj @@ -544,9 +544,10 @@ EXAMPLES ;; create a regular index - (monger.collection/ensure-index \"documents\" {\"language\" 1}) + ;; clojure.core/array-map produces an ordered map + (monger.collection/ensure-index \"documents\" (array-map \"language\" 1)) ;; create a unique index - (monger.collection/ensure-index \"pages\" {:url 1} {:unique true}) + (monger.collection/ensure-index \"pages\" (array-map :url 1) {:unique true}) " ([^String collection ^Map keys] (.ensureIndex (.getCollection monger.core/*mongodb-database* (name collection)) (as-field-selector keys))) diff --git a/test/monger/test/full_text_search_test.clj b/test/monger/test/full_text_search_test.clj index 5b61680..3af94c4 100644 --- a/test/monger/test/full_text_search_test.clj +++ b/test/monger/test/full_text_search_test.clj @@ -20,7 +20,7 @@ (deftest ^{:edge-features true :search true} test-basic-full-text-search-query (let [coll "docs"] - (mc/ensure-index coll {:subject "text" :content "text"}) + (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") diff --git a/test/monger/test/indexing_test.clj b/test/monger/test/indexing_test.clj index a40e79a..7753ef5 100644 --- a/test/monger/test/indexing_test.clj +++ b/test/monger/test/indexing_test.clj @@ -26,11 +26,11 @@ (mc/create-index collection ["language"]) (mc/drop-index collection "language_1") (is (nil? (second (mc/indexes-on collection)))) - (mc/ensure-index collection { "language" 1 } {:unique true}) + (mc/ensure-index collection (array-map "language" 1) {:unique true}) (is (= "language_1" (:name (second (mc/indexes-on collection))))) - (mc/ensure-index collection { "language" 1 }) - (mc/ensure-index collection { "language" 1 } { :unique true }) + (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 @@ -38,7 +38,7 @@ ttl 30 sleep 120] (mc/remove coll) - (mc/ensure-index coll {:created-at 1} {:expireAfterSeconds ttl}) + (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] From b7660bec6de0d71f95fcb3869957c19da0b600a5 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Thu, 4 Apr 2013 23:51:29 +0400 Subject: [PATCH 06/14] update copy year --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f537bed..e42860c 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,6 @@ on Github. ## License -Copyright (C) 2011-2012 Michael S. Klishin +Copyright (C) 2011-2013 Michael S. Klishin Distributed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html), the same as Clojure. From 9c529cd6c71ed38f158780943a65732673b8547d Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Thu, 4 Apr 2013 23:51:46 +0400 Subject: [PATCH 07/14] Double EPL/APL2 license --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e42860c..daf96da 100644 --- a/README.md +++ b/README.md @@ -134,4 +134,5 @@ on Github. Copyright (C) 2011-2013 Michael S. Klishin -Distributed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html), the same as Clojure. +Double licensed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html) (the same as Clojure) or +the [Apache Public License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). From 85d392b4c78469279aecdc0acbfb6d40d6db3ca6 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 7 Apr 2013 00:37:08 +0400 Subject: [PATCH 08/14] Add contributing.md --- CONTRIBUTING.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e50cc51 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,12 @@ +## Pre-requisites + +The project uses [Leiningen 2](https://leiningen.org) and requires MongoDB `2.4+` to be running +locally. Make +sure you have those two installed and then run tests against all supported Clojure versions using + + lein2 all test + +## Pull Requests + +Then create a branch and make your changes on it. Once you are done with your changes and all +tests pass, write a [good, detailed commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) submit a pull request on GitHub. From c001ab36103cae76c84d0e04bfe1aba7769947b6 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 7 Apr 2013 22:34:47 +0400 Subject: [PATCH 09/14] Minor README update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index daf96da..a9450c4 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ on Github. ## License -Copyright (C) 2011-2013 Michael S. Klishin +Copyright (C) 2011-2013 [Michael S. Klishin](http://twitter.com/michaelklishin) Double licensed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html) (the same as Clojure) or the [Apache Public License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). From bffb58cc1fc908b3f84ff2ad68e9be9cd8bbdaaf Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 14 Apr 2013 01:53:56 +0400 Subject: [PATCH 10/14] Introduce additional cache implementation that can use any database --- ChangeLog.md | 14 ++++++- src/clojure/monger/cache.clj | 65 +++++++++++++++++++++++++++++---- test/monger/test/cache_test.clj | 40 ++++++++++++++++++++ 3 files changed, 110 insertions(+), 9 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 745b76b..b35e50d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,18 @@ ## Changes between 1.5.0 and 1.6.0 -No changes yet. +### One More Cache Implementation + +`monger.cache/db-aware-monger-cache-factory` will return a MongoDB-backed `clojure.core.cache` +implementation that can use any database: + +``` clojure +(require '[monger.cache :as cache]) + +(let [db (mg/get-db "altcache") + coll "cache_entries" + c (db-aware-monger-cache-factory db coll)] + (comment "This cache instance will use the altcache DB")) +``` ## Changes between 1.4.0 and 1.5.0 diff --git a/src/clojure/monger/cache.clj b/src/clojure/monger/cache.clj index 6348bef..d74a804 100644 --- a/src/clojure/monger/cache.clj +++ b/src/clojure/monger/cache.clj @@ -4,9 +4,11 @@ :author "Michael S. Klishin"} monger.cache (:require [monger.collection :as mc] - [clojure.core.cache :as cache]) - (:use monger.conversion) - (:import clojure.core.cache.CacheProtocol)) + [clojure.core.cache :as cache] + [monger.conversion :as cnv]) + (:import clojure.core.cache.CacheProtocol + [com.mongodb DB DBObject WriteConcern] + java.util.Map)) ;; ;; Implementation @@ -15,6 +17,24 @@ (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 ;; @@ -24,11 +44,8 @@ (extend-protocol cache/CacheProtocol BasicMongerCache (lookup [c k] - (:value (mc/find-map-by-id (:collection c) k))) - #_ (lookup [c k not-found] - (if-let [doc (mc/find-map-by-id (:collection c) k)] - (:value doc) - not-found)) + (let [m (mc/find-map-by-id (:collection c) k)] + (:value m))) (has? [c k] (not (nil? (mc/find-by-id (get c :collection) k)))) (hit [this k] @@ -52,3 +69,35 @@ (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) + 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) + 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))) diff --git a/test/monger/test/cache_test.clj b/test/monger/test/cache_test.clj index 1834482..f8f564b 100644 --- a/test/monger/test/cache_test.clj +++ b/test/monger/test/cache_test.clj @@ -1,5 +1,6 @@ (ns monger.test.cache-test (:require [monger.test.helper :as helper] + [monger.core :as mg] [monger.collection :as mc]) (:use clojure.core.cache clojure.test monger.cache) (:import [clojure.core.cache BasicCache FIFOCache LRUCache TTLCache] @@ -121,3 +122,42 @@ "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-basic-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 d5b0e2c8be7506c63904d910865085e40e8e8596 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 14 Apr 2013 02:04:27 +0400 Subject: [PATCH 11/14] Correct change log --- ChangeLog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index b35e50d..c4e585a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,11 +6,12 @@ implementation that can use any database: ``` clojure +(require '[monger.core :as mg]) (require '[monger.cache :as cache]) (let [db (mg/get-db "altcache") coll "cache_entries" - c (db-aware-monger-cache-factory db coll)] + c (cache/db-aware-monger-cache-factory db coll)] (comment "This cache instance will use the altcache DB")) ``` From 0bd3ef12ab02ca41a2b6fd293ba6410c4fa938d1 Mon Sep 17 00:00:00 2001 From: Andy Fingerhut Date: Sat, 13 Apr 2013 16:18:22 -0700 Subject: [PATCH 12/14] Eliminate some reflection via adding type hints, and correcting one --- src/clojure/monger/ring/session_store.clj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clojure/monger/ring/session_store.clj b/src/clojure/monger/ring/session_store.clj index 0aa450e..8d830de 100644 --- a/src/clojure/monger/ring/session_store.clj +++ b/src/clojure/monger/ring/session_store.clj @@ -26,7 +26,7 @@ (defrecord ClojureReaderBasedMongoDBSessionStore [^String collection-name]) (defmethod print-dup java.util.Date - [^java.util.Date d ^java.io.OutputStream out] + [^java.util.Date d ^java.io.Writer out] (.write out (str "#=" `(java.util.Date. ~(.getYear d) @@ -37,7 +37,7 @@ ~(.getSeconds d))))) (defmethod print-dup org.bson.types.ObjectId - [oid out] + [oid ^java.io.Writer out] (.write out (str "#=" `(org.bson.types.ObjectId. ~(str oid))))) @@ -101,4 +101,4 @@ ([] (MongoDBSessionStore. default-session-store-collection)) ([^String s] - (MongoDBSessionStore. s))) \ No newline at end of file + (MongoDBSessionStore. s))) From f40161f035546096d6c6cc0ec25942ca0712731e Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Mon, 15 Apr 2013 03:40:18 +0400 Subject: [PATCH 13/14] 1.6.0-beta1 --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 1842a2f..cc2e8fe 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject com.novemberain/monger "1.6.0-SNAPSHOT" +(defproject com.novemberain/monger "1.6.0-beta1" :description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included" :url "http://clojuremongodb.info" :min-lein-version "2.0.0" From 0bee6bed9e51f43d2c6e74bb4235694a6f29bf2b Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Mon, 15 Apr 2013 03:41:13 +0400 Subject: [PATCH 14/14] Back to snapshot --- project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.clj b/project.clj index cc2e8fe..153b6f8 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject com.novemberain/monger "1.6.0-beta1" +(defproject com.novemberain/monger "1.6.0-beta2-SNAPSHOT" :description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included" :url "http://clojuremongodb.info" :min-lein-version "2.0.0"