ポンザオが指摘したように、間違ったカウントを拾っています。
マクロ展開を見ると
(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
呼び出しも拡張できます。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__))))