Dasherize HoneySQL Columns
Well…Korma didn’t work out… There are lots of
things to like about it, but I honestly can’t deal with the fact that
when you join on a belongs-to
relationship, it simply merges all of
columns into a single map (:id-2
?).
Anyway, I’ve moved on to HoneySQL for now. Which still features
the_kind_of_attribute_names
only a database could love. Let’s
kick that to the curb.
First off, the input piece:
(ns camdez.blog.dasherize-honeysql
(:require [honeysql.core :as sql]
[honeysql.helpers :refer :all]
[clojure.java.jdbc :as jdbc]
[clojure.string :as str))
(-> (insert-into :muscle-cars)
(values [{:name "1964 Pontiac GTO"
:engine-displacement 389}])
sql/format)
; => ["INSERT INTO muscle_cars (name, engine_displacement) VALUES (?, 389)" "1964 Pontiac GTO"]
Lo and behold! HoneySQL already has that one covered!
But if we fetch it back…
(jdbc/query db (-> (select :*)
(from :muscle-cars)
sql/format))
; => ({:id 1
; :name "1964 Pontiac GTO"
; :engine_displacement 389})
…ugly underscores.
The solution is that clojure.java.jdbc/query
allows us to pass a
function which is used to format the database column names on the way
out. The default is just to call clojure.string/lower-case
, so
we’ll write a new function to do our dashification:
(defn- format-column-name [col]
(-> col str/lower-case (str/replace "_" "-")))
Now let’s try again, passing our formatter:
(jdbc/query db (-> (select :*)
(from :muscle-cars)
sql/format)
:identifiers format-column-name)
; => ({:id 1
; :name "1964 Pontiac GTO"
; :engine-displacement 389})
Perfect! Finally, since we always want to do this, let’s write our own query function to encapsulate the common elements:
(defn query [db honey]
(jdbc/query db (sql/format honey) :identifiers format-column-name))
(query db (-> (select :*)
(from :muscle-cars)))
; => ({:id 1
; :name "1964 Pontiac GTO"
; :engine-displacement 389})
Ahhhhh… Delicious kebab-case… :)