From 3a948667d5d64597c483eb0231f840e8aaf37e46 Mon Sep 17 00:00:00 2001 From: "Michael S. Klishin" Date: Thu, 14 Jun 2012 19:28:40 +0400 Subject: [PATCH] Fight Java with Java Make our own version of DBRef that is exactly like the original but has one extra constructor and implements clojure.lang.IDeref so it is possible to @dereference such refs. This is only one small step in a proper, Clojuric, easy to use DBRef support. We may tack more Monger-specific extensions to our DBRef implementation later. As sang by Jetallica: Do unto others as they have done unto you but what in the hell is this world coming to? Blow the universe into nothingness nuclear warfare shall lay us to rest Fight Java with Java ending is near fight Java with Java bursting with fear --- .travis.yml | 2 +- project.clj | 1 + src/clojure/monger/conversion.clj | 8 ++++ src/java/com/novemberain/monger/DBRef.java | 44 ++++++++++++++++++++++ test/monger/test/inserting_test.clj | 6 ++- 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 src/java/com/novemberain/monger/DBRef.java diff --git a/.travis.yml b/.travis.yml index 287dd85..ff83892 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: clojure lein: lein2 before_script: - ./bin/ci/before_script.sh -script: lein2 ci test +script: lein2 javac && lein2 all test jdk: - openjdk6 - openjdk7 diff --git a/project.clj b/project.clj index 83f5998..9f4b34e 100644 --- a/project.clj +++ b/project.clj @@ -21,6 +21,7 @@ :all (constantly true)} :source-paths ["src/clojure"] :java-source-paths ["src/java"] + :javac-options ["-target" "1.6" "-source" "1.6"] :codox {:exclude [monger.internal.pagination]} :mailing-list {:name "clojure-monger" :archive "https://groups.google.com/group/clojure-mongodb" diff --git a/src/clojure/monger/conversion.clj b/src/clojure/monger/conversion.clj index a036c31..5faa1da 100644 --- a/src/clojure/monger/conversion.clj +++ b/src/clojure/monger/conversion.clj @@ -69,6 +69,10 @@ DBObject (to-db-object [^DBObject input] input) + com.novemberain.monger.DBRef + (to-db-object [^com.novemberain.monger.DBRef dbref] + dbref) + Object (to-db-object [input] input)) @@ -99,6 +103,10 @@ (from-db-object [^BasicDBList input keywordize] (vec (map #(from-db-object % keywordize) input))) + com.mongodb.DBRef + (from-db-object [^com.novemberain.monger.DBRef input keywordize] + (com.novemberain.monger.DBRef. input)) + DBObject (from-db-object [^DBObject input keywordize] ;; DBObject provides .toMap, but the implementation in diff --git a/src/java/com/novemberain/monger/DBRef.java b/src/java/com/novemberain/monger/DBRef.java new file mode 100644 index 0000000..4b7006f --- /dev/null +++ b/src/java/com/novemberain/monger/DBRef.java @@ -0,0 +1,44 @@ +package com.novemberain.monger; + +import clojure.lang.IDeref; +import com.mongodb.DB; +import com.mongodb.DBObject; +import org.bson.BSONObject; + +/** + * Exactly as com.mongodb.DBRef but also implements Clojure IDefer for @dereferencing + */ +public class DBRef extends com.mongodb.DBRef implements IDeref { + + /** + * Creates a DBRef + * @param db the database + * @param o a BSON object representing the reference + */ + public DBRef(DB db, BSONObject o) { + super(db , o.get("$ref").toString(), o.get("$id")); + } + + /** + * Creates a DBRef + * @param db the database + * @param ns the namespace where the object is stored + * @param id the object id + */ + public DBRef(DB db, String ns, Object id) { + super(db, ns, id); + } + + /** + * Creates a DBRef from a com.mongodb.DBRef instance. + * @param source The original reference MongoDB Java driver uses + */ + public DBRef(com.mongodb.DBRef source) { + this(source.getDB(), source.getRef(), source.getId()); + } + + @Override + public DBObject deref() { + return this.fetch(); + } +} diff --git a/test/monger/test/inserting_test.clj b/test/monger/test/inserting_test.clj index f3c6998..1c600a5 100644 --- a/test/monger/test/inserting_test.clj +++ b/test/monger/test/inserting_test.clj @@ -95,8 +95,10 @@ 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"})] - (is (= dbref (:owner fetched)))))) + (let [fetched (mc/find-one-as-map coll1 {:type "pentagon"}) + fo (:owner fetched)] + (is (= {:_id oid :name "Joe"} (from-db-object @fo true))) + (is (= dbref fo))))) ;;