Fork me on GitHub
#sql
<
2023-03-18
>
slipset12:03:35

So our usage of next.jdbc for querying looks something like this:

(map (partial post-read some-config) (next.jdbc/execute! ds q {:builder-fn }))
Which seems kind’a not so great, since we’re now looping over stuff twice.
(next.jdbc/execute! ds q {:builder-fn (comp (partial post-read some-config) )})
Would perhaps be better, because we’d then only loop over the result once. I’ve been skimming the docs, but didn’t quite realize that in theory, it should be as simple as the above, question is, is it, or should this be done some other way?

seancorfield18:03:33

Reduce over plan would be my approach. I use plan a lot.

slipset12:03:39

But how do you do that efficiently given that I want maps with unqualified kws back? Looking a bit into the code, I see that with execute we can pass a builder-fn which gets access to the result set metadata which has the column names, but for plan, I don’t have access to that metadata, which means I have to do the key operating on the result map one at a time? like:

(reduce (fn [a r] (conj a (medley/map-keys (comp keyword name) r))) [] (jdbc/plan ds ["select * from foo"])))
What am I missing?

seancorfield15:03:58

plan operates on the raw ResultSet which uses plain String labels for columns, and you can produce whatever data you want from the reducing function. The only "conversion" it does is from keywords to strings.

seancorfield15:03:33

(into [] (map #(select-keys % [:timezone]))
        (jdbc/plan ds ["select * from user where siteid = 45"]))  
produces a vector of maps with plain :timezone keys. You'll only get qualified keys out of plan if you perform a (slow) operation that inflates the wrapped ResultSet back into a full Clojure data structure -- which you're trying to avoid by using plan... that's kind of the whole point.

seancorfield15:03:12

So it depends on exactly what post-read does to the map-like object it is passed in...

seancorfield15:03:14

(you could pass the as-unqualified-maps builder to plan but then you're just hiding any inefficiencies you create by accidentally inflating the Java object into a full Clojure data structure so I would avoid that until you get your reducing function right)