I want to log all SQL strings executed by HugSQL. I looked through the docs, but couldn't find anything. Whats the recommended way?
问题:
回答1:
I solved it myself by digging around the hugsql source. I works similar to converting the result set of a generated function (https://github.com/layerware/hugsql/issues/21):
(defn log-sqlvec [sqlvec]
(log/info (->> sqlvec
(map #(clojure.string/replace (or % "") #"\n" ""))
(clojure.string/join " ; "))))
(defn log-command-fn [this db sqlvec options]
(log-sqlvec sqlvec)
(condp contains? (:command options)
#{:!} (hugsql.adapter/execute this db sqlvec options)
#{:? :<!} (hugsql.adapter/query this db sqlvec options)))
(defmethod hugsql.core/hugsql-command-fn :! [sym] `log-command-fn)
(defmethod hugsql.core/hugsql-command-fn :<! [sym] `log-command-fn)
(defmethod hugsql.core/hugsql-command-fn :? [sym] `log-command-fn)
回答2:
Per the HugSQL doc:
HugSQL generates a format internally known as sqlvec. The sqlvec format is a vector with an SQL string in the first position containing any
?
placeholders, followed by any number of parameter values to be applied to the SQL in positional order....
HugSQL provides the
hugsql.core/def-sqlvec-fns
macro to create functions returning the sqlvec format. The created functions have an-sqlvec
suffix by default, though this is configurable with the:fn-suffix
option. These functions are helpful during development/debugging and for the purpose of using the parameter-replacing functionality of HugSQL without using the built-in adapter database functions to execute queries.
So you could use the sqlvec
version of the functions colocated with where you call your HugSQL functions to log out the SQL that would be executed.
The doc actually provides the following example. Given that you've loaded HugSQL queries like so:
(ns princess-bride.db.characters
(:require [hugsql.core :as hugsql]))
(hugsql/def-db-fns "princess_bride/db/sql/characters.sql")
(hugsql/def-sqlvec-fns "princess_bride/db/sql/characters.sql")
And given the following function call:
(characters/characters-by-ids-specify-cols db
{:ids [1 2], :cols ["name" "specialty"]})
You can get at the generated sqlvec with the following:
(characters/characters-by-ids-specify-cols-sqlvec
{:ids [1 2], :cols ["name" "specialty"]})
Which would return something like:
["select name, specialty from characters
where id in (?,?)",1,2]