Newer
Older
(ns document-storage.postgres.db
(:require
[conman.core :as conman]
[clojure.string :as str]
[hugsql.core :as hugsql]
[clojure.repl]
[clojure.java.jdbc :as jdbc]
[next.jdbc.prepare :as p]
[next.jdbc.result-set :as rs])
(:import
[org.postgresql.util PGobject]
[java.sql Timestamp]
[java.sql Date Timestamp PreparedStatement]))
(defn get-database-url [config]
(or (get config :jdbc-url)
(str "jdbc:postgresql://"
(get config :database-host) ":"
(get config :database-port) "/"
(get config :database-name) "?"
"user=" (get config :database-user) "&"
"password=" (get config :database-password))))
(defn connect! [config]
(let [connection (conman/connect! (merge config
{:jdbc-url (get-database-url config)}))]
{:connection connection
:queries (conman/bind-connection-map
connection
"sql/_ds_postgres.sql"
"sql/_ds_postgres_repository.sql"
"sql/_ds_postgres_storage.sql"

Bruno Burke
committed
"sql/_ds_postgres_cache.sql"
"sql/_ds_postgres_document_stats.sql")}))
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
(defn disconnect! [connection]
(.close connection)
(conman/disconnect! connection))
(defn kw->pgenum [kw]
(let [type (-> (namespace kw)
(str/replace "-" "_"))
value (name kw)]
(doto (PGobject.)
(.setType type)
(.setValue value))))
(defn pg-param-type
[^PreparedStatement s ^long idx]
(if-let [md (.getParameterMetaData s)]
(or (.getParameterTypeName md idx)
(throw (ex-info "We could not obtain the column type name" {:got s :meta md})))
(throw (ex-info "We could not obtain metadata from the prepared statement" {:got s}))))
(defn <-pgobject
"Transform PGobject containing `json` or `jsonb` value to Clojure
data."
[^org.postgresql.util.PGobject v]
(let [type (.getType v)
value (.getValue v)]
(cond
(str/includes? type "ds_encoding") (keyword "ds-encoding" value)
(str/includes? type "ds_type") (keyword "ds-type" value)
:else value)))
(extend-protocol rs/ReadableColumn
org.postgresql.util.PGobject
(read-column-by-label [^org.postgresql.util.PGobject v _]
(<-pgobject v))
(read-column-by-index [^org.postgresql.util.PGobject v _2 _3]
(<-pgobject v)))
(extend-protocol p/SettableParameter
clojure.lang.Keyword
(set-parameter [^clojure.lang.Keyword v ^PreparedStatement ps ^long i]
(.setObject ps i (kw->pgenum v)))
java.util.Date
(set-parameter [^java.util.Date v ^PreparedStatement stmt ^long idx]
(.setObject stmt idx
(case (pg-param-type stmt idx)
"date" (Date. (.getTime v))
"timestamp" (Timestamp. (.getTime v))
"timestamptz" (Timestamp. (.getTime v))))))