How to avoid unresolved symbol with clj-kond when using hugSQL def-db-fns macro?
Asked Answered
R

1

13

I write Clojure using the VS Code Calva extension, which uses clj-kondo to perform static analysis of my code.

I'm using HugSQL to create Clojure functions from SQL queries and statements.

I'm aware that I could handle the database connection and the HugSQL integration with a library like conman, infact I used it in the past and I like it, but this time I wanted to keep things vanilla and talk to HugSQL myself.

HugSQL's def-db-fns macro takes a SQL file and creates Clojure functions based on the SQL queries and statements contained in that file.

My code below works, but clj-kondo complains that seed-mytable! is an unresolved symbol.

(ns my-app.db
  "This namespace represents the bridge between the database world and the clojure world."
  (:require [environ.core :refer [env]]
            [hugsql.core :as hugsql]
            [nano-id.core :refer [nano-id]]))

;; This create the function seed-mytable!, but clj-kondo doesn't (cannot?) know it.
(hugsql/def-db-fns "sql/mytable.sql")

;; The functions created by HugSQL can accept a db-spec, a connection, a connection pool,
;; or a transaction object. Let's keep it simple and use a db-spec for a SQLite database.
(def db-spec {:classname "org.sqlite.JDBC"
              :subprotocol "sqlite"
              :subname (env :database-subname)})

(defn db-seed
  "Populate the table with some fakes."
  []
  (let [fakes [[(nano-id) "First fake title" "First fake content"]
               [(nano-id) "Second fake title" "Second fake content"]]]

    ;; clj-kondo complains that seed-my-table! is an unresolved symbol
    (seed-mytable! db-spec {:fakes fakes})))

I understand why clj-kondo complains: seed-mytable! is not defined anywhere, it's "injected" in this namespace when calling the def-db-fns macro.

Is there a way to tell clj-kondo that after calling the hugsql/def-db-fns macro the symbol does indeed exist?

Probably it's not that useful, but this is the SQL file I'm loading with HugSQL.

-- :name seed-mytable!
-- :command :execute
-- :result :affected
-- :doc Seed the `mytable` table with some fakes.
INSERT INTO mytable (id, title, content)
VALUES :t*:fakes;
Replevin answered 11/5, 2020 at 10:32 Comment(1)
Of course I could add something like (defn seed-mytable! [db params] nil) and have that evaluated before (hugsql/def-db-fns "sql/mytable.sql"), so clj-kondo would stop complaining. But that doesn't seem like a good idea to me.Replevin
H
18

From the clj-kondo documentation:

Sometimes vars are introduced by executing macros, e.g. when using HugSQL's def-db-fns. You can suppress warnings about these vars by using declare. Example:

(ns hugsql-example
  (:require [hugsql.core :as hugsql]))

(declare select-things)

;; this will define a var #'select-things:
(hugsql/def-db-fns "select_things.sql")

(defn get-my-things [conn params]
  (select-things conn params))

If the amount of symbols introduced by HugSQL becomes too unwieldy, consider introducing a separate namespace in which HugSQL generates the vars: foo.db.hugsql. You can then refer to this namespace from foo.db with (require '[foo.db.hugsql :as sql]) (sql/insert! ...) and clj-kondo will not complain about this. If it does, you can add {:linters {:unresolved-var {:exclude [my-hugsql.functions-ns]}}} to your config.

Hirsutism answered 11/5, 2020 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.