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
11pub trait Statement<'q>: Send + Sync {
20 type Database: Database;
21
22 fn to_owned(&self) -> <Self::Database as Database>::Statement<'static>;
25
26 fn sql(&self) -> &str;
28
29 fn parameters(&self) -> Option<Either<&[<Self::Database as Database>::TypeInfo], usize>>;
34
35 fn columns(&self) -> &[<Self::Database as Database>::Column];
37
38 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 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}