Skip to content

Instantly share code, notes, and snippets.

@snorremd
Created April 24, 2021 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snorremd/b023d2b9f532ce2c8006467e25868f3c to your computer and use it in GitHub Desktop.
Save snorremd/b023d2b9f532ce2c8006467e25868f3c to your computer and use it in GitHub Desktop.
Clojure next.jdbc protocols for type/value conversion
;; Documents how to handle time and interval postgres types with next.jdbc library
;; See more docs here: https://cljdoc.org/d/com.github.seancorfield/next.jdbc/1.1.646/doc/getting-started/result-set-builders
(ns yourapp.db
(:require [next.jdbc.result-set :as rs]
[next.jdbc.prepare :as p]
[next.jdbc.date-time :refer [read-as-local]]
[tick.core :as tick])
(:import [org.postgresql.util PGInterval]
[java.sql PreparedStatement]))
(defn duration->pg-interval
"Takes a Dudration instance and converts it into a PGInterval
instance where the interval is created as a number of seconds."
[^java.time.Duration duration]
(doto (PGInterval.)
(.setSeconds (.getSeconds duration))))
(defn pg-interval->duration
"Takes a PGInterval instance and converts it into a Duration
instance. Ignore sub-second units."
[^org.postgresql.util.PGInterval interval]
(println interval)
(-> (tick/new-duration 0 :seconds)
(.plusSeconds (.getSeconds interval))
(.plusMinutes (.getMinutes interval))
(.plusHours (.getHours interval))
(.plusDays (.getDays interval))))
;; Call this so all dates are read as local dates
(read-as-local)
(extend-protocol p/SettableParameter
;; Convert durations to PGIntervals before inserting into db
java.time.Duration
(set-parameter [^java.time.Duration v ^PreparedStatement statement ^long index]
(.setObject statement index (duration->pg-interval v))))
(extend-protocol rs/ReadableColumn
;; Convert PGIntervals back to durations
org.postgresql.util.PGInterval
(read-column-by-label [^org.postgresql.util.PGInterval v _]
(pg-interval->duration v))
(read-column-by-index [^org.postgresql.util.PGInterval v _2 _3]
(pg-interval->duration v)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment