Attribute Macro inline_sql::inline_sql

source ·
#[inline_sql]
Expand description

Mark a function that executes an SQL query.

The function body must follow the form query! { ... } or query!(...).

The return type of the function determines the behavior of the function. There are a few options for the return type:

  • Result<(), E>: Execute the query without returning anything. Errors are still reported.
  • Result<u64, E>: Execute the query and return the number of affected rows.
  • Result<Vec<T>, E>: Execute the query and return the rows as a vector.
  • Result<Option<T>, E>: Execute the query and return a single optional row.
  • Result<RowStream, E>: Execute the query and return a RowStream.

The row type T must implement TryFrom<tokio_postgres::Row>. The TryFrom::Error type must implement Into<E>.

The error type E must implement From<tokio_postgres::Error>`.

For functions that return a Result<Option<T>, E>, an error is reported if the query returned more than one row.

You can generally not use a type alias in the return type of the function. The proc macro can not resolve the alias, and will not know which variant to generate.

§Macro arguments

The attribute macro also accepts a arguments. Multiple arguments may be specified separated by a comma.

§#[inline_sql(client = ...)]

Specify the SQL client object to use. The argument value must be an expression that gives a tokio_postgres::Client, preferably by reference.

§#[inline_sql(map_row = ...)]

Specify a custom function to convert a row from the query result to the return value. The argument value must be an expression that gives a function with the signature Fn(tokio_postgres::Row) -> Result<T, E>.

You can specify the name of a function or a closure.

§#[inline_sql(map_err = ...)]

Specify a custom function to convert the SQL error to the error from the function return type. The argument value must be an expression that gives a function with the signature Fn(tokio_postgres::Error) -> E.

You can specify the name of a function or a closure.

§Example 1: Ignore the query output.

use inline_sql::inline_sql;

#[inline_sql]
async fn create_pets_table(
  client: &tokio_postgres::Client
) -> Result<(), tokio_postgres::Error> {
  query! {
    CREATE TABLE pets (
      name TEXT PRIMARY KEY,
      species TEXT NOT NULL
    )
  }
}

§Example: Return a Vec of rows.

use inline_sql::inline_sql;


#[inline_sql]
async fn get_pets_by_species(
  client: &tokio_postgres::Client,
  species: &str,
) -> Result<Vec<Pet>, tokio_postgres::Error> {
    query!(SELECT * FROM pets WHERE species = #species)
}

§Example: Return an Option.

use inline_sql::inline_sql;


#[inline_sql]
async fn get_pet_by_name(
  client: &tokio_postgres::Client,
  name: &str,
) -> Result<Option<Pet>, tokio_postgres::Error> {
    query!(SELECT * FROM pets WHERE name = #name)
}

§Example: Return the number of affected rows.

use inline_sql::inline_sql;


#[inline_sql]
async fn rename_species(
  client: &tokio_postgres::Client,
  old_species: &str,
  new_species: &str,
) -> Result<u64, tokio_postgres::Error> {
    query!(UPDATE pets SET species = #new_species WHERE species = #old_species)
}