2011-08-24 13 views
6

clojureqlのオープングローバルとwith-resultsの目的を理解しようとしています。私はこの概要を読んで始めました:How does ClojureQL compare to clojure.contrib.sql?clojureql、open-globalとwith-results

私はopen-globalがsql/with-connectionを置き換えると考えました。私はこれがうまくいくと思った:

しかし、これは動作しません。私はオープングローバルを実行し、実行クエリを(SQL /接続DB)でラップする必要があるようです。私は驚いています(私はオープングローバルがデフォルトでグローバルにアクセス可能な接続を提供していると思っていました)。それで、そうではないように見えるので、私は今、それが何をしているのか疑問に思っています。

また、@でクエリを実行すると結果がどのように違うのですか?なぜなら、@(table:users)はクエリを実行した結果であるシーケンスを私に残してしまうからです(これはwith-resultsと同様です)。

答えて

3

@シンボル)とwith-resultsの使用の違いは非常に微妙です。基本的には両方とも同じことをしますが、唯一の違いはクエリが実際に実行される瞬間です。どちらも、実際にRelationプロトコルのapply-on方法のためだけのラッパーで、ここでwith-resultsのためのコードは次のとおりです。

(defmacro with-results 
    [[results tble] & body] 
    `(apply-on ~tble (fn [~results] [email protected]))) 

そしてderef用:

(deref [this] 
    (apply-on this doall)) 

あなたはderefは全く同じである見ることができるように:

(with-results [res (table :users)] (doall res)) 

doallのドキュメントを見ると、それは、シーケンスが完全に評価され、したがってもはや怠惰ではなくメモリに常駐するような、副作用を強制するために怠惰なシーケンスを歩き回るために使用される関数です。

derefを使用すると、実際に呼び出された時点でクエリが実行され、with-resultsを使用すると、結果が実際に消費されるときにクエリが遅延実行されます。

open-globalについては、あなたが正しく、実際にはwiht-connectionを使用しない場合にClojureQLで使用されるグローバルに利用可能な接続を開く必要があります。あなたが観察している動作はおそらくバグですので、IRCチャンネルまたはGithubのClojureQL issue trackerに報告することをお勧めします。私はしばらくのうちにClojureQLを使用していないが、コードを見て、彼らはclojure.contrib.sqlの代わりにclojure.java.jdbcを使用するように移行しているようだ、何かが間違っている可能性があります。

+0

もう少し詳しく、テストで私はwith-resultsを使ってオープングローバルの作品を使っているが、deref/@を使うと接続が必要だと思っていた。 )。私はircをチェックして、詳細な返答に感謝します! – Kevin

関連する問題