use clap::{Parser, Subcommand}; use futures::TryStreamExt; use sqlx::postgres::PgPool; #[derive(Parser)] #[command(version, about, long_about = None)] #[command(propagate_version = true)] struct Cli { /// Name of the person to greet #[command(subcommand)] command: Commands, #[arg(short = 'u', long, global = true, env = "CLI_DB_URL")] db_url: Option, } #[derive(Subcommand)] enum Commands { /// Executes a query agains the database, it pass it directly to the underliying driver Query { /// Query to execute sql: String, }, } #[tokio::main] async fn main() { let cli = Cli::parse(); let url = cli.db_url.unwrap(); // You can check for the existence of subcommands, and if found use their // matches just as you would the top level cmd match &cli.command { Commands::Query { sql } => handle_query(url, sql).await.unwrap(), } } async fn handle_query(url: String, query: &String) -> Result<(), sqlx::Error> { let pool = PgPool::connect(url.as_str()).await?; let mut rows = sqlx::query("DELETE FROM table").fetch(&pool); while let Some(row) = rows.try_next().await? { // map the row into a user-defined domain type let email: &str = row.try_get("email")?; } return Ok(()); }