# postgres-named-parameters `postgres-named-parameters` is a lightweight macro wrapper around the `postgres` crate which gives you the ergonomics of named parameters in your raw SQL queries. Under the hood, your named parameters are transformed into numbered parameters at compile time. ## Usage example ```rust,no_run use postgres_from_row::FromRow; use postgres_named_parameters::Query; // Use the postgres-from-row crate to decode each row returned // from a query into a struct. #[derive(FromRow, Debug)] struct Person { first_name: String, last_name: String, hobby: Option, alive: bool, } // Use a struct to define a query. The #[derive(Query)] will implement // query functions that handle passing in the parameters, and the named // parameters are converted to numbered parameters ($1, $2,...) at compile // time. #[derive(Query)] #[query( // Write the query using named parameters sql = " SELECT * FROM Person WHERE (first_name = @name OR last_name = @name) AND alive = @alive", // Specify what type each row returned from the query should decode to row = Person )] struct GetPeople<'a> { // Define the query's parameters alive: bool, name: &'a str, } fn main() -> Result<(), postgres::Error> { let connection_string = std::env::var("POSTGRES_CONNECTION_STRING") .unwrap_or("host=localhost user=postgres".to_owned()); let mut db = postgres::Client::connect(&connection_string, postgres::NoTls)?; // Execute the query let people: Vec = GetPeople { alive: true, name: "John", } .query_all(&mut db)?; // This roughly desugars to: // // let people: Vec = db.query( // "SELECT * // FROM Person // WHERE (first_name = $2 OR last_name = $2) // AND alive = $1", // &[&true, &"John"], // )? // .iter() // .map(Person::try_from_row) // .collect::,postgres::Error>>()?; // // Note that the #[derive(Query)] takes care of changing the SQL to use // numbered parameters (i.e. $1, $2) at compile time. println!("Found: {:?}", people); Ok(()) } ``` For a more thorough example (including bulk queries), see the example project folder in the [GitHub repository](https://github.com/jmoore34/postgres-named-parameters). # Features * Supports transactions * SQL transformation to numbered parameters happens at compile time * Mis-typing a named parameter (e.g. `@naame` instead of `@name`) produces a compile-time error # Attribution & Related Libraries This crate was inspired by the following libraries: * [couch/aykroyd](https://git.sr.ht/~couch/aykroyd) provided the idea of representing queries as structs * [nolanderc/rust-postgres-query](https://github.com/nolanderc/rust-postgres-query) and [solidsnack/rust-postgres-named-parameters](https://github.com/solidsnack/rust-postgres-named-parameters) were used as reference when creating the SQL parser * [3noch/postgres-simple-interpolate](https://github.com/3noch/postgresql-simple-interpolate) is the Haskell library that motivated creating an ergonomic way of dealing with SQL parameters in Rust