query_lazy!() { /* proc-macro */ }Expand description
Type-safe SQL macro that builds a lazy query and returns a stream on execution.
Like query!, this macro validates table/column names and binds arguments at compile time,
but it does not execute immediately. Instead it returns a lazy query builder that can be
stored, moved, and executed later.
? (handling result) is required to build the lazy query.
§Syntax
ⓘ
query_lazy!(<Driver> SQL)<Driver>is optional; if omitted the default driver is taken from the build script viasql_build::build. If multiple (or zero) defaults are configured, you must specify the driver explicitly.- Uses the same SQL syntax and helpers as
query! - There is no connection parameter in the macro call; pass it when fetching.
§Return value
returns a anyhow::Result<LazyQueryResult> with the following method:
fetch(impl EasyExecutorInto)- with a generic
conn: &mut impl EasyExecutor, usefetch(&mut *conn)when you need to useconnagain later in the same scope- on the final use in that scope,
fetch(conn)is valid and shorter
- on the final use in that scope,
- otherwise pass a connection or transaction directly (e.g.,
fetch(conn)orfetch(&mut transaction))
- with a generic
Both return futures::Stream<Item = anyhow::Result<Output>>. The stream borrows the
connection; drop or fully consume it before reusing the connection.
§Output and query forms
- Output must be a single-row type implementing
Output. To return multiple rows, iterate/collect the stream yourself. - Supported query forms:
SELECT,INSERT,UPDATE,DELETE. INSERT/UPDATE/DELETEmust includeRETURNING(because results are streamed).EXISTSis not supported; usequery!instead.
§Examples
ⓘ
let mut lazy = query_lazy!(<Sqlite> SELECT OutputType FROM TableType WHERE column = 42)?;
let mut stream = lazy.fetch(&mut conn);
let row = stream.next().await.context("Expected at least one row")?;
let row = row.context("Failed to fetch row")?;ⓘ
let min_val = 10;
let mut lazy = query_lazy!(
SELECT ExprTestData FROM ExprTestTable WHERE ExprTestTable.int_field > {min_val}
)?;
let mut rows = Vec::new();
let mut stream = lazy.fetch(&mut conn);
while let Some(row) = stream.next().await {
rows.push(row.context("Failed to fetch row")?);
}ⓘ
async fn generic_executor_example(
conn: &mut impl EasyExecutor<ExampleDriver>,
) -> anyhow::Result<()> {
let mut lazy = query_lazy!(SELECT ExprTestData FROM ExprTestTable)?;
let mut stream = lazy.fetch(conn);
let maybe = stream.next().await.transpose()?;
assert!(maybe.is_some());
Ok(())
}