clojureql, открытый-глобальный и с результатами - PullRequest
6 голосов
/ 24 августа 2011

Просто пытаюсь понять цель open-global и побочных результатов clojureql.Я начал с чтения этого обзора: Как ClojureQL сравнивается с clojure.contrib.sql?

Я думал, что по какой-то причине open-global заменит sql / with-connection, например, я думалэто будет работать:

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

(println (:name (first @(table :users))) 

Однако это не работает.Кажется, мне нужно как сделать open-global, так и обернуть исполняемый запрос в (sql / with-connection db), что меня как-то удивило (я думал, что open-global предоставил глобально доступное соединение по умолчанию).Так что, похоже, это не тот случай, и я теперь задаюсь вопросом, что именно он делает.

Кроме того ... чем отличаются результаты with от простого выполнения запроса с @?Потому что, кажется, @ (таблица: пользователи) оставит мне последовательность, которая является результатом выполнения запроса (не так ли это и с with-results)?

1 Ответ

3 голосов
/ 25 августа 2011

Разница между использованием deref (символ @) и результатами со-довольно тонкая. В основном оба делают одно и то же, единственное различие заключается в том, в какой момент запрос фактически выполняется. На самом деле оба являются обертками для метода apply-on протокола Relation, вот код для with-results:

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

А для deref:

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

Как видите, deref точно так же, как:

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

Если вы посмотрите документацию doall, вы увидите, что это функция, используемая для обхода ленивой последовательности, чтобы вызвать любой побочный эффект, в результате чего последовательность будет полностью оценена, и, следовательно, не будет ленивый, но находящийся в памяти.

Таким образом, чтобы дать вам более простое объяснение, использование deref фактически выполняет запрос в тот момент, когда он вызывается, тогда как with-results запрос будет выполняться лениво, то есть когда результат фактически потребляется.

Что касается open-global, вы были правы в этом, оно действительно должно открыть глобально доступное соединение, которое будет использоваться ClojureQL, если не указать одно с помощью wiht-connection. Поведение, которое вы наблюдаете, вероятно, является ошибкой, поэтому я предлагаю вам сообщить об этом на IRC-канале или на трекер проблем ClojureQL на Github. Некоторое время я не использовал ClojureQL, но, глядя на код, они, похоже, перешли на использование clojure.java.jdbc вместо clojure.contrib.sql, возможно, что-то там пошло не так.

...