我试图使用Clojure+Korma运行一个简单的查询来提取记录的数量。这就是我要做的:
(defmacro number-of [ref & filter]
`(let [basetmp# (-> (kc/select* ~ref)
(kc/aggregate (count :*) :cnt))]
(if ~filter
(-> basetmp#
(kc/where ~filter))
basetmp#)))
然而,如果我尝试使用这个宏,我得到一个错误消息说:core$count
查询将完美地工作,如果在一个函数中执行,但有一些错误/缺失在宏中我找不到:(
谢谢,尼科
正如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""
更新:
从评论"计数到底代表什么?"-如果你意识到kc/aggregate
也是一个宏,并且参数是各种各样的"SQL聚合"DSL,那么你也可以扩展kc/aggregate
调用。你会发现在发动机里有一个函数,parse-aggregate
。clj,最终映射到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__))))