Clojureql, open-global and with results

Just trying to understand the purpose of clojureql open-global and with-results. I started reading this review: How is ClojureQL compared to clojure.contrib.sql?

For some reason, I thought that open-global would replace sql / with-connection, for example. I thought this would work:

(def db {...}) ; connection details omitted (open-global db) (println (:name (first @(table :users))) 

However, this does not work. It seems that I need both to execute open-global and complete the executable query in (sql / with-connection db), which surprised me (I thought open-global provides the global accessible connection by default). So it seems that this is not so, now it remains to me interesting what exactly he does.

Also ... how is it different from the results from just executing a query with @? Because it seems that @ (table: users) will leave me with a sequence that is the result of a query (isn't it the same with the results)?

+6
source share
1 answer

The difference between using deref ( @ symbol) and results is pretty subtle. Basically both do the same thing, the only difference is at what point the request is actually executed. Both of them are actually wrappers for the apply-on method of the Relation protocol, here is the code for with-results :

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

And for deref :

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

As you can see, deref exactly the same as:

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

If you look at the doall documentation, you will see that it is a function that is used to pass through a lazy sequence to force any side effect to be applied, as a result of which the sequence will be fully appreciated, lazy more, but staying in memory.

So, to give you a more detailed explanation, using deref , actually deref request at the time of its invocation, and when using with-results request will be executed lazily, that is, when the result is actually consumed.

Regarding open-global , you were right about this, it really should open a globally accessible connection that ClojureQL will use when not specified using wiht-connection . The behavior that you are observing is probably a mistake, so I suggest you report it on the IRC channel or the ClojureQL tracker on Github. I have not used ClojureQL for a while, but looking at the code, they seem to have switched to using clojure.java.jdbc instead of clojure.contrib.sql , something could go wrong there.

+3
source

Source: https://habr.com/ru/post/895770/


All Articles