2015-03-18 3 views
1

Как использовать именованные параметры при выполнении запросов с помощью Yesql? Например, учитывая следующий запросИменованные параметры в Yesql

-- name: example 
select * from table1 where col1=:value1 and col2=:value2 

я хотел бы использовать следующий код:

(defquery q "query.sql") 
(q db {:value1 "A" :value2 "B"}) 

Прямо сейчас, Yesql рассматривает карту в виде одного позиционного параметра.

Спасибо!

ответ

3

Текущая версия Yesql - 0.4.0 - не поддерживает это легко. Именованные параметры предназначены только для документации. Вы можете увидеть их, если вы делаете (doc q), но вы не можете использовать их для запуска запроса. Автор Yesql упомянул, что they're planning exactly what you want for Yesql 0.5.

Что я сделал в той же ситуации, это просто вручную завернуть запрос в другую функцию:

(defn q1 [db {:keys [value1 value2]}] (q db value1 value2)) 

Это немного громоздким, но это работает.


Это можно сделать автоматически, даже без улучшения Yesql, но ... это будет немного рубить. Вы, вероятно, не хотите этого делать.

Мы можем определить функцию, аналогичную apply, которая использует метаданные функции запроса, чтобы получить аргументы в правильном порядке с карты именованных параметров.

(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)))) [email protected])) 

Вы можете использовать это, чтобы выполнить запрос:

(apply-with-arglist q db {:value1 "A" :value2 "B"}) 

Действительно, хотя, должно быть обработка ошибок и дело с угловыми случаев. Лучшим подходом было бы увидеть, можете ли вы помочь автору Yesql получить Yesql 0.5.

Смежные вопросы