babashka / babashka-sql-pods

Babashka pods for SQL databases
Eclipse Public License 1.0
85 stars 17 forks source link

Can't use with-open on postgres database #60

Closed lunik1 closed 8 months ago

lunik1 commented 10 months ago

version

babashka v1.3.186

postgresql 0.1.0

platform

linux x86_64

problem

When using with-open to manage a connection to a postgres database I get this error at the end of the block:

----- Error --------------------------------------------------------------------
Type:     java.lang.NoSuchFieldException
Message:  close

repro

#!/usr/bin/env bb

(require '[babashka.pods :as pods]
         '[babashka.deps :as deps])

(pods/load-pod 'org.babashka/postgresql "0.1.0")

(require '[pod.babashka.postgresql :as pg])

(def db [ ... ])

(with-open [conn (pg/get-connection db)]
  (println "Hello, world!"))

Supply your own postgres db :)

expected behavior

Connection should be closed at end of with-open block

additional

A quick macro I whipped up as a workaround

(defmacro with-conn
  [binding & body]
  (let [rtn (gensym 'rtn)]
    `(let ~(into [] (concat binding [rtn `(do ~@body)]))
       (pg/close-connection ~(first binding))
       ~rtn)))
lunik1 commented 10 months ago

I'm taking this usage of with-open from next-jdbc, not sure if it is the intended behaviour for this pod.

borkdude commented 10 months ago

Due to the nature of pods this won't be supported. I think your macro looks good, but I recommend calling pg/close-connection in a finally block in case an exception happens in the body. This is also what the with-open macro itself does.

Btw I didn't understand this concrete example:

(with-open [pg/get-connection db]
  (println "Hello, world!"))

The left-hand symbol in with-open should be a simple symbol, not a namespaced symbol.

lunik1 commented 10 months ago

Ah it's the end of the week and my brain is failing me, fixed. And thanks for the finally tip.

lunik1 commented 10 months ago
(defmacro with-conn
  [binding & body]
  `(let ~binding
     (try
       ~@body
       (finally (pg/close-connection ~(first binding))))))

try/finally is much cleaner