#![allow(dead_code)] use tokio::task::JoinHandle; use tokio_rusqlite::{params, Connection, Result}; #[derive(Debug)] struct Person { id: i32, name: String, data: Option>, } #[tokio::main] async fn main() -> Result<()> { let conn = Connection::open_in_memory().await?; // Create table. conn.call(|conn| { conn.execute( "CREATE TABLE person ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, data BLOB )", [], ) .map_err(|e| e.into()) }) .await?; // Start tasks. let add_steven = add_steven_task(conn.clone()); let add_bob = add_bob_task(conn.clone()); // Wait for tasks to finish. add_steven.await.unwrap(); add_bob.await.unwrap(); // Select inserted data and collect results. let people = conn .call(|conn| { let mut stmt = conn.prepare("SELECT id, name, data FROM person")?; let people = stmt .query_map([], |row| { Ok(Person { id: row.get(0)?, name: row.get(1)?, data: row.get(2)?, }) })? .collect::, rusqlite::Error>>()?; Ok(people) }) .await?; for person in people { println!("Found person {person:?}"); } conn.close().await?; Ok(()) } fn add_steven_task(conn: Connection) -> JoinHandle<()> { tokio::spawn(async move { let steven = Person { id: 0, name: "Steven".to_string(), data: None, }; conn.call(move |conn| { conn.execute( "INSERT INTO person (name, data) VALUES (?1, ?2)", params![steven.name, steven.data], ) .map_err(|e| e.into()) }) .await .unwrap(); }) } fn add_bob_task(conn: Connection) -> JoinHandle<()> { tokio::spawn(async move { let bob = Person { id: 0, name: "Bob".to_string(), data: None, }; conn.call(move |conn| { conn.execute( "INSERT INTO person (name, data) VALUES (?1, ?2)", params![bob.name, bob.data], ) .map_err(|e| e.into()) }) .await .unwrap(); }) }