clojureql,open-global和with-results

Kev*_*vin 6 clojure clojureql

只是想了解clojureql的开放全局和结果的目的.我首先阅读了这篇概述:ClojureQL与clojure.contrib.sql相比如何?

我认为由于某种原因open-global将取代sql/with-connection,例如我认为这样可行:

(def db {...}) ; connection details omitted
(open-global db) 

(println (:name (first @(table :users))) 
Run Code Online (Sandbox Code Playgroud)

但这不起作用.看来我需要做开放全局并将执行查询包装在(sql/with-connection数据库)中,这让我感到惊讶(我认为open-global提供了一个默认的全局可访问连接).所以,既然情况似乎并非如此,我现在就想知道它到底是做什么的.

另外......结果与简单地用@执行查询有什么不同?因为似乎@(table:users)会给我一个序列,这个序列是执行查询的结果(不是那个with-results也是如此)?

Nic*_*roi 3

deref使用(@符号)与结果之间的区别非常微妙。基本上两者都做同样的事情,唯一的区别在于实际执行查询的时刻。两者实际上只是协议apply-on方法的包装Relation,以下是代码with-results:

(defmacro with-results
  [[results tble] & body]
  `(apply-on ~tble (fn [~results] ~@body)))
Run Code Online (Sandbox Code Playgroud)

对于deref:

(deref [this]
  (apply-on this doall))
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,deref与以下内容完全相同:

(with-results [res (table :users)] (doall res))
Run Code Online (Sandbox Code Playgroud)

如果您查看doall文档,您会发现它是一个用于遍历惰性序列以强制产生任何副作用的函数,结果是该序列将被完全评估,因此不再是惰性的,而是驻留在内存中。

因此,为了给您一个更实际的解释,usingderef在调用查询时实际执行查询,而 usingwith-results查询将延迟执行,即实际使用结果时。

至于open-global,你是对的,它确实应该打开一个全局可用的连接,当未使用 指定连接时,ClojureQL 将使用该连接wiht-connection。您观察到的行为可能是一个错误,因此我建议您在 IRC 频道或 Github 上的 ClojureQL 问题跟踪器上报告它。我有一段时间没有使用 ClojureQL,但看看代码,他们似乎已经过渡到使用clojure.java.jdbc而不是clojure.contrib.sql,那里可能出了问题。