postgres-named-parameters 0.1.0

A lightweight macro wrapper around the `postgres` crate which gives you the ergonomics of named parameters in your raw SQL queries
Documentation
# 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<String>,
    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<Person> = GetPeople {
        alive: true,
        name: "John",
    }
    .query_all(&mut db)?;

    // This roughly desugars to:
    //
    // let people: Vec<Person> = 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::<Result<Vec<Person>,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