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
|
||||
(:import (com.mongodb DBObject BasicDBObject)
|
||||
(:import (com.mongodb DBObject BasicDBObject BasicDBList)
|
||||
(clojure.lang IPersistentMap Keyword)
|
||||
(java.util List Map)))
|
||||
|
||||
|
|
@ -27,10 +27,46 @@
|
|||
|
||||
List
|
||||
(to-db-object [#^List input] (map to-db-object input)))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(declare associate-pairs)
|
||||
(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
|
||||
(:require [monger core collection convertion])
|
||||
(:import (com.mongodb DBObject BasicDBObject BasicDBList) (java.util List ArrayList))
|
||||
(:use [clojure.test]))
|
||||
|
||||
|
||||
;;
|
||||
;; DBObject to Clojure
|
||||
;;
|
||||
|
||||
(deftest convert-nil-to-dbobject
|
||||
(let [input nil
|
||||
output (monger.convertion/to-db-object input)]
|
||||
|
|
@ -32,6 +38,66 @@
|
|||
|
||||
|
||||
(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) } }
|
||||
output (monger.convertion/to-db-object input)]
|
||||
(is (= 10 (.get (.get output "map") "int")))))
|
||||
(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)
|
||||
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