/
coerce.clj
91 lines (76 loc) · 2.57 KB
/
coerce.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
(ns clj-pg.coerce
(:require [cheshire.core :refer [generate-string parse-string]]
[clojure.java.jdbc :as jdbc]
[clj-time.coerce :as tc]
[clj-time.core :as t]
[clojure.tools.logging :as log]
[clojure.string :as str])
(:import clojure.lang.IPersistentMap
clojure.lang.IPersistentVector
(org.joda.time DateTime)
[java.sql
BatchUpdateException
Date
Timestamp
PreparedStatement]
[org.postgresql.jdbc PgArray]
org.postgresql.util.PGobject))
(defn- to-date [sql-time]
(tc/from-sql-time sql-time))
(defn- to-sql-date [clj-time]
(tc/to-sql-time clj-time))
(extend-protocol jdbc/IResultSetReadColumn
java.sql.Date
(result-set-read-column [v _ _] (to-date v))
java.sql.Timestamp
(result-set-read-column [v _ _] (to-date v)))
(extend-type java.util.Date
jdbc/ISQLParameter
(set-parameter [v ^PreparedStatement stmt idx]
(.setTimestamp stmt idx (java.sql.Timestamp. (.getTime v)))))
(defn parse-int-range [s]
(let [pair (-> (str/replace s #"\[|\]|\(|\)" "")
(str/split #","))]
(mapv read-string pair)))
(extend-protocol jdbc/IResultSetReadColumn
Date
(result-set-read-column [v _ _] (to-date v))
Timestamp
(result-set-read-column [v _ _] (to-date v))
PgArray
(result-set-read-column [v _ _] (vec (.getArray v)))
PGobject
(result-set-read-column [pgobj _metadata _index]
(let [type (.getType pgobj)
value (.getValue pgobj)]
(case type
"json" (parse-string value true)
"jsonb" (parse-string value true)
"int8range" (parse-int-range value)
"citext" (str value)
value))))
(extend-type java.util.Date
jdbc/ISQLParameter
(set-parameter [v ^PreparedStatement stmt idx]
(.setTimestamp stmt idx (Timestamp. (.getTime v)))))
(defn to-pg-json [value]
(doto (PGobject.)
(.setType "jsonb")
(.setValue (generate-string value))))
(defn to-pg-array
([conn value & [sql-type]]
(.createArrayOf conn (or sql-type "text") (into-array value)))
([value]
(log/warn "Create array without connection")
(str "{" (clojure.string/join "," (map #(str "\"" % "\"") value)) "}")))
(extend-protocol jdbc/ISQLValue
clojure.lang.Keyword
(sql-value [value] (name value))
org.joda.time.DateTime
(sql-value [value] (to-sql-date value))
java.util.Date
(sql-value [value] (java.sql.Timestamp. (.getTime value)))
IPersistentMap
(sql-value [value] (to-pg-json value))
IPersistentVector
(sql-value [value] (to-pg-array value)))