> clj
Clojure 1.10.1
user=> (require '[next.jdbc :as jdbc])
nil
user=> (def db {:dbtype "h2" :dbname "example"})
#'user/db
user=> (def ds (jdbc/get-datasource db))
#'user/ds
user=> (jdbc/execute! ds ["
create table address (
id int auto_increment primary key,
name varchar(32),
email varchar(255)
)"])
[#:next.jdbc{:update-count 0}]
user=> (jdbc/execute! ds ["
insert into address(name,email)
values('John Smith','[email protected]')"])
[#:next.jdbc{:update-count 1}]
user=> (jdbc/execute! ds ["select * from address"])
[#:ADDRESS{:ID 1, :NAME "John Smith", :EMAIL "[email protected]"}]
That is an example REPL session to setup the library, setup a datasource, create a table, insert a row into the table, and then select from the table. The "user=>" part is the REPL command prompt. Essentially it's one statement for each SQL query executed, and 1 or 2 statements to setup the JDBC datasource. This is tight. (client/get "http://example.com/resources/3" {:accept :json :query-params {"q" "foo, bar"}})
With the response, you can examine response headers, the body, etc. (defn read-column [reader column-index]
(let [data (read-csv reader)]
(map #(nth % column-index) data)))
(defn sum-second-column [filename]
(with-open [reader (io/reader filename)] ; Read in the CSV file (streaming / lazily)
(->> (read-column reader 1) ; Convert to just the first column of data.
(drop 1) ; Drop the first row (the CSV header)
(map #(Double/parseDouble %)) ; convert each string in this column into double
(reduce + 0)))) ; sum the result
Because it's lazy, this code should work regardless of how large the CSV file.
Java upgraded to native threads, and then you could have N java threads bound to N kernel threads. This was way better, but had downsides: You're limited on how many threads you can spawn, you need a threadpool to help manage, and any long-running tasks could effectively deplete your thread-pool.
With Loom, now you have M green threads mapped to N kernel threads. These green threads are way cheaper to spawn, so you could have thousands (millions even?) of green threads. Blocking calls won't tie up a kernel thread. So if you have many long-running IO tasks, they aren't going to waste a kernel thread and have it sit around idle waiting on IO. This is similar to async libraries, but without the mental overhead. You should be able to just code synchronously and the JVM will take care of the rest.