Dasherize Korma Columns
A quick tip for the Korma SQL library for Clojure:
By default, Korma will return column names with underscores
(e.g. :this_kind
, unmodified from the database convention), while
Clojurists are likely more comfortable with :this-kind
of
dash-separated keyword. (Some people call this “kebab-case”
vs. “snake-case”). To wit:
(defentity locations
(belongs-to user))
(select locations)
; => ({:user_id 1, :latitude 30.02, :longitude -116.992})
We can convince Korma to automatically translate these names using
Korma’s own prepare
and transform
functions, which are given the
chance to mutate attribute names and values on the way to / from the
database, as Conan Cook points out in his
Tasty Korma Recipes post. But it gets a bit cumbersome to
inline this code in every entity definition.
Building on that idea, here’s single function you can drop in your
code and invoke in your defentity
forms to take care of the
translation:
(defn- normalize-keys
"Invoke in a `defentity` form to automatically translate between
dash-separated keywords and underscore-separated DB column names."
[ent]
(let [map-keys (fn [f m] (reduce-kv #(assoc %1 (f %2) %3) {} m))
underscore-kw (comp keyword #(clojure.string/replace % "-" "_") name)
dasherize-kw (comp keyword #(clojure.string/replace % "_" "-") name)]
(-> ent
(korma.core/prepare (partial map-keys underscore-kw))
(korma.core/transform (partial map-keys dasherize-kw)))))
If we now add that to our entity definition, the translation is cleanly handled:
(defentity locations
(belongs-to user)
(normalize-keys))
(select locations)
; => ({:user-id 1, :latitude 30.02, :longitude -116.992})