Created
April 24, 2021 14:53
-
-
Save snorremd/b023d2b9f532ce2c8006467e25868f3c to your computer and use it in GitHub Desktop.
Clojure next.jdbc protocols for type/value conversion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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