hugsql

zendevil.eth 2021-11-30T18:03:17.012Z

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

zendevil.eth 2021-11-30T18:04:57.012300Z

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.eth 2021-11-30T18:06:02.013600Z

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

lukasz 2021-11-30T18:06:16.013900Z

you're not passing an :id field

zendevil.eth 2021-11-30T18:06:36.014300Z

@lukaszkorecki just fixzed

lukasz 2021-11-30T18:06:38.014400Z

ok, you're passing it now :-)

zendevil.eth 2021-11-30T18:07:08.015300Z

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

lukasz 2021-11-30T18:07:59.016100Z

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

lukasz 2021-11-30T18:09:21.017500Z

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

lukasz 2021-11-30T18:09:54.018100Z

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

lukasz 2021-11-30T18:10:31.018700Z

this thing:

hugsql/def-sqlvec-fns

zendevil.eth 2021-11-30T18:10:51.019100Z

are there docs for how to use this?

lukasz 2021-11-30T18:11:13.019300Z

yep, this section: https://www.hugsql.org/#using-def-sqlvec-fns

zendevil.eth 2021-11-30T18:14:51.020800Z

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

zendevil.eth 2021-11-30T18:15:00.021Z

but it works

zendevil.eth 2021-11-30T18:15:17.021400Z

as if in hugsql clojure it is false

lukasz 2021-11-30T18:15:24.021600Z

yeah, I misread that section sorry!

lukasz 2021-11-30T18:16:37.022400Z

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

lukasz 2021-11-30T18:17:08.022900Z

so yeah, the sqlvec approach might shed some light