Squiller¶
Squiller generates boilerplate code from annotated SQL queries.
Working with SQL is often tedious, especially in statically typed settings. You need to explicitly bind values to parameters, and extract the resulting values for every column with the right type. Squiller can generate this boilerplate code from a SQL file, based on annotations in comments.
Status¶
Squiller is a work in progress, beta quality at best. Basic code generation for the rust-sqlite
target works, other targets are experimental and incomplete.
Example¶
Given the following input:
-- Look up a user by username.
-- @query get_user_by_name(name: str) ->? User
select
id /* :i64 */,
name /* :str */,
email /* :str */
from
users
where
name = :name;
When targeting Rust and the sqlite
crate, Squiller would generate roughly1:
struct User {
id: i64,
name: String,
email: String,
}
/// Look up a user by username.
pub fn get_user_by_name(
tx: &mut Transaction,
name: &str
) -> Result<Option<User>> {
let mut statement = tx.prepare(
r#"
select
id,
name,
email
from
users
where
name = :name;
"#
)?;
statement.bind(1, name)?;
match statement.next()? {
State::Done => Ok(None),
State::Row => {
let result = User {
id: statement.read(0)?,
name: statement.read(1)?,
email: statement.read(2)?,
};
Ok(Some(result))
}
}
}
In reality the generated code is a bit more verbose for several reasons. There are more intermediate variables to make the code easier to generate. There is an additional call to
next
to avoid leaving statements in progress. And finally, we cache the prepared statement in a hash table, instead of preparing it every call. ↩