For already quite some time I prefer using Clojure REPL instead of any other tools for querying the databases. At work we have variety of the storage solutions available (Postgres, Aurora, Presto, Hive), and having a single consistent SQL read-only API to them is crucial for productivity. Additional benefit compared to the graphical tools available in the market is the ability of programmatic post-processing of the data using higher-level language. Being very data-oriented, Clojure comes really handy.

Recently was asking myself a question, if there’d be a way to share this experience with other people, not necessarily familiar with Clojure. I bundled together clojure.jdbc and rebel.readline, spiced it with a couple of nice macro commands into a single executable jar. I added the default configuration with most commonly used storages people use to inspect the databases on the staging environment and sent it over for the feedback among my colleagues. From 6 people to whom I presented this tool one found it pretty useful, and it wasn’t me. I consider that as a huge success. I also use it myself for running some large csv exports (thanks to reducible-query) , adhoc queries and data exploration.

A week ago there was Clojure meetup in Hamburg, where we were doing some adventofcode tasks together, was super nice to be there. A friend of mine in Saint-Petersburg wrote me last week that he is really into Clojure and engaged heavily with the community. Arne Brasseur started a series of the blog-posts called “Advent Of Parens”. Too many things that could turn you on in terms of some Clojure hacking.

So, quickly with the goals: I had an idea (ultimate query tool for multiple database solutions using Clojure REPL) and some sort of a prototype that worked so far quite good. I want to build a similar project, but make it more appropriate for the general audience and extendable for other database solutions. I also want to try out few things that are sound these days:

  • deps.edn
  • jdbc.next instead of clojure/java.jdbc

deps.edn

{:deps {org.clojure/clojure {:mvn/version "1.9.0"}
        com.taoensso/timbre {:mvn/version "4.10.0"}
        com.fzakaria/slf4j-timbre {:mvn/version "0.3.14"}
        seancorfield/next.jdbc {:mvn/version "1.0.12"}
        com.h2database/h2 {:mvn/version "1.4.199"}
        cheshire {:mvn/version "5.8.0"}
        clj-time {:mvn/version "0.14.4"}
        cyrus/config {:mvn/version "0.3.1"}
        com.bhauman/rebel-readline {:mvn/version "0.1.4"}
        org.clojure/data.csv {:mvn/version "0.1.4"}}}

Working with the project in emacs is relatively straightforward, all the environment started to work for me pretty smooth and I was already able to see the codebase working:

asciicast

Now it’s the time to package the whole and make it run as a standalone jar. That was a bit tricky, because I wasn’t familiar at all with the new uberjar ecosystem. Tried several approaches:

{:uberjar {:extra-deps {uberdeps {:mvn/version "0.1.6"}}
           :main-opts ["-m" "uberdeps.uberjar"]}
 :depstar {:extra-deps {seancorfield/depstar {:mvn/version "0.3.4"}}}
 :cambada {:extra-deps {luchiniatwork/cambada {:mvn/version "1.0.2"}}}}

Out of them only depstar fork by Sean Corfield worked out of the box - and, of course, this is the main reason for choosing the tool unfortunately and very positive experience I had so far working with next-jdbc

Nice that you’ve finished reading this one. Here’s the link to repository itself link