Yesql中的命名参数

Named parameters in Yesql

运行使用Yesql查询时如何使用命名参数?例如,给定以下查询

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

我想使用以下代码:

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

现在,Yesql 将地图视为单个位置参数。

谢谢!

当前版本的 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 也可以自动执行此操作,但是...这将有点 hack。 您可能不想这样做。

我们可以定义一个类似于 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)))) ~@args))

您可以使用它来 运行 查询:

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

不过,确实应该有错误处理和极端情况处理。更好的方法是看看你是否可以帮助 Yesql 作者准备好 Yesql 0.5。