Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log sql statments/queries executed by HugSQL

I want to log all SQL strings executed by HugSQL. I looked through the docs, but couldn't find anything. Whats the recommended way?

like image 596
Frederik Claus Avatar asked Oct 31 '17 12:10

Frederik Claus


2 Answers

I solved it myself by digging around the hugsql source. It 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)
like image 162
Frederik Claus Avatar answered Nov 03 '22 07:11

Frederik Claus


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]
like image 29
alvinfrancis Avatar answered Nov 03 '22 07:11

alvinfrancis