use std::convert::Infallible; use std::time::Duration; use sqlstr::{expr, ArgumentBuffer, SqlCommand}; use sqlx::postgres::PgArguments; use sqlx::{Arguments, Encode, Postgres, Type}; #[derive(Default)] struct PostgresArg { arg: PgArguments, count: u32, } impl ArgumentBuffer for PostgresArg where T: for<'q> Encode<'q, Postgres> + Type + Send, { type Error = Infallible; fn push(&mut self, value: T) -> Result<(), Self::Error> { self.count += 1; self.arg.add(value); Ok(()) } fn count(&self) -> u32 { self.count } } const DEFAULT_DATABASE_URL: &str = "postgres://root:root@localhost:5432/sqlstr_example"; fn main() -> Result<(), Box> { use sqlx::postgres::PgPoolOptions; use sqlx::Row; use tokio::runtime; let database_url: String = match std::env::args().nth(1) { None => DEFAULT_DATABASE_URL.into(), Some(arg) => arg .as_str() .strip_prefix("--database-url=") .unwrap_or(DEFAULT_DATABASE_URL) .into(), }; let rt = runtime::Builder::new_current_thread() .enable_io() .enable_time() .build()?; let query = rt.block_on(async { println!("connecting to database at '{}'", database_url); let pool = PgPoolOptions::new() .max_connections(1) .acquire_timeout(Duration::from_secs(3)) .connect(&database_url) .await .expect("connect to database"); println!("database connected!"); let query = make_sql_command().expect("create an SQL command as an infallible operation"); println!("executing query '{}'", query.as_command()); sqlx::query_with(&query.command, query.arguments.arg) .fetch_one(&pool) .await .expect("execute the SQL command in the connected database") }); println!("query returned!\nextracting values from the query result"); let num: i32 = query.get(0); let list: Vec = query.get(1); let boolean: bool = query.get(2); let strr: &str = query.get(3); println!("asserting returned values ..."); assert_eq!(num, -1); assert_eq!(list, vec!["array", "of", "str"]); assert!(!boolean); assert_eq!(strr, "sqlstr"); println!("all values are correct, exiting!"); Ok(()) } fn make_sql_command() -> Result, Infallible> { let mut sql: SqlCommand = SqlCommand::default(); expr::select(&mut sql); expr::separator(&mut sql); sql.push_value(-1_i32)?; expr::item_separator(&mut sql); sql.push_value(["array", "of", "str"])?; expr::item_separator(&mut sql); sql.push_value(false)?; expr::item_separator(&mut sql); sql.push_value("sqlstr")?; Ok(sql) }