korma / Korma

Tasty SQL for Clojure.
http://sqlkorma.com
1.48k stars 222 forks source link

hook into select query field values #402

Open reutsharabani opened 5 years ago

reutsharabani commented 5 years ago

Is it possible to transform select field values?

My use case is that my database handles specific types much better than others, so I want to force a type for field when querying against it in a reasonable manner (not forcing the user to cast specifically all the time).

Currently I use my own macros for this, but it seems very fragile and I was wondering if korma has facilities to make it easier for me.

The reason I need macros is that korma allows special keyword (like between) in select queries, so I need to transform the select parameters inside the where macro. Maybe there's a nicer way to do it... I'm open to any suggestion :)

Here are my macros:

(defmacro type-convert [k]
  `(get {:f1 bigdec
         :f2 double
         :f3 bigdec} ~k identity))

(defmacro transform-kv [k v]
  `(let [f# (if (some? ~v)
              (type-convert ~k)
              identity)]
     (let [vtype# (type ~v)]
       (if (vector? ~v)
         (let [pred# (first ~v)
               args# (second ~v)]
           (if (vector? args#)
             [~k [pred# (map f# args#)]]
             [~k [pred# (f# args#)]]))
         [~k (f# ~v)]))))

(defmacro transform-where [m]
  `(into {} (for [[k# v#] ~m] (transform-kv k# v#))))

(defmacro typed-where [q m]
  `(db/where ~q (transform-where ~m)))

And I use typed-where instead of where if I want to use the recommended field types.