use anyhow::Result;
use sqll::{OpenOptions, Statements, TryFromSendStatementError, TypedStatement};
#[derive(Statements)]
#[sql(read_only)]
struct Read {
#[sql = "SELECT name, age FROM users ORDER BY age"]
all: TypedStatement<(), (String, i32)>,
}
#[derive(Statements)]
struct Write {
#[sql(statements)]
read: Read,
#[sql = "INSERT INTO users (name, age) VALUES (?, ?)"]
insert: TypedStatement<(String, i32), ()>,
}
fn setup() -> Result<sqll::Connection> {
let c = OpenOptions::new()
.no_mutex()
.read_write()
.create()
.open_in_memory()?;
c.execute("CREATE TABLE users (name TEXT, age INTEGER)")?;
Ok(c)
}
#[test]
fn end_to_end_execute_and_query() -> Result<()> {
let mut c = setup()?;
let mut w = Write::build(&mut c)?;
w.insert.execute(("Alice".to_string(), 25))?;
w.insert.execute(("Bob".to_string(), 35))?;
w.insert.execute(("Charlie".to_string(), 30))?;
let mut out = Vec::new();
let mut stmt = w.read.all.query()?;
while let Some(row) = stmt.next()? {
out.push(row);
}
assert_eq!(
out,
vec![
("Alice".to_string(), 25),
("Charlie".to_string(), 30),
("Bob".to_string(), 35),
]
);
Ok(())
}
fn select_one_send(c: &sqll::Connection) -> Result<sqll::SendStatement> {
let s = c.prepare("SELECT 1")?;
Ok(unsafe { s.into_send()? })
}
#[test]
fn try_from_wrong_bind_count() -> Result<()> {
let c = setup()?;
let send = select_one_send(&c)?;
let err = TypedStatement::<(i32,), (i32,)>::try_from(send)
.map(drop)
.unwrap_err();
assert_eq!(
err.to_string(),
"unexpected bind parameter count for statement: expected 1, got 0"
);
fn assert_error<E: core::error::Error>(_: &E) {}
assert_error::<TryFromSendStatementError>(&err);
Ok(())
}
#[test]
fn try_from_wrong_column_count() -> Result<()> {
let c = setup()?;
let send = select_one_send(&c)?;
let err = TypedStatement::<(), (i32, i32)>::try_from(send)
.map(drop)
.unwrap_err();
assert_eq!(
err.to_string(),
"unexpected column count for statement: expected 2, got 1"
);
Ok(())
}
#[test]
fn try_from_matching_counts() -> Result<()> {
let c = setup()?;
let send = select_one_send(&c)?;
let mut stmt = TypedStatement::<(), (i32,)>::try_from(send).unwrap();
assert_eq!(stmt.query()?.first()?, Some((1,)));
Ok(())
}