The latest and greatest for SQL databases seems to be HoneySQL and Yesql.
HoneySQL is a quite elegant DSL to generate SQL queries. There are rumours it can even modify the statements to be highly optimized, see the clojure-group thread "Current best-of-breed JDBC libraries?" from Feb 24 2015.
Niels van Klaveren says in the above-mentioned thread:
"Basically, it [HoneySQL] generates SQL scripts to relink foreign key references to clean up duplicates in a database. It takes a honeysql select query with (at least) a from
table, a group-by
and an order-by
clause as a base definition what are to be considered doubles, and in which order records should be preserved. In combination with JDBC metadata that query effectively gets rewritten to generate:
- A temporary replacement table
- Queries to unify unique indexes, to prevent clashes when foreign key references are updated
- Queries to update all foreign key references
- Delete statements to remove all duplicates
To create the best performing, but still database independent SQL, I had to extend honeysql with extra clauses like OVER
and PARTITION BY
. I wouldn't say it was a breeze, but seemed to work very well.
...
That cut down SQL to (sometimes) GB's of script to around a few 100 lines of SQL, and on one occasion, a runtime from 19 hours to 1.5 minutes."
Yesql, on the other hand, aim for total simplicity. It defines some functions to load parameterized .sql
-files.
It's webpage mentions the following "USPs":
- No syntactic surprises. Your database doesn't stick to the SQL standard - none of them do - but Yesql doesn't care. You will never spend time hunting for "the equivalent sexp syntax". You will never need to fall back to a
(raw-sql "some('funky'::SYNTAX)")
function.
- Better editor support. Your editor probably already has great SQL support. By keeping the SQL as SQL, you get to use it.
- Team interoperability. Your DBAs can read and write the SQL you use in your Clojure project.
- Easier performance tuning. Need to EXPLAIN that query plan? It's much easier when your query is ordinary SQL.
- Query reuse. Drop the same SQL files into other projects, because they're just plain ol' SQL. Share them as a submodule.