sqlx_core_oldapi/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///
95/// ### `flatten`
96///
97/// If you want to handle a field that implements [`FromRow`],
98/// you can use the `flatten` attribute to specify that you want
99/// it to use [`FromRow`] for parsing rather than the usual method.
100/// For example:
101///
102/// ```rust,ignore
103/// #[derive(sqlx::FromRow)]
104/// struct Address {
105/// country: String,
106/// city: String,
107/// road: String,
108/// }
109///
110/// #[derive(sqlx::FromRow)]
111/// struct User {
112/// id: i32,
113/// name: String,
114/// #[sqlx(flatten)]
115/// address: Address,
116/// }
117/// ```
118/// Given a query such as:
119///
120/// ```sql
121/// SELECT id, name, country, city, road FROM users;
122/// ```
123///
124/// This field is compatible with the `default` attribute.
125///
126/// ## Manual implementation
127///
128/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
129/// have a struct with a field that needs manual decoding:
130///
131///
132/// ```rust,ignore
133/// use sqlx::{FromRow, sqlite::SqliteRow, sqlx::Row};
134/// struct MyCustomType {
135/// custom: String,
136/// }
137///
138/// struct Foo {
139/// bar: MyCustomType,
140/// }
141///
142/// impl FromRow<'_, SqliteRow> for Foo {
143/// fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
144/// Ok(Self {
145/// bar: MyCustomType {
146/// custom: row.try_get("custom")?
147/// }
148/// })
149/// }
150/// }
151/// ```
152///
153/// #### `try_from`
154///
155/// When your struct contains a field whose type is not matched with the database type,
156/// if the field type has an implementation [`TryFrom`] for the database type,
157/// you can use the `try_from` attribute to convert the database type to the field type.
158/// For example:
159///
160/// ```rust,ignore
161/// #[derive(sqlx::FromRow)]
162/// struct User {
163/// id: i32,
164/// name: String,
165/// #[sqlx(try_from = "i64")]
166/// bigIntInMySql: u64
167/// }
168/// ```
169///
170/// Given a query such as:
171///
172/// ```sql
173/// SELECT id, name, bigIntInMySql FROM users;
174/// ```
175///
176/// In MySql, `BigInt` type matches `i64`, but you can convert it to `u64` by `try_from`.
177///
178pub trait FromRow<'r, R: Row>: Sized {
179 fn from_row(row: &'r R) -> Result<Self, Error>;
180}
181
182// implement FromRow for tuples of types that implement Decode
183// up to tuples of 9 values
184
185macro_rules! impl_from_row_for_tuple {
186 ($( ($idx:tt) -> $T:ident );+;) => {
187 impl<'r, R, $($T,)+> FromRow<'r, R> for ($($T,)+)
188 where
189 R: Row,
190 usize: crate::column::ColumnIndex<R>,
191 $($T: crate::decode::Decode<'r, R::Database> + crate::types::Type<R::Database>,)+
192 {
193 #[inline]
194 fn from_row(row: &'r R) -> Result<Self, Error> {
195 Ok(($(row.try_get($idx as usize)?,)+))
196 }
197 }
198 };
199}
200
201impl_from_row_for_tuple!(
202 (0) -> T1;
203);
204
205impl_from_row_for_tuple!(
206 (0) -> T1;
207 (1) -> T2;
208);
209
210impl_from_row_for_tuple!(
211 (0) -> T1;
212 (1) -> T2;
213 (2) -> T3;
214);
215
216impl_from_row_for_tuple!(
217 (0) -> T1;
218 (1) -> T2;
219 (2) -> T3;
220 (3) -> T4;
221);
222
223impl_from_row_for_tuple!(
224 (0) -> T1;
225 (1) -> T2;
226 (2) -> T3;
227 (3) -> T4;
228 (4) -> T5;
229);
230
231impl_from_row_for_tuple!(
232 (0) -> T1;
233 (1) -> T2;
234 (2) -> T3;
235 (3) -> T4;
236 (4) -> T5;
237 (5) -> T6;
238);
239
240impl_from_row_for_tuple!(
241 (0) -> T1;
242 (1) -> T2;
243 (2) -> T3;
244 (3) -> T4;
245 (4) -> T5;
246 (5) -> T6;
247 (6) -> T7;
248);
249
250impl_from_row_for_tuple!(
251 (0) -> T1;
252 (1) -> T2;
253 (2) -> T3;
254 (3) -> T4;
255 (4) -> T5;
256 (5) -> T6;
257 (6) -> T7;
258 (7) -> T8;
259);
260
261impl_from_row_for_tuple!(
262 (0) -> T1;
263 (1) -> T2;
264 (2) -> T3;
265 (3) -> T4;
266 (4) -> T5;
267 (5) -> T6;
268 (6) -> T7;
269 (7) -> T8;
270 (8) -> T9;
271);
272
273impl_from_row_for_tuple!(
274 (0) -> T1;
275 (1) -> T2;
276 (2) -> T3;
277 (3) -> T4;
278 (4) -> T5;
279 (5) -> T6;
280 (6) -> T7;
281 (7) -> T8;
282 (8) -> T9;
283 (9) -> T10;
284);
285
286impl_from_row_for_tuple!(
287 (0) -> T1;
288 (1) -> T2;
289 (2) -> T3;
290 (3) -> T4;
291 (4) -> T5;
292 (5) -> T6;
293 (6) -> T7;
294 (7) -> T8;
295 (8) -> T9;
296 (9) -> T10;
297 (10) -> T11;
298);
299
300impl_from_row_for_tuple!(
301 (0) -> T1;
302 (1) -> T2;
303 (2) -> T3;
304 (3) -> T4;
305 (4) -> T5;
306 (5) -> T6;
307 (6) -> T7;
308 (7) -> T8;
309 (8) -> T9;
310 (9) -> T10;
311 (10) -> T11;
312 (11) -> T12;
313);
314
315impl_from_row_for_tuple!(
316 (0) -> T1;
317 (1) -> T2;
318 (2) -> T3;
319 (3) -> T4;
320 (4) -> T5;
321 (5) -> T6;
322 (6) -> T7;
323 (7) -> T8;
324 (8) -> T9;
325 (9) -> T10;
326 (10) -> T11;
327 (11) -> T12;
328 (12) -> T13;
329);
330
331impl_from_row_for_tuple!(
332 (0) -> T1;
333 (1) -> T2;
334 (2) -> T3;
335 (3) -> T4;
336 (4) -> T5;
337 (5) -> T6;
338 (6) -> T7;
339 (7) -> T8;
340 (8) -> T9;
341 (9) -> T10;
342 (10) -> T11;
343 (11) -> T12;
344 (12) -> T13;
345 (13) -> T14;
346);
347
348impl_from_row_for_tuple!(
349 (0) -> T1;
350 (1) -> T2;
351 (2) -> T3;
352 (3) -> T4;
353 (4) -> T5;
354 (5) -> T6;
355 (6) -> T7;
356 (7) -> T8;
357 (8) -> T9;
358 (9) -> T10;
359 (10) -> T11;
360 (11) -> T12;
361 (12) -> T13;
362 (13) -> T14;
363 (14) -> T15;
364);
365
366impl_from_row_for_tuple!(
367 (0) -> T1;
368 (1) -> T2;
369 (2) -> T3;
370 (3) -> T4;
371 (4) -> T5;
372 (5) -> T6;
373 (6) -> T7;
374 (7) -> T8;
375 (8) -> T9;
376 (9) -> T10;
377 (10) -> T11;
378 (11) -> T12;
379 (12) -> T13;
380 (13) -> T14;
381 (14) -> T15;
382 (15) -> T16;
383);