Introducing Monglorious!
I've been burning the midnight oil on a new project, Monglorious. It's basically a MongoDB client library which executes strings in the syntax of MongoDB shell commands. This is in stark contrast to virtually every other MongoDB library which provide a domain-specific language (DSL) for building queries.
Why?
So why create yet another MongoDB library? DSLs are great, and they make it very easy to translate queries into code. But I had a particular use case which involves storing user-submitted queries in a database for future execution. So I need something analogous to SQL for MongoDB (which doesn't exist). Not the SQL syntax per se, but rather a canonical string representation of a MongoDB query.
How does it work?
String queries are parsed with a custom EBNF grammar which specifies the supported query syntax. I'm using a parsing library, Instaparse, which transforms the query string into an abstract syntax tree (AST). This representation can be easily translated into corresponding MongoDB library calls, which in turn are executed to return the results.
Monglorious is written in Clojure, which I've found to be a great match for language parsing and evaluation. And it's leveraging Monger for the underlying MongoDB calls.
What's next?
A Java interop layer is top priority, if only to expand the audience who might consider using it. Clojure itself provides some Java class generation, but I'll probably end up writing a custom wrapper for a more idiomatic feel.
Another feature I'm considering is the ability to provide post-parse, pre-execution function hooks. Basically, allowing the calling code to specify a function that gets called with the AST as an argument, before execution. The function could then inspect, modify, and/or reject the execution. Some of the uses I had in mind: restricting the full set of queries to a subset; enforcing permissions for different collections; aliasing collections or column names; even rewriting queries to some degree.
And finally, Monglorious currently only supports querying data. For completion, it would be nice to expand to insert/update/delete operations, although it's harder to imagine a compelling use case for these.
Check it out here: https://baumandm.github.io/monglorious/