Reputation: 3638
How can one use named parameters when running queries using Yesql? For instance, given the following query
-- name: example
select * from table1 where col1=:value1 and col2=:value2
i'd like to use the following code:
(defquery q "query.sql")
(q db {:value1 "A" :value2 "B"})
Right now, Yesql treats the map as a single positional parameter.
Thanks!
Upvotes: 1
Views: 450
Reputation: 4653
The current version of Yesql - 0.4.0 - does not support easily this. The named parameters are only for documentation. You can see them if you do (doc q)
, but you can't use them to run the query. The author of Yesql has mentioned that they're planning exactly what you want for Yesql 0.5.
What I've done in the same situation is to just manually wrap the query into another function:
(defn q1 [db {:keys [value1 value2]}] (q db value1 value2))
It's a bit cumbersome, but it works.
It is possible to do this automatically even without improving Yesql, but... this is going to be a bit of a hack. You probably do not want to do this.
We can define a function similar to apply
that uses the query function's metadata to get the arguments in the right order from the map of named parameters.
(defn apply-with-arglist-fn [f arglist & args]
(let [nargs (butlast args)
kwargs (last args)]
(apply f (concat nargs (map #(get kwargs (keyword %))
(drop (count nargs) arglist))))))
;; Let's define a macro to make calling this a bit easier.
(defmacro apply-with-arglist [f & args]
"Applies fn f to the arguments in a map by matching them with f's
arglist. Works like apply, except that the last parameter should be
a map of keyword arguments. For example:
(defn f [a b c] ...)
(apply-with-arglist f 1 {:b 2 :c 3})
This is equivalent to calling (f 1 2 3)."
`(apply-with-arglist-fn ~f (first (:arglists (meta (var ~f)))) ~@args))
You can use this to run the query:
(apply-with-arglist q db {:value1 "A" :value2 "B"})
Really, though, there should be error handling and dealing with corner cases. A better approach would be to see if you can help the Yesql author to get Yesql 0.5 ready.
Upvotes: 3