sqlx_core_guts/from_row.rs
1use crate::error::Error;
2use crate::row::Row;
3
4/// A record that can be built from a row returned by the database.
5///
6/// In order to use [`query_as`](crate::query_as) the output type must implement `FromRow`.
7///
8/// ## Derivable
9///
10/// This trait can be derived by SQLx for any struct. The generated implementation
11/// will consist of a sequence of calls to [`Row::try_get`] using the name from each
12/// struct field.
13///
14/// ```rust,ignore
15/// #[derive(sqlx::FromRow)]
16/// struct User {
17/// id: i32,
18/// name: String,
19/// }
20/// ```
21///
22/// ### Field attributes
23///
24/// Several attributes can be specified to customize how each column in a row is read:
25///
26/// #### `rename`
27///
28/// When the name of a field in Rust does not match the name of its corresponding column,
29/// you can use the `rename` attribute to specify the name that the field has in the row.
30/// For example:
31///
32/// ```rust,ignore
33/// #[derive(sqlx::FromRow)]
34/// struct User {
35/// id: i32,
36/// name: String,
37/// #[sqlx(rename = "description")]
38/// about_me: String
39/// }
40/// ```
41///
42/// Given a query such as:
43///
44/// ```sql
45/// SELECT id, name, description FROM users;
46/// ```
47///
48/// will read the content of the column `description` into the field `about_me`.
49///
50/// #### `rename_all`
51/// By default, field names are expected verbatim (with the exception of the raw identifier prefix `r#`, if present).
52/// Placed at the struct level, this attribute changes how the field name is mapped to its SQL column name:
53///
54/// ```rust,ignore
55/// #[derive(sqlx::FromRow)]
56/// #[sqlx(rename_all = "camelCase")]
57/// struct UserPost {
58/// id: i32,
59/// // remapped to "userId"
60/// user_id: i32,
61/// contents: String
62/// }
63/// ```
64///
65/// The supported values are `snake_case` (available if you have non-snake-case field names for some
66/// reason), `lowercase`, `UPPERCASE`, `camelCase`, `PascalCase`, `SCREAMING_SNAKE_CASE` and `kebab-case`.
67/// The styling of each option is intended to be an example of its behavior.
68///
69/// #### `default`
70///
71/// When your struct contains a field that is not present in your query,
72/// if the field type has an implementation for [`Default`],
73/// you can use the `default` attribute to assign the default value to said field.
74/// For example:
75///
76/// ```rust,ignore
77/// #[derive(sqlx::FromRow)]
78/// struct User {
79/// id: i32,
80/// name: String,
81/// #[sqlx(default)]
82/// location: Option<String>
83/// }
84/// ```
85///
86/// Given a query such as:
87///
88/// ```sql
89/// SELECT id, name FROM users;
90/// ```
91///
92/// will set the value of the field `location` to the default value of `Option<String>`,
93/// which is `None`.
94///
95pub trait FromRow<'r, R: Row>: Sized {
96 fn from_row(row: &'r R) -> Result<Self, Error>;
97}
98
99// implement FromRow for tuples of types that implement Decode
100// up to tuples of 9 values
101
102macro_rules! impl_from_row_for_tuple {
103 ($( ($idx:tt) -> $T:ident );+;) => {
104 impl<'r, R, $($T,)+> FromRow<'r, R> for ($($T,)+)
105 where
106 R: Row,
107 usize: crate::column::ColumnIndex<R>,
108 $($T: crate::decode::Decode<'r, R::Database> + crate::types::Type<R::Database>,)+
109 {
110 #[inline]
111 fn from_row(row: &'r R) -> Result<Self, Error> {
112 Ok(($(row.try_get($idx as usize)?,)+))
113 }
114 }
115 };
116}
117
118impl_from_row_for_tuple!(
119 (0) -> T1;
120);
121
122impl_from_row_for_tuple!(
123 (0) -> T1;
124 (1) -> T2;
125);
126
127impl_from_row_for_tuple!(
128 (0) -> T1;
129 (1) -> T2;
130 (2) -> T3;
131);
132
133impl_from_row_for_tuple!(
134 (0) -> T1;
135 (1) -> T2;
136 (2) -> T3;
137 (3) -> T4;
138);
139
140impl_from_row_for_tuple!(
141 (0) -> T1;
142 (1) -> T2;
143 (2) -> T3;
144 (3) -> T4;
145 (4) -> T5;
146);
147
148impl_from_row_for_tuple!(
149 (0) -> T1;
150 (1) -> T2;
151 (2) -> T3;
152 (3) -> T4;
153 (4) -> T5;
154 (5) -> T6;
155);
156
157impl_from_row_for_tuple!(
158 (0) -> T1;
159 (1) -> T2;
160 (2) -> T3;
161 (3) -> T4;
162 (4) -> T5;
163 (5) -> T6;
164 (6) -> T7;
165);
166
167impl_from_row_for_tuple!(
168 (0) -> T1;
169 (1) -> T2;
170 (2) -> T3;
171 (3) -> T4;
172 (4) -> T5;
173 (5) -> T6;
174 (6) -> T7;
175 (7) -> T8;
176);
177
178impl_from_row_for_tuple!(
179 (0) -> T1;
180 (1) -> T2;
181 (2) -> T3;
182 (3) -> T4;
183 (4) -> T5;
184 (5) -> T6;
185 (6) -> T7;
186 (7) -> T8;
187 (8) -> T9;
188);
189
190impl_from_row_for_tuple!(
191 (0) -> T1;
192 (1) -> T2;
193 (2) -> T3;
194 (3) -> T4;
195 (4) -> T5;
196 (5) -> T6;
197 (6) -> T7;
198 (7) -> T8;
199 (8) -> T9;
200 (9) -> T10;
201);
202
203impl_from_row_for_tuple!(
204 (0) -> T1;
205 (1) -> T2;
206 (2) -> T3;
207 (3) -> T4;
208 (4) -> T5;
209 (5) -> T6;
210 (6) -> T7;
211 (7) -> T8;
212 (8) -> T9;
213 (9) -> T10;
214 (10) -> T11;
215);
216
217impl_from_row_for_tuple!(
218 (0) -> T1;
219 (1) -> T2;
220 (2) -> T3;
221 (3) -> T4;
222 (4) -> T5;
223 (5) -> T6;
224 (6) -> T7;
225 (7) -> T8;
226 (8) -> T9;
227 (9) -> T10;
228 (10) -> T11;
229 (11) -> T12;
230);
231
232impl_from_row_for_tuple!(
233 (0) -> T1;
234 (1) -> T2;
235 (2) -> T3;
236 (3) -> T4;
237 (4) -> T5;
238 (5) -> T6;
239 (6) -> T7;
240 (7) -> T8;
241 (8) -> T9;
242 (9) -> T10;
243 (10) -> T11;
244 (11) -> T12;
245 (12) -> T13;
246);
247
248impl_from_row_for_tuple!(
249 (0) -> T1;
250 (1) -> T2;
251 (2) -> T3;
252 (3) -> T4;
253 (4) -> T5;
254 (5) -> T6;
255 (6) -> T7;
256 (7) -> T8;
257 (8) -> T9;
258 (9) -> T10;
259 (10) -> T11;
260 (11) -> T12;
261 (12) -> T13;
262 (13) -> T14;
263);
264
265impl_from_row_for_tuple!(
266 (0) -> T1;
267 (1) -> T2;
268 (2) -> T3;
269 (3) -> T4;
270 (4) -> T5;
271 (5) -> T6;
272 (6) -> T7;
273 (7) -> T8;
274 (8) -> T9;
275 (9) -> T10;
276 (10) -> T11;
277 (11) -> T12;
278 (12) -> T13;
279 (13) -> T14;
280 (14) -> T15;
281);
282
283impl_from_row_for_tuple!(
284 (0) -> T1;
285 (1) -> T2;
286 (2) -> T3;
287 (3) -> T4;
288 (4) -> T5;
289 (5) -> T6;
290 (6) -> T7;
291 (7) -> T8;
292 (8) -> T9;
293 (9) -> T10;
294 (10) -> T11;
295 (11) -> T12;
296 (12) -> T13;
297 (13) -> T14;
298 (14) -> T15;
299 (15) -> T16;
300);