sql

All things SQL and JDBC...
salokristian 2020-04-17T06:12:25.289Z

@vachichng I think go channels are best used with non-blocking libraries (which next.jdbc is not, and I don't know a Clojure SQL client that is) or for CPU-bound tasks, which this is not. https://eli.thegreenplace.net/2017/clojure-concurrency-and-blocking-with-coreasync/ is a great read on the subject.

1👍
Vachi 2020-04-17T07:49:20.289200Z

then maybe Pulsar? it's a Fiber library. http://docs.paralleluniverse.co/pulsar/

salokristian 2020-04-18T09:04:09.303500Z

Yeah, I think I'll look into it. It looks promising.

nikolavojicic 2020-04-22T18:22:07.323300Z

Use async/thread instead async/go for blocking operations. Channels work the same for both blocking and non-blocking operations (i.e. ! and !!). Core.async works great with next.jdbc.

Vachi 2020-04-17T07:49:20.289200Z

then maybe Pulsar? it's a Fiber library. http://docs.paralleluniverse.co/pulsar/

seancorfield 2020-04-17T16:05:16.292400Z

If you treat next.jdbc/plan as a producer for a channel of results, that's reasonable. Channel consumption will automatically create back pressure on reduce-over-`plan` as it streams the result set onto the channel. It's trickier if you want a way to terminate early (and return reduced) since you need a way to tell the reduce to stop but it will be (deliberately) blocked trying to put data on the channel.

jonpither 2020-04-17T16:09:13.294200Z

Howdy @seancorfield. Do you ever find yourself wanting a clojure keyword mapping from/to java.sql.Types? I.e. to map to/fro java.sql.Types/VARCHAR to :varchar

jonpither 2020-04-17T16:09:37.294700Z

Had a scan around next.jdbc and clojure.java.jdbc and couldn't see such a mapping

seancorfield 2020-04-17T16:12:26.296400Z

@jonpither I do run into situations where I have a keyword and want to store it as a string (via name usually) but not often enough that I'd want an automatic conversion: I'd rather have it fail in the cases where I didn't expect to get a keyword (and that has, indeed, uncovered several bugs for me in the past).

seancorfield 2020-04-17T16:13:23.297600Z

In general, I tend to find keywords in Clojure may get mapped to ENUM in SQL (MySQL) so having an explicit conversion is safer. Overall, I prefer explicit conversions to/from SQL than global implicit ones.

seancorfield 2020-04-17T16:13:59.298300Z

(I don't even leverage the next.jdbc.date-time auto-conversions from Java Time to SQL date/timestamp)

jonpither 2020-04-17T16:14:14.298500Z

thanks @seancorfield

2020-04-17T16:50:54.298600Z

I implemented https://www.bevuta.com/en/blog/using-postgresql-enums-in-clojure/ in next.jdbc , now trying to extract the defined enum types out of postgres so they are not hard-coded into the coercion code....

emccue 2020-04-17T20:18:26.299300Z

@salo.kristian Have you/are you using connection pooling yet?

emccue 2020-04-17T20:18:34.299600Z

Kinda obvious but I did some testing locally

emccue 2020-04-17T20:18:54.300Z

(time
  (doseq [_ (range 100)]
    (with-open [conn (jdbc/get-connection (jdbc/get-datasource db-spec))]
      (jdbc/execute! conn ["SELECT * FROM USERS"]))))
"Elapsed time: 7557.7078 msecs"
=> nil
(time
  (doseq [_ (range 100)]
    (with-open [conn (jdbc/get-connection datasource)]
      (jdbc/execute! conn ["SELECT * FROM USERS"]))))
"Elapsed time: 282.6531 msecs"
=> nil

emccue 2020-04-17T20:21:37.300300Z

(time
  (doseq [_ (range 10000)]
    (with-open [conn (jdbc/get-connection datasource)]
      (jdbc/execute! conn ["SELECT * FROM USERS"]))))
"Elapsed time: 2021.8485 msecs"

emccue 2020-04-17T20:21:56.300700Z

you might come pretty close to your perf requirements with just that

salokristian 2020-04-18T09:02:52.303100Z

I haven't yet done any tests, since I've mainly been familiarizing myself with the alternatives. However, I have a HikariCP connection pool already setup.

salokristian 2020-04-18T09:03:25.303300Z

How large a connection pool did you use for your tests? They look very promising.

salokristian 2020-04-20T06:05:03.304200Z

@emccue

emccue 2020-04-20T17:10:11.304400Z

just the default one, 10 active connections

emccue 2020-04-20T17:10:59.304600Z

(in my case at least)

seancorfield 2020-04-17T20:42:24.302Z

@emccue It never occurred to me to even ask that question -- good point! I just sort of assume that anyone who cares about performance is already making sure they use connection pooling and don't try to stand up a new connection for every query. 🙂