-
-
Save mpenet/23fd53aabc853eb7e565 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns qbits.alia.codec | |
(:require [clojure.core.typed :as T]) | |
(:import | |
(java.nio ByteBuffer) | |
(com.datastax.driver.core | |
DataType | |
DataType$Name | |
ResultSet | |
Row))) | |
(defmacro make-decoders [row idx col-type & specs] | |
(reduce (fn [m [decoder-type# form#]] | |
(assoc m | |
decoder-type# | |
`(fn [~(vary-meta row assoc :tag "com.datastax.driver.core.Row") | |
~(vary-meta idx assoc :tag "java.lang.Integer") | |
~(vary-meta col-type assoc :tag "com.datastax.driver.core.DataType")] | |
~form#))) | |
{} | |
(partition 2 specs))) | |
(defn ^Class types-args->type | |
[^"[Lcom.datastax.driver.core.DataType;" type-args pred] | |
(.asJavaClass ^DataType (pred type-args))) | |
(def decoders | |
(make-decoders row idx col-type | |
DataType$Name/ASCII (.getString row idx) | |
DataType$Name/BIGINT (.getLong row idx) | |
DataType$Name/BLOB (.getBytes row idx) | |
DataType$Name/BOOLEAN (.getBool row idx) | |
DataType$Name/COUNTER (.getLong row idx) | |
DataType$Name/CUSTOM (.getBytesUnsafe row idx) | |
DataType$Name/DECIMAL (.getDecimal row idx) | |
DataType$Name/DOUBLE (.getDouble row idx) | |
DataType$Name/FLOAT (.getFloat row idx) | |
DataType$Name/INET (.getInet row idx) | |
DataType$Name/INT (.getInt row idx) | |
DataType$Name/TEXT (.getString row idx) | |
DataType$Name/TIMESTAMP (.getDate row idx) | |
DataType$Name/TIMEUUID (.getUUID row idx) | |
DataType$Name/UUID (.getUUID row idx) | |
DataType$Name/VARCHAR (.getString row idx) | |
DataType$Name/VARINT (.getVarint row idx) | |
DataType$Name/LIST (seq (.getList row idx (types-args->type (.getTypeArguments col-type) first))) | |
DataType$Name/SET (into #{} (.getSet row idx (types-args->type (.getTypeArguments col-type) first))) | |
DataType$Name/MAP (let [t (.getTypeArguments col-type)] | |
(into {} (.getMap row idx | |
(types-args->type t first) | |
(types-args->type t second)))))) | |
(defn decode | |
[^Row row ^Integer idx ^DataType col-type] | |
((decoders (.getName col-type)) row idx col-type)) | |
(T/ann encode [Any -> Any]) | |
;; only used for prepared statements | |
(T/defprotocol> PCodec | |
(encode [x] | |
"Encodes clj value into a valid cassandra value for prepared | |
statements (usefull for external libs such as joda time)")) | |
(T/tc-ignore | |
(extend-protocol PCodec | |
(Class/forName "[B") | |
(encode [x] (ByteBuffer/wrap x)) | |
Object | |
(encode [x] x) | |
nil | |
(encode [x] x))) | |
(defn result-set->maps | |
[^ResultSet result-set string-keys?] | |
(let [key-fn (if string-keys? identity keyword)] | |
(-> (map (fn [^Row row] | |
(let [cdef (.getColumnDefinitions row) | |
len (.size cdef)] | |
(loop [idx (int 0) | |
row-map (transient {})] | |
(if (= idx len) | |
(persistent! row-map) | |
(recur (unchecked-inc-int idx) | |
(assoc! row-map | |
(key-fn (.getName cdef idx)) | |
(decode row idx (.getType cdef idx)))))))) | |
result-set) | |
(vary-meta assoc :execution-info (.getExecutionInfo result-set))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
user=> (clojure.repl/pst)
ExceptionInfo Class not found: (Class/forName "[B") {:file "qbits/alia/codec.clj", :column 13, :line 68, :class (Class/forName "[B"), :ast {:name x__#0, :op :binding, :env {:line 68, :column 13, :internal-name "fn__3329", :file "qbits/alia/codec.clj", :once false, :context :expr, :ns qbits.alia.codec}, :o-tag (Class/forName "[B"), :variadic? false, :arg-id 0, :form x, :tag (Class/forName "[B"), :local :arg}}
clojure.core/ex-info (core.clj:4403)
clojure.tools.analyzer.passes.jvm.validate/validate (validate.clj:236)
clojure.tools.analyzer.jvm/run-passes/analyze--13492/fn--13493 (jvm.clj:416)
clojure.tools.analyzer.ast/walk (ast.clj:68)
clojure.tools.analyzer.ast/walk/walk--12055 (ast.clj:67)
clojure.core/mapv/fn--6311 (core.clj:6353)
clojure.lang.ArrayChunk.reduce (ArrayChunk.java:58)
clojure.core.protocols/fn--6093 (protocols.clj:98)
clojure.core.protocols/fn--6057/G--6052--6066 (protocols.clj:19)
clojure.core.protocols/seq-reduce (protocols.clj:31)
clojure.core.protocols/fn--6076 (protocols.clj:60)
clojure.core.protocols/fn--6031/G--6026--6044 (protocols.clj:13)
nil
user=>