forked from pingles/clj-hector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
serialize.clj
147 lines (135 loc) · 6.31 KB
/
serialize.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
(ns ^{:author "Paul Ingles"
:description "Utilities for serializing and deserializing Clojure and Hector types."}
clj-hector.serialize
(:import [me.prettyprint.cassandra.serializers StringSerializer IntegerSerializer LongSerializer TypeInferringSerializer BytesArraySerializer SerializerTypeInferer UUIDSerializer BigIntegerSerializer BooleanSerializer DateSerializer ObjectSerializer AsciiSerializer ByteBufferSerializer FloatSerializer CharSerializer DoubleSerializer ShortSerializer CompositeSerializer DynamicCompositeSerializer]
[me.prettyprint.cassandra.model QueryResultImpl HColumnImpl ColumnSliceImpl RowImpl RowsImpl SuperRowImpl SuperRowsImpl HSuperColumnImpl CounterSliceImpl HCounterColumnImpl CounterSuperSliceImpl HCounterSuperColumnImpl CounterRowsImpl CounterRowImpl]
[me.prettyprint.hector.api.ddl KeyspaceDefinition ColumnFamilyDefinition ColumnDefinition]
[me.prettyprint.hector.api.beans AbstractComposite AbstractComposite$Component]
[me.prettyprint.hector.api Serializer]
[java.nio ByteBuffer]))
(def serializers {:integer (IntegerSerializer/get)
:string (StringSerializer/get)
:long (LongSerializer/get)
:bytes (BytesArraySerializer/get)
:uuid (UUIDSerializer/get)
:bigint (BigIntegerSerializer/get)
:bool (BooleanSerializer/get)
:date (DateSerializer/get)
:object (ObjectSerializer/get)
:ascii (AsciiSerializer/get)
:byte-buffer (ByteBufferSerializer/get)
:char (CharSerializer/get)
:double (DoubleSerializer/get)
:float (FloatSerializer/get)
:short (ShortSerializer/get)
:dynamic-composite (new DynamicCompositeSerializer)
:composite (new CompositeSerializer)
:type-inferring (TypeInferringSerializer/get)})
(defn serializer
"Returns an instance of the specified serializer.
Argument: either a) instance of Serializer.
b) a keyword for one of the supported serializers.
c) any object.
If an object is passed the relevant serializer will be determined by
Hector's SerializerTypeInferer. This can be useful when serializing
strings or other types where serializers can be determined automatically.
Supported serializers: :integer, :string, :long, :bytes, :uuid
:bigint, :bool, :date, :object, :ascii, :byte-buffer, :char, :double
:float, :short."
[x]
(cond (keyword? x) (x serializers)
(instance? Serializer x) x
:else (SerializerTypeInferer/getSerializer x)))
(defn- deserialize-composite
"Given a composite and a list of deserializers deserialize the
component values of the composite returning a vector of values.
Unfortunatly this is required due to a limition of the Composite
implementation in Hector. this isn't neccessary for
DynamicComposite."
[composite deserializers]
(vec
(map (fn [component deserializer]
(.fromByteBuffer (serializer deserializer) (.getBytes component)))
(.getComponents composite)
deserializers)))
(defprotocol ToClojure
(to-clojure [_ _] "Convert hector types to Clojure data structures."))
(defn partial>
"Like clojure.core/partial, but appends args to the end of
the argument list when f is applied."
[f & args]
(fn [& more] (apply f (concat more args))))
(extend-protocol ToClojure
ColumnDefinition
(to-clojure [c _] {:name (.getName c)
:index (.getIndexName c)
:index-type (.getIndexType c)
:validation-class (.getValidationClass c)})
ColumnFamilyDefinition
(to-clojure [c opts] {:name (.getName c)
:comment (.getComment c)
:column-type (.getColumnType c)
:comparator-type (.getComparatorType c)
:sub-comparator-type (.getSubComparatorType c)
:columns (map (partial> to-clojure opts) (.getColumnMetadata c))})
KeyspaceDefinition
(to-clojure [k opts] {(.getName k) {:strategy (.getStrategyClass k)
:replication (.getReplicationFactor k)
:column-families (map (partial> to-clojure opts) (.getCfDefs k))}})
CounterRowsImpl
(to-clojure [s opts]
(into (sorted-map) (partial> to-clojure opts) (iterator-seq (.iterator s))))
CounterRowImpl
(to-clojure [s opts]
{(.getKey s) (to-clojure (.getColumnSlice s) opts)})
SuperRowsImpl
(to-clojure [s opts]
(map (partial> to-clojure opts) (iterator-seq (.iterator s))))
SuperRowImpl
(to-clojure [s opts]
{(.getKey s) (map (partial> to-clojure opts) (seq (.. s getSuperSlice getSuperColumns)))})
HSuperColumnImpl
(to-clojure [s opts]
{(.getName s) (into (sorted-map) (map (partial> to-clojure opts) (.getColumns s)))})
RowsImpl
(to-clojure [s opts]
(map (partial> to-clojure opts) (iterator-seq (.iterator s))))
RowImpl
(to-clojure [s opts]
{(.getKey s) (to-clojure (.getColumnSlice s) opts)})
ColumnSliceImpl
(to-clojure [s opts]
(into (sorted-map) (for [c (.getColumns s)] (to-clojure c opts))))
HColumnImpl
(to-clojure [s opts]
{(let [col (.getName s)] (if (instance? AbstractComposite col)
(to-clojure col opts) col)) (.getValue s)})
HCounterColumnImpl
(to-clojure [s opts]
{(.getName s) (.getValue s)})
CounterSuperSliceImpl
(to-clojure [s opts]
(into (sorted-map) (map (partial> to-clojure opts) (.getSuperColumns s))))
HCounterSuperColumnImpl
(to-clojure [s opts]
{(.getName s) (into (sorted-map) (map (partial> to-clojure opts) (.getColumns s)))})
CounterSliceImpl
(to-clojure [s opts]
(into (sorted-map) (map (partial> to-clojure opts) (.getColumns s))))
Integer
(to-clojure [s _]
{:count s})
AbstractComposite
(to-clojure [s opts]
(let [serializers (:c-serializer opts)]
(if serializers
(deserialize-composite s serializers)
(vec (map #(.getValue %1) (.getComponents s))))))
QueryResultImpl
(to-clojure [s opts]
(with-meta
(if-let [result (.get s)]
(to-clojure result opts)
{})
{:exec_us (.getExecutionTimeMicro s)
:host (.getHostUsed s)})))