2

kormaを使用して非常に単純な API を作成しようとしています。

ユーザーは次のようにデータベースにクエリを実行できます。

localhost:8080/my_postgres_db/users.json?where[age]=50&limit=1  

現在、where 句を既存の構成可能なクエリに適用しようとすると、エラーが発生します。

clojure.lang.ArityException: Wrong number of args (2) passed to: core$where

問題のコード:

(defn- comp-query [q [func arg]]
  (let [sql-fn (ns-resolve 'korma.core (-> func name symbol))]
    (sql-fn q arg)))

(defn compose-query [table col]
  (reduce comp-query (select* table) col))

使用法:

 (def clauses {:where {:column1 10} :fields "a,b" :limit 10 :offset 500})
 (-> (compose-query table clauses) select)

where句を除いて、すべてが期待どおりに動作します。制限、オフセット、およびフィールドを任意の方法で組み合わせることができ、期待どおりの結果が得られます。マップにキーがある場合にのみ:where、エラーが発生します。

私はすべきではないことを試みていますか?これは悪いクロージュアですか?どんな助けでも大歓迎です。

注:私はこのSOの質問を読みました

編集lein repl同じ方法で手動でクエリを作成でき、機能します

(where (select* "my_table") {:a 5})

編集:compose-query関数をこれ に変更すると:

(defn compose-query [table col]
  ; remove where clause to process seperately
  (let [base (reduce comp-query (select* table) (dissoc col :where))]
    (if-let [where-clause (:where col)]
      (-> base (where where-clause))
      base)))

すべてが期待どおりに機能します。

4

3 に答える 3

3

ここでの問題はkorma.core/where、関数ではなく、特別に処理する必要があることです。関数として実装できず、次のようなことを正しく処理できない場合(where query (or (= :hits 1) (> :hits 5)))

于 2012-08-21T07:30:02.293 に答える
3

where*機能はそのまま使えますselect*。次のように句マップを作成するだけです。

(def clauses {:where* {:column1 10} :fields "a,b" :limit 10 :offset 500})
于 2012-08-21T09:34:47.210 に答える
1

ただの予感; いくつかのスレッド マクロを展開すると、それらが正しいかどうかを確認するのが少し難しくなります。

core> (macroexpand-1 '(-> (compose-query table clauses) select))
(select (compose-query table clauses))                                                                     
core> (macroexpand-1 '(-> func name symbol))
(clojure.core/-> (clojure.core/-> func name) symbol)                                                       
core> (macroexpand-1 '(clojure.core/-> func name))
(name func)

func を name に渡すのは疑わしいようです。

于 2012-08-21T00:14:27.470 に答える