我正在尝试使用Clojure + Korma运行一个简单的查询来提取记录数。 这就是我想要做的事情:
(defmacro number-of [ref & filter]
`(let [basetmp# (-> (kc/select* ~ref)
(kc/aggregate (count :*) :cnt))]
(if ~filter
(-> basetmp#
(kc/where ~filter))
basetmp#)))
但是,如果我尝试使用此宏,我会收到一条错误消息: args(2)的错误数量传递给:核心$ count
如果在函数中执行但是有错误/缺失,查询将完美地工作 在宏观上我无法发现:(
谢谢, 尼科
答案 0 :(得分:4)
正如ponzao所指出的那样,你错了。
看宏观扩张
(number-of 'foo) ;; expands to....
(clojure.core/let [basetmp__9167__auto__ (clojure.core/->
(korma.core/select* 'foo)
(korma.core/aggregate
(clojure.core/count :*)
:cnt))]
(if nil
(clojure.core/-> basetmp__9167__auto__ (korma.core/where nil))
basetmp__9167__auto__))
因此,您需要阻止宏的计数扩展为clojure.core/count
,您可以使用unquote / quote执行此操作:
(defmacro number-of [ref & filter]
`(let [basetmp# (-> (kc/select* ~ref)
(kc/aggregate (~'count :*) :cnt))]
(if ~filter
(-> basetmp#
(kc/where ~filter))
basetmp#)))
然后按预期扩展...
(clojure.core/let [basetmp__9137__auto__ (clojure.core/->
(korma.core/select* 'foo)
(korma.core/aggregate
(count :*)
:cnt))]
(if nil
(clojure.core/-> basetmp__9137__auto__ (korma.core/where nil))
basetmp__9137__auto__))
结果SQL看起来合理:
(kc/as-sql (number-of 'foo))
"SELECT COUNT(*) \"cnt\" FROM \"foo\""
<强>更新强>
从评论&#34;计数实际代表什么?&#34; - 如果您意识到kc/aggregate
也是一个宏,并且参数是一个&#39; SQL聚合&#39;各种DSL,那么你也可以扩展kc/aggregate
电话。你发现engine.clj中有一个函数parse-aggregate
,它最终映射到korma.sql.fn/agg-count
:
(clojure.core/let [q__2640__auto__ (kc/select* 'foo)]
(korma.sql.engine/bind-query
q__2640__auto__
(clojure.core/let [res__2641__auto__ (korma.core/fields
q__2640__auto__
[(clojure.core/->
q__2640__auto__
(korma.sql.fns/agg-count
:*))
:cnt])]
(if nil
(korma.core/group res__2641__auto__ nil)
res__2641__auto__))))