This repository has been archived by the owner on Apr 26, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 36
/
core.clj
122 lines (99 loc) · 3.41 KB
/
core.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
(ns commiteth.db.core
(:require
[cheshire.core :refer [generate-string parse-string]]
[clojure.java.jdbc :as jdbc]
[conman.core :as conman]
[commiteth.config :refer [env]]
[mount.core :refer [defstate]]
[migratus.core :as migratus]
[mpg.core :as mpg]
[hugsql.core]
[clojure.string :as str])
(:import org.postgresql.util.PGobject
java.sql.Array
clojure.lang.IPersistentMap
clojure.lang.IPersistentVector
[java.sql
BatchUpdateException
Date
Timestamp
PreparedStatement]))
(mpg/patch)
(defn start []
(let [db (env :jdbc-database-url)
migratus-config {:store :database
:migration-dir "migrations/"
:migration-table-name "schema_migrations"
:db db}]
(migratus/migrate migratus-config)
(conman/connect! {:jdbc-url db})
db))
(defstate ^:dynamic *db*
:start (start)
:stop (conman/disconnect! *db*))
(conman/bind-connection *db* "sql/queries.sql")
(defn to-date [^java.sql.Date sql-date]
(-> sql-date (.getTime) (java.util.Date.)))
(extend-protocol jdbc/IResultSetReadColumn
Date
(result-set-read-column [v _ _] (to-date v))
Timestamp
(result-set-read-column [v _ _] (to-date v))
Array
(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)
"citext" (str value)
value))))
(extend-type java.util.Date
jdbc/ISQLParameter
(set-parameter [v ^PreparedStatement stmt ^long idx]
(.setTimestamp stmt idx (Timestamp. (.getTime v)))))
(defn to-pg-json [value]
(doto (PGobject.)
(.setType "jsonb")
(.setValue (generate-string value))))
(extend-type clojure.lang.IPersistentVector
jdbc/ISQLParameter
(set-parameter [v ^java.sql.PreparedStatement stmt ^long idx]
(let [conn (.getConnection stmt)
meta (.getParameterMetaData stmt)
type-name (.getParameterTypeName meta idx)]
(if-let [elem-type (when (= (first type-name) \_) (str/join (rest type-name)))]
(.setObject stmt idx (.createArrayOf conn elem-type (to-array v)))
(.setObject stmt idx (to-pg-json v))))))
(extend-protocol jdbc/ISQLValue
IPersistentMap
(sql-value [value] (to-pg-json value))
IPersistentVector
(sql-value [value] (to-pg-json value)))
(defmacro with-tx [& body]
"Performs a set of queries in transaction."
`(conman/with-transaction [*db*]
~@body))
(defn update! [& args]
(apply jdbc/update! *db* args))
(defn convert-keys-to-lisp-case [res]
(->> res
(map #(vector (keyword (str/replace (name (first %1)) "_" "-"))
(second %1)))
(into {})))
(defn result-one-sql->lisp
[this result options]
(convert-keys-to-lisp-case (first result)))
(defn result-many-sql->lisp
[this result options]
(map convert-keys-to-lisp-case result))
(defmethod hugsql.core/hugsql-result-fn :1 [sym]
'commiteth.db.core/result-one-sql->lisp)
(defmethod hugsql.core/hugsql-result-fn :one [sym]
'commiteth.db.core/result-one-sql->lisp)
(defmethod hugsql.core/hugsql-result-fn :* [sym]
'commiteth.db.core/result-many-sql->lisp)
(defmethod hugsql.core/hugsql-result-fn :many [sym]
'commiteth.db.core/result-many-sql->lisp)