Support Rust expression like {x.y} in SQL strings

This commit is contained in:
gwenn 2023-08-20 10:35:26 +02:00
parent e8f73c93c4
commit b86d9321b5
4 changed files with 34 additions and 7 deletions

View File

@ -12,5 +12,5 @@ categories = ["database"]
proc-macro = true
[dependencies]
sqlite3-parser = { version = "0.9", default-features = false, features = ["YYNOERRORRECOVERY"] }
sqlite3-parser = { version = "0.10.0", default-features = false, features = ["YYNOERRORRECOVERY", "rust_variable"] }
fallible-iterator = "0.3"

View File

@ -58,11 +58,15 @@ fn try_bind(input: TokenStream) -> Result<TokenStream> {
let mut res = TokenStream::new();
for (i, name) in info.names.iter().enumerate() {
res.extend(Some(stmt.clone()));
let offset = match name.as_bytes()[0] {
b'$' | b'@' | b'#' | b':' => 1,
_ => 0, // captured identifier: {...}
};
res.extend(respan(
parse_ts(&format!(
".raw_bind_parameter({}, &{})?;",
i + 1,
&name[1..]
&name[offset..]
)),
call_site,
));

View File

@ -16,7 +16,30 @@ fn test_literal() -> Result {
let first_name = "El";
let last_name = "Barto";
let mut stmt = Stmt;
__bind!(stmt "SELECT $first_name, $last_name");
__bind!(stmt "SELECT $first_name, {last_name}");
Ok(())
}
#[test]
fn test_tuple() -> Result {
let names = ("El", "Barto");
let mut stmt = Stmt;
__bind!(stmt "SELECT {names.0}, {names.1}");
Ok(())
}
#[test]
fn test_struct() -> Result {
struct Person<'s> {
first_name: &'s str,
last_name: &'s str,
}
let p = Person {
first_name: "El",
last_name: "Barto",
};
let mut stmt = Stmt;
__bind!(stmt "SELECT {p.first_name}, {p.last_name}");
Ok(())
}

View File

@ -220,9 +220,9 @@ macro_rules! named_params {
/// Captured identifiers in SQL
///
/// * only SQLite `$x` / `@x` / `:x` syntax works (Rust `&x` syntax does not
/// work).
/// * SQLite `$x` / `@x` / `:x` syntax works (Rust `&x` syntax does not work).
/// * `$x.y` expression does not work.
/// * `{x}` and `{x.y}` work
///
/// # Example
///
@ -249,9 +249,9 @@ macro_rules! prepare_and_bind {
/// Captured identifiers in SQL
///
/// * only SQLite `$x` / `@x` / `:x` syntax works (Rust `&x` syntax does not
/// work).
/// * SQLite `$x` / `@x` / `:x` syntax works (Rust `&x` syntax does not work).
/// * `$x.y` expression does not work.
/// * `{x}` and `{x.y}` work
#[cfg(feature = "rusqlite-macros")]
#[cfg_attr(docsrs, doc(cfg(feature = "rusqlite-macros")))]
#[macro_export]