[−][src]Crate postgres_query
Helper macros and traits built around tokio-postgres to define queries with human readable parameters and return values.
Example
// Connect to the database let client: Client = connect(/* ... */); // Construct the query let query = query!( "SELECT age, name FROM people WHERE age >= $min_age", min_age = 18 ); // Define the structure of the data returned from the query #[derive(FromSqlRow)] struct Person { age: i32, name: String, } // Execute the query let people: Vec<Person> = query.fetch(&client).await?; for person in people { println!("{} is {} years young", person.name, person.age); }
Queries
The preferred way of constructing a new Query
is through the query!
macro. It uses a
syntax similar to the format!(...)
family of macros from the standard library. The first
parameter is the SQL query and is always given as a string literal (this might be relaxed in the
future). This string literal may contain parameter bindings on the form $ident
where ident
is any valid Rust identifier ($abc
, $value_123
, etc.).
let age = 42; let insert_person = query!( "INSERT INTO people VALUES ($age, $name)", name = "John Wick", // Binds "$name" to "John Wick" age, // Binds "$age" to the value of `age` );
During compilation the query is converted into the format expected by PostgreSQL: parameter bindings are converted to using numbers ($1, $2, etc.) and the actual parameter values are put into a 1-indexed array. The code snippet above would be expanded into the following:
let age = 42; let insert_person = Query { sql: "INSERT INTO people VALUES ($1, $2)", parameters: vec![&age, &"John Wick"], };
Data Extraction
In addition to helping you define new queries this crate provides the FromSqlRow
trait which
makes it easy to extract typed values from the resulting rows. The easiest way to implement this
trait for new struct
s is to use the included derive(FromSqlRow)
macro.
- If used on a tuple struct, values will be extracted from the corresponding columns based on their position in the tuple.
- If used on a stuct with named fields, values will be extracted from the column with the same name as the field.
#[derive(FromSqlRow)] struct TupleData(i32, String); #[derive(FromSqlRow)] struct NamedData { age: i32, name: String, };
Caching queries
From time to time you probably want to execute the same query multiple times, but with different
parameters. In times like these we can decrease the load on the database by preparing our
queries before executing them. By wrapping a client in a Caching
struct this behaviour is
automatically provided for all queries that originate from this crate:
// Connect to the database let client: Client = connect(/* ... */); // Wrap the client in a query cache let cached_client = Caching::new(client); for age in 0..100i32 { let query = query!("SELECT name, weight FROM people WHERE age = $age", age); // The query is prepared and cached the first time it's executed. // All subsequent fetches will use the cached Statement. let people: Vec<(String, i32)> = query.fetch(&cached_client).await?; /* Do something with people */ }
Re-exports
pub use extract::FromSqlRow; |
Modules
client | Abstractions over client-like types. |
execute | Executing queries through a client. |
extract | Extract typed values from rows. |
Macros
query | Constructs a new query. |
Structs
Caching | A client wrapper which caches prepared queries. |
Query | A static query with dynamic parameters. |
Enums
Error | Any error that this crate may produce. |
Type Definitions
Result |
Derive Macros
FromSqlRow | Extract values from a row. |