ShapeyShifty/src/clj/shapey_shifty/db/core.clj

86 lines
2.5 KiB
Clojure

(ns shapey-shifty.db.core
(:require
[cheshire.core :refer [generate-string parse-string]]
[clojure.java.jdbc :as jdbc]
[clojure.tools.logging :as log]
[conman.core :as conman]
[java-time :as jt]
[java-time.pre-java8]
[shapey-shifty.config :refer [env]]
[mount.core :refer [defstate]])
(:import org.postgresql.util.PGobject
java.sql.Array
clojure.lang.IPersistentMap
clojure.lang.IPersistentVector
[java.sql
BatchUpdateException
PreparedStatement]))
(defstate ^:dynamic *db*
:start (if-let [jdbc-url (env :database-url)]
(conman/connect! {:jdbc-url jdbc-url})
(do
(log/warn "database connection URL was not found, please set :database-url in your config, e.g: dev-config.edn")
*db*))
:stop (conman/disconnect! *db*))
(conman/bind-connection *db* "sql/queries.sql")
(extend-protocol jdbc/IResultSetReadColumn
java.sql.Timestamp
(result-set-read-column [v _2 _3]
(.toLocalDateTime v))
java.sql.Date
(result-set-read-column [v _2 _3]
(.toLocalDate v))
java.sql.Time
(result-set-read-column [v _2 _3]
(.toLocalTime 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))))
(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) \_) (apply str (rest type-name)))]
(.setObject stmt idx (.createArrayOf conn elem-type (to-array v)))
(.setObject stmt idx (to-pg-json v))))))
(extend-protocol jdbc/ISQLValue
java.util.Date
(sql-value [v]
(java.sql.Timestamp. (.getTime v)))
java.time.LocalTime
(sql-value [v]
(jt/sql-time v))
java.time.LocalDate
(sql-value [v]
(jt/sql-date v))
java.time.LocalDateTime
(sql-value [v]
(jt/sql-timestamp v))
java.time.ZonedDateTime
(sql-value [v]
(jt/sql-timestamp v))
IPersistentMap
(sql-value [value] (to-pg-json value))
IPersistentVector
(sql-value [value] (to-pg-json value)))