Implement most of monger.convertion.ConvertFromDBObject
This commit is contained in:
parent
b38b357f50
commit
3a431bf1e0
2 changed files with 108 additions and 6 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
(ns monger.convertion
|
(ns monger.convertion
|
||||||
(:import (com.mongodb DBObject BasicDBObject)
|
(:import (com.mongodb DBObject BasicDBObject BasicDBList)
|
||||||
(clojure.lang IPersistentMap Keyword)
|
(clojure.lang IPersistentMap Keyword)
|
||||||
(java.util List Map)))
|
(java.util List Map)))
|
||||||
|
|
||||||
|
|
@ -31,6 +31,42 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(declare associate-pairs)
|
||||||
(defprotocol ConvertFromDBObject
|
(defprotocol ConvertFromDBObject
|
||||||
(from-db-object [input] "Converts given DBObject instance to a piece of Clojure data"))
|
(from-db-object [input keywordize] "Converts given DBObject instance to a piece of Clojure data"))
|
||||||
|
|
||||||
|
(extend-protocol ConvertFromDBObject
|
||||||
|
nil
|
||||||
|
(from-db-object [input keywordize] input)
|
||||||
|
|
||||||
|
Object
|
||||||
|
(from-db-object [input keywordize] input)
|
||||||
|
|
||||||
|
Map
|
||||||
|
(from-db-object [#^Map input keywordize]
|
||||||
|
(associate-pairs (.entrySet input) keywordize))
|
||||||
|
|
||||||
|
List
|
||||||
|
(from-db-object [#^List input keywordize]
|
||||||
|
(vec (map #(from-db-object % keywordize) input)))
|
||||||
|
|
||||||
|
DBObject
|
||||||
|
(from-db-object [#^DBObject input keywordize]
|
||||||
|
;; DBObject provides .toMap, but the implementation in
|
||||||
|
;; subclass GridFSFile unhelpfully throws
|
||||||
|
;; UnsupportedOperationException
|
||||||
|
(associate-pairs (for [key-set (.keySet input)] [key-set (.get input key-set)])
|
||||||
|
keywordize)))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- associate-pairs [pairs keywordize]
|
||||||
|
;; Taking the keywordize test out of the fn reduces derefs
|
||||||
|
;; dramatically, which was the main barrier to matching pure-Java
|
||||||
|
;; performance for this marshalling
|
||||||
|
(reduce (if keywordize
|
||||||
|
(fn [m [#^String k v]]
|
||||||
|
(assoc m (keyword k) (from-db-object v true)))
|
||||||
|
(fn [m [#^String k v]]
|
||||||
|
(assoc m k (from-db-object v false))))
|
||||||
|
{} (reverse pairs)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
(ns monger.test.convertion
|
(ns monger.test.convertion
|
||||||
(:require [monger core collection convertion])
|
(:require [monger core collection convertion])
|
||||||
|
(:import (com.mongodb DBObject BasicDBObject BasicDBList) (java.util List ArrayList))
|
||||||
(:use [clojure.test]))
|
(:use [clojure.test]))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; DBObject to Clojure
|
||||||
|
;;
|
||||||
|
|
||||||
(deftest convert-nil-to-dbobject
|
(deftest convert-nil-to-dbobject
|
||||||
(let [input nil
|
(let [input nil
|
||||||
output (monger.convertion/to-db-object input)]
|
output (monger.convertion/to-db-object input)]
|
||||||
|
|
@ -32,6 +38,66 @@
|
||||||
|
|
||||||
|
|
||||||
(deftest convert-nested-map-to-dbobject
|
(deftest convert-nested-map-to-dbobject
|
||||||
(let [input { :int 1, :string "Mongo", :float 22.23, :map { :int 10, :string "Clojure", :float 11.9, :list '(1 "a" :b) } }
|
(let [input { :int 1, :string "Mongo", :float 22.23, :map { :int 10, :string "Clojure", :float 11.9, :list '(1 "a" :b), :map { :key "value" } } }
|
||||||
output (monger.convertion/to-db-object input)]
|
output (monger.convertion/to-db-object input)
|
||||||
(is (= 10 (.get (.get output "map") "int")))))
|
inner (.get output "map")]
|
||||||
|
(is (= 10 (.get inner "int")))
|
||||||
|
(is (= "Clojure" (.get inner "string")))
|
||||||
|
(is (= 11.9 (.get inner "float")))
|
||||||
|
(is (= '(1 "a" "b") (.get inner "list")))
|
||||||
|
(is (= { "key" "value" } (.get inner "map")))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Clojure to DBObject
|
||||||
|
;;
|
||||||
|
|
||||||
|
(deftest convert-nil-from-db-object
|
||||||
|
(is (nil? (monger.convertion/from-db-object nil false)))
|
||||||
|
(is (nil? (monger.convertion/from-db-object nil true))))
|
||||||
|
|
||||||
|
(deftest convert-integer-from-dbobject
|
||||||
|
(is (= 2 (monger.convertion/from-db-object 2 false)))
|
||||||
|
(is (= 2 (monger.convertion/from-db-object 2 true))))
|
||||||
|
|
||||||
|
(deftest convert-float-from-dbobject
|
||||||
|
(is (= 3.3 (monger.convertion/from-db-object 3.3 false)))
|
||||||
|
(is (= 3.3 (monger.convertion/from-db-object 3.3 true))))
|
||||||
|
|
||||||
|
(deftest convert-flat-db-object-to-map-without-keywordizing
|
||||||
|
(let [name "Michael"
|
||||||
|
age 26
|
||||||
|
input (doto (BasicDBObject.)
|
||||||
|
(.put "name" name)
|
||||||
|
(.put "age" age))
|
||||||
|
output (monger.convertion/from-db-object input false)]
|
||||||
|
(is (= (output { "name" name, "age" age })))
|
||||||
|
(is (= (output "name") name))
|
||||||
|
(is (nil? (output :name)))
|
||||||
|
(is (= (output "age") age))
|
||||||
|
(is (nil? (output "points")))
|
||||||
|
))
|
||||||
|
|
||||||
|
(deftest convert-flat-db-object-to-map-without-keywordizing
|
||||||
|
(let [name "Michael"
|
||||||
|
age 26
|
||||||
|
input (doto (BasicDBObject.)
|
||||||
|
(.put "name" name)
|
||||||
|
(.put "age" age))
|
||||||
|
output (monger.convertion/from-db-object input true)]
|
||||||
|
(is (= (output { :name name, :age age })))
|
||||||
|
(is (= (output :name) name))
|
||||||
|
(is (nil? (output "name")))
|
||||||
|
(is (= (output :age) age))
|
||||||
|
(is (nil? (output "points")))))
|
||||||
|
|
||||||
|
|
||||||
|
(deftest convert-flat-db-object-to-nested-map
|
||||||
|
(let [did "b38b357f5014a3250d813a16376ca2ff4837e8e1"
|
||||||
|
nested (doto (BasicDBObject.) (.put "int" 101) (.put "dblist" (doto (BasicDBList.) (.put "0" 0) (.put "1" 1))) (.put "list" (ArrayList. ["red" "green" "blue"])) (.put "nil" nil))
|
||||||
|
input (doto (BasicDBObject.)
|
||||||
|
(.put "_id" did)
|
||||||
|
(.put "nested" nested))]
|
||||||
|
(is (= (monger.convertion/from-db-object input false) { "_id" did, "nested" { "int" 101, "dblist" {"0" 0, "1" 1}, "list" ["red" "green" "blue"], "nil" nil } }))
|
||||||
|
(is (= (monger.convertion/from-db-object input true) { :_id did, :nested { :int 101, :dblist {:0 0, :1 1}, :list ["red" "green" "blue"], :nil nil } }))
|
||||||
|
))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue