Fork me on GitHub
#hugsql
<
2021-11-30
>
zendevil.eth18:11:17

hi guys, I don’t understand how hugsql is working in this case:

zendevil.eth18:11:57

I have the following:

-- :name update-user! :>! :1
-- :doc updates an existing user record, sets id=id to make hugsql syntax work
UPDATE users SET
id = id
--~ (when (contains? params :name) ",name = :name")
--~ (when (contains? params :email) ",email = :email")
--~ (when (contains? params :image) ",image = :image")
--~ (when (contains? params :pass) ",pass = :pass")
--~ (when (contains? params :reset-token) ",reset_token = :reset-token")
WHERE id = :id
RETURNING name, email, image, organization_id, role, reset_token

zendevil.eth18:11:02

And basically I’m doing the following:

(update-user! {:id "foobar" :name "foo" :email nil :image "kasdasfj"})
And somehow this works when there are the when clauses there but doesn’t when there aren’t

lukasz18:11:16

you're not passing an :id field

lukasz18:11:38

ok, you're passing it now :-)

zendevil.eth18:11:08

my question is (contains? {:foo nil} :foo) is true, so why is this working

lukasz18:11:59

in my own code I usually write the conditional part as --~ (when (:pass params) " pass = :pass") instead

lukasz18:11:21

and if a field needs to be nullfied then I'd add a dedicated query/function for that - I (and my team) found that relying on this behavior leads to weird bugs sometimes

lukasz18:11:54

lastly, you can use the -sqlvec stuff to see the final query that HugSQL generates

lukasz18:11:31

this thing:

hugsql/def-sqlvec-fns

zendevil.eth18:11:51

are there docs for how to use this?

zendevil.eth18:11:51

(contains? {:foo nil} :foo) is true

zendevil.eth18:11:17

as if in hugsql clojure it is false

lukasz18:11:24

yeah, I misread that section sorry!

lukasz18:11:37

I just grepped all our source code and we are using contains? in only one update statement, and according to tests it works as expected

lukasz18:11:08

so yeah, the sqlvec approach might shed some light