Skip to content

Instantly share code, notes, and snippets.

@djtango
Created July 19, 2019 12:19
Show Gist options
  • Save djtango/6d823001b643a65734ee0988a4f41f00 to your computer and use it in GitHub Desktop.
Save djtango/6d823001b643a65734ee0988a4f41f00 to your computer and use it in GitHub Desktop.
Convert Heroku DB URL into a JDBC url
(ns heroku-to-jdbc
"untested and brittle parser - use at your own peril")
(defn colon?
[_ c]
(= c \:))
(defn label-result [result label]
(update result 0 (fn [x] [label x])))
(defn flip-switch [pred]
(let [flipped? (atom false)]
(fn [& args]
(if-not @flipped?
(let [result (apply pred args)]
(if result
(do
(reset! flipped? true)
result)
result))
true))))
(defn split [s pred]
(let [pred* (flip-switch pred)]
(reduce (fn [[left right] c]
(if (pred* s c)
[left (str right c)]
[(str left c) right]))
["" ""]
s)))
(defn parse-jdbc-url [url]
(reduce (fn [[bits remaining-url] f]
(let [result (f remaining-url)]
[(conj bits (first result)) (second result)]))
[{} url]
[(fn hostname [url]
(label-result (split url colon?) :hostname))
(fn user [url]
(label-result (split (drop 3 url) colon?) :user))
(fn password [url]
(label-result (split (drop 1 url) (fn [_ c] (= c \@))) :password))
(fn pg-dns-hostname [url]
(label-result [(apply str (drop 1 url)) ""] :pg-dns-hostname))]))
(defn recombine-url [bits]
(let [{:keys [hostname user password pg-dns-hostname]} bits]
(str "jdbc:" hostname "ql://" pg-dns-hostname "?user=" user "&password=" password)))
(defn heroku->jdbc [url]
(recombine-url (first (parse-heroku-url url))))
(heroku->jdbc
"postgres://theuser:[email protected]:5432/pgdbname")
;;=> "jdbc:postgresql://ec1-23-456-789-012.us-west-9001.compute.amazonaws.com:5432/pgdbname?user=theuser&password=pa$$w0rd!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment