sqlx_core/
statement.rs

1use crate::arguments::IntoArguments;
2use crate::column::ColumnIndex;
3use crate::database::Database;
4use crate::error::Error;
5use crate::from_row::FromRow;
6use crate::query::Query;
7use crate::query_as::QueryAs;
8use crate::query_scalar::QueryScalar;
9use either::Either;
10
11/// An explicitly prepared statement.
12///
13/// Statements are prepared and cached by default, per connection. This type allows you to
14/// look at that cache in-between the statement being prepared and it being executed. This contains
15/// the expected columns to be returned and the expected parameter types (if available).
16///
17/// Statements can be re-used with any connection and on first-use it will be re-prepared and
18/// cached within the connection.
19pub trait Statement<'q>: Send + Sync {
20    type Database: Database;
21
22    /// Creates an owned statement from this statement reference. This copies
23    /// the original SQL text.
24    fn to_owned(&self) -> <Self::Database as Database>::Statement<'static>;
25
26    /// Get the original SQL text used to create this statement.
27    fn sql(&self) -> &str;
28
29    /// Get the expected parameters for this statement.
30    ///
31    /// The information returned depends on what is available from the driver. SQLite can
32    /// only tell us the number of parameters. PostgreSQL can give us full type information.
33    fn parameters(&self) -> Option<Either<&[<Self::Database as Database>::TypeInfo], usize>>;
34
35    /// Get the columns expected to be returned by executing this statement.
36    fn columns(&self) -> &[<Self::Database as Database>::Column];
37
38    /// Gets the column information at `index`.
39    ///
40    /// A string index can be used to access a column by name and a `usize` index
41    /// can be used to access a column by position.
42    ///
43    /// # Panics
44    ///
45    /// Panics if `index` is out of bounds.
46    /// See [`try_column`](Self::try_column) for a non-panicking version.
47    fn column<I>(&self, index: I) -> &<Self::Database as Database>::Column
48    where
49        I: ColumnIndex<Self>,
50    {
51        self.try_column(index).unwrap()
52    }
53
54    /// Gets the column information at `index` or a `ColumnIndexOutOfBounds` error if out of bounds.
55    fn try_column<I>(&self, index: I) -> Result<&<Self::Database as Database>::Column, Error>
56    where
57        I: ColumnIndex<Self>,
58    {
59        Ok(&self.columns()[index.index(self)?])
60    }
61
62    fn query(&self) -> Query<'_, Self::Database, <Self::Database as Database>::Arguments<'_>>;
63
64    fn query_with<'s, A>(&'s self, arguments: A) -> Query<'s, Self::Database, A>
65    where
66        A: IntoArguments<'s, Self::Database>;
67
68    fn query_as<O>(
69        &self,
70    ) -> QueryAs<'_, Self::Database, O, <Self::Database as Database>::Arguments<'_>>
71    where
72        O: for<'r> FromRow<'r, <Self::Database as Database>::Row>;
73
74    fn query_as_with<'s, O, A>(&'s self, arguments: A) -> QueryAs<'s, Self::Database, O, A>
75    where
76        O: for<'r> FromRow<'r, <Self::Database as Database>::Row>,
77        A: IntoArguments<'s, Self::Database>;
78
79    fn query_scalar<O>(
80        &self,
81    ) -> QueryScalar<'_, Self::Database, O, <Self::Database as Database>::Arguments<'_>>
82    where
83        (O,): for<'r> FromRow<'r, <Self::Database as Database>::Row>;
84
85    fn query_scalar_with<'s, O, A>(&'s self, arguments: A) -> QueryScalar<'s, Self::Database, O, A>
86    where
87        (O,): for<'r> FromRow<'r, <Self::Database as Database>::Row>,
88        A: IntoArguments<'s, Self::Database>;
89}
90
91#[macro_export]
92macro_rules! impl_statement_query {
93    ($A:ty) => {
94        #[inline]
95        fn query(&self) -> $crate::query::Query<'_, Self::Database, $A> {
96            $crate::query::query_statement(self)
97        }
98
99        #[inline]
100        fn query_with<'s, A>(&'s self, arguments: A) -> $crate::query::Query<'s, Self::Database, A>
101        where
102            A: $crate::arguments::IntoArguments<'s, Self::Database>,
103        {
104            $crate::query::query_statement_with(self, arguments)
105        }
106
107        #[inline]
108        fn query_as<O>(
109            &self,
110        ) -> $crate::query_as::QueryAs<
111            '_,
112            Self::Database,
113            O,
114            <Self::Database as $crate::database::Database>::Arguments<'_>,
115        >
116        where
117            O: for<'r> $crate::from_row::FromRow<
118                'r,
119                <Self::Database as $crate::database::Database>::Row,
120            >,
121        {
122            $crate::query_as::query_statement_as(self)
123        }
124
125        #[inline]
126        fn query_as_with<'s, O, A>(
127            &'s self,
128            arguments: A,
129        ) -> $crate::query_as::QueryAs<'s, Self::Database, O, A>
130        where
131            O: for<'r> $crate::from_row::FromRow<
132                'r,
133                <Self::Database as $crate::database::Database>::Row,
134            >,
135            A: $crate::arguments::IntoArguments<'s, Self::Database>,
136        {
137            $crate::query_as::query_statement_as_with(self, arguments)
138        }
139
140        #[inline]
141        fn query_scalar<O>(
142            &self,
143        ) -> $crate::query_scalar::QueryScalar<
144            '_,
145            Self::Database,
146            O,
147            <Self::Database as $crate::database::Database>::Arguments<'_>,
148        >
149        where
150            (O,): for<'r> $crate::from_row::FromRow<
151                'r,
152                <Self::Database as $crate::database::Database>::Row,
153            >,
154        {
155            $crate::query_scalar::query_statement_scalar(self)
156        }
157
158        #[inline]
159        fn query_scalar_with<'s, O, A>(
160            &'s self,
161            arguments: A,
162        ) -> $crate::query_scalar::QueryScalar<'s, Self::Database, O, A>
163        where
164            (O,): for<'r> $crate::from_row::FromRow<
165                'r,
166                <Self::Database as $crate::database::Database>::Row,
167            >,
168            A: $crate::arguments::IntoArguments<'s, Self::Database>,
169        {
170            $crate::query_scalar::query_statement_scalar_with(self, arguments)
171        }
172    };
173}