2 minutes
HugSQLx - SQL queries turned into Rust functions
Clojure world is lucky to have HugSQL - brilliant library which makes daily work with SQLs a real pleasure. HugSql decouples queries from the code, so they do not interfere with content of .clj files and transforms (interns into a namespace) queries to plain clojure functions. Functions created this way are quite smart - underlaying magic connects to postgres, sqlite or whatever DB keeps your data (and is supported by JDBC) and runs defined query with provided function arguments.
Simple, yet so effective…
Can we have something simmilar in Rust?
Seems like we can.
Motivation
There are 3 main points where hugsqlx
really shines when dealing with SQLs:
- queries separated from the code - that brings proper formatting, syntax highlighting and better documentation (readable comments) out of the box. Your IDE is way happier to edit .sql file rather than SQLs inside rust source.
- named queries - query becomes easier to identify. Easier to indentify in a code, easier to deduce in logs when one looks for query that just blown up production.
- queries as documented functions - better way to understand author’s intention - what the query does in summary, what to expect in result?
Last but not least - queries turned into functions enable auto-completion and quick doc view out of the box (if you’re lucky enough with your LSP)
Solution (PoC)
HugSqlx is still kind of proof-of-concept, doing its best to materialize these ideas. Although crate is at its newborn stage, it should be quite functional. Standing on the shoulders of awesome SQLx it implements query-as-a-function concept for 3 major databases: postgres, sqlite and mysql. From a technical point of view, entire logic comes down to a simple (more or less..) code transformation which generates a static trait functions for your struct.
First results seem to be promising. I de-cluttered my sources, enjoy LSP happily providing me queries names via auto-completion. And, most importantly, I learned a lot about procedural macros.