1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#![doc = include_str!("../README.md")]

/// # Emit conditional compile-time verified `query_as!` invocations
///
/// The generated type exposes the same methods as `sqlx::query::Map`, with the exception of `map`
/// and `try_map`.
///
///
/// ## Bound parameters
///
/// This macro supports two kind of bound parameters, run-time bound and compile-time bound.
///
///
/// ### Run-time bound parameters
///
/// Run-time bound parameers are regular bound parameters that are passed as separate parameters to
/// the database, allowing you to use variable data without the risk of SQL injections.
/// Additionally since the same prepared query can be reused it means that the database knows to
/// generate a more optimized query-plan if it's used a lot.
///
/// Unlike in SQLx's macros you specify run-time bound parameters using a format-string-like
/// syntax: `{foo}`.  There must be a variable with the given name in scope, and it must be a valid
/// type to pass to `query_as!`.
///
/// You can pass type overrides to SQLx using a colon after the binding reference.  E.g.
/// `{foo:_}`
///
/// Which kind of bound parameter references are generated depends on the activated features.
///
///
/// ### Compile-time bound parameters
///
/// Compile-time bound parameters are expanded at compile-time.  This means that each possible
/// option will generate a unique `query_as!` invocation.
///
/// They are referenced by prepending the bound name with a hash: `{#foo}`.
///
/// They are bound by following the query string with a series of match statements in the following
/// format.  Compile-time binding expressions can evaluate to either a string literal or a tuple of
/// string literals.
///
/// ```rust,ignore
/// #foo = match something {
///     true => "BAR",
///     false => "BAZ",
/// }
/// ```
///
///
/// ## Examples
///
/// ```rust,ignore
/// enum OrderDirection {
///     Ascending,
///     Descending,
/// }
///
/// let limit = Some(42);
/// let order_dir = OrderDirection::Ascending;
///
/// conditional_query_as!(
///     OutputType,
///     r#"
///         SELECT id, foo, bar
///         FROM table
///         {#limit}
///         ORDER BY id {#order_dir}, foo {#order_dir_rev}
///     "#,
///     #limit = match limit {
///         Some(_) => "LIMIT {limit}",
///         None => "",
///     },
///     #(order_dir, order_dir_rev) = match order_dir {
///         OrderDirection::Ascending => ("ASC", "DESC"),
///         OrderDirection::Descending => ("DESC", "ASC"),
///     },
/// )
///     .fetch_all(&mut *tx)
///     .await?;
/// ```
pub use sqlx_conditional_queries_macros::conditional_query_as;

/// Do not use this module.  It is only meant to be used by the generated by
/// [`conditional_query_as!`] macro.
#[doc(hidden)]
pub mod exports {
    pub use futures_core::stream::BoxStream;
}