sqlx_core/
from_row.rs

1use crate::{error::Error, row::Row};
2
3/// A record that can be built from a row returned by the database.
4///
5/// In order to use [`query_as`](crate::query_as) the output type must implement `FromRow`.
6///
7/// ## Derivable
8///
9/// This trait can be derived by SQLx for any struct. The generated implementation
10/// will consist of a sequence of calls to [`Row::try_get`] using the name from each
11/// struct field.
12///
13/// ```rust,ignore
14/// #[derive(sqlx::FromRow)]
15/// struct User {
16///     id: i32,
17///     name: String,
18/// }
19/// ```
20///
21/// ### Field attributes
22///
23/// Several attributes can be specified to customize how each column in a row is read:
24///
25/// #### `rename`
26///
27/// When the name of a field in Rust does not match the name of its corresponding column,
28/// you can use the `rename` attribute to specify the name that the field has in the row.
29/// For example:
30///
31/// ```rust,ignore
32/// #[derive(sqlx::FromRow)]
33/// struct User {
34///     id: i32,
35///     name: String,
36///     #[sqlx(rename = "description")]
37///     about_me: String
38/// }
39/// ```
40///
41/// Given a query such as:
42///
43/// ```sql
44/// SELECT id, name, description FROM users;
45/// ```
46///
47/// will read the content of the column `description` into the field `about_me`.
48///
49/// #### `rename_all`
50/// By default, field names are expected verbatim (with the exception of the raw identifier prefix `r#`, if present).
51/// Placed at the struct level, this attribute changes how the field name is mapped to its SQL column name:
52///
53/// ```rust,ignore
54/// #[derive(sqlx::FromRow)]
55/// #[sqlx(rename_all = "camelCase")]
56/// struct UserPost {
57///     id: i32,
58///     // remapped to "userId"
59///     user_id: i32,
60///     contents: String
61/// }
62/// ```
63///
64/// The supported values are `snake_case` (available if you have non-snake-case field names for some
65/// reason), `lowercase`, `UPPERCASE`, `camelCase`, `PascalCase`, `SCREAMING_SNAKE_CASE` and `kebab-case`.
66/// The styling of each option is intended to be an example of its behavior.
67///
68/// Case conversion is handled by the `heck` crate.
69/// See [its documentation](https://docs.rs/heck/0.5.0/heck/#definition-of-a-word-boundary)
70/// for details.
71///
72/// Note that numbers are *not* considered separate words.
73/// For example, `Foo1` to snake case would be `foo1`, *not* `foo_1`.
74/// See [this issue](https://github.com/launchbadge/sqlx/issues/3864) for discussion.
75///
76/// #### `default`
77///
78/// When your struct contains a field that is not present in your query,
79/// if the field type has an implementation for [`Default`],
80/// you can use the `default` attribute to assign the default value to said field.
81/// For example:
82///
83/// ```rust,ignore
84/// #[derive(sqlx::FromRow)]
85/// struct User {
86///     id: i32,
87///     name: String,
88///     #[sqlx(default)]
89///     location: Option<String>
90/// }
91/// ```
92///
93/// Given a query such as:
94///
95/// ```sql
96/// SELECT id, name FROM users;
97/// ```
98///
99/// will set the value of the field `location` to the default value of `Option<String>`,
100/// which is `None`.
101///
102/// Moreover, if the struct has an implementation for [`Default`], you can use the `default`
103/// attribute at the struct level rather than for each single field. If a field does not appear in the result,
104/// its value is taken from the `Default` implementation for the struct.
105/// For example:
106///
107/// ```rust, ignore
108/// #[derive(Default, sqlx::FromRow)]
109/// #[sqlx(default)]
110/// struct Options {
111///     option_a: Option<i32>,
112///     option_b: Option<String>,
113///     option_c: Option<bool>,
114/// }
115/// ```
116///
117/// For a derived `Default` implementation this effectively populates each missing field
118/// with `Default::default()`, but a manual `Default` implementation can provide
119/// different placeholder values, if applicable.
120///
121/// This is similar to how `#[serde(default)]` behaves.
122///
123/// #### `flatten`
124///
125/// If you want to handle a field that implements [`FromRow`],
126/// you can use the `flatten` attribute to specify that you want
127/// it to use [`FromRow`] for parsing rather than the usual method.
128/// For example:
129///
130/// ```rust,ignore
131/// #[derive(sqlx::FromRow)]
132/// struct Address {
133///     country: String,
134///     city: String,
135///     road: String,
136/// }
137///
138/// #[derive(sqlx::FromRow)]
139/// struct User {
140///     id: i32,
141///     name: String,
142///     #[sqlx(flatten)]
143///     address: Address,
144/// }
145/// ```
146/// Given a query such as:
147///
148/// ```sql
149/// SELECT id, name, country, city, road FROM users;
150/// ```
151///
152/// This field is compatible with the `default` attribute.
153///
154/// #### `skip`
155///
156/// This is a variant of the `default` attribute which instead always takes the value from
157/// the `Default` implementation for this field type ignoring any results in your query.
158/// This can be useful, if some field does not satifisfy the trait bounds (i.e.
159/// `sqlx::decode::Decode`, `sqlx::type::Type`), in particular in case of nested structures.
160/// For example:
161///
162/// ```rust,ignore
163/// #[derive(sqlx::FromRow)]
164/// struct Address {
165///     user_name: String,
166///     street: String,
167///     city: String,
168/// }
169///
170/// #[derive(sqlx::FromRow)]
171/// struct User {
172///     name: String,
173///     #[sqlx(skip)]
174///     addresses: Vec<Address>,
175/// }
176/// ```
177///
178/// Then when querying into `User`, only `name` needs to be set:
179///
180/// ```rust,ignore
181/// let user: User = sqlx::query_as("SELECT name FROM users")
182///    .fetch_one(&mut some_connection)
183///    .await?;
184///
185/// // `Default` for `Vec<Address>` is an empty vector.
186/// assert!(user.addresses.is_empty());
187/// ```
188///
189/// #### `try_from`
190///
191/// When your struct contains a field whose type is not matched with the database type,
192/// if the field type has an implementation [`TryFrom`] for the database type,
193/// you can use the `try_from` attribute to convert the database type to the field type.
194/// For example:
195///
196/// ```rust,ignore
197/// #[derive(sqlx::FromRow)]
198/// struct User {
199///     id: i32,
200///     name: String,
201///     #[sqlx(try_from = "i64")]
202///     bigIntInMySql: u64
203/// }
204/// ```
205///
206/// Given a query such as:
207///
208/// ```sql
209/// SELECT id, name, bigIntInMySql FROM users;
210/// ```
211///
212/// In MySql, `BigInt` type matches `i64`, but you can convert it to `u64` by `try_from`.
213///
214/// #### `json`
215///
216/// If your database supports a JSON type, you can leverage `#[sqlx(json)]`
217/// to automatically integrate JSON deserialization in your [`FromRow`] implementation using [`serde`](https://docs.rs/serde/latest/serde/).
218///
219/// ```rust,ignore
220/// #[derive(serde::Deserialize)]
221/// struct Data {
222///     field1: String,
223///     field2: u64
224/// }
225///
226/// #[derive(sqlx::FromRow)]
227/// struct User {
228///     id: i32,
229///     name: String,
230///     #[sqlx(json)]
231///     metadata: Data
232/// }
233/// ```
234///
235/// Given a query like the following:
236///
237/// ```sql
238/// SELECT
239///     1 AS id,
240///     'Name' AS name,
241///     JSON_OBJECT('field1', 'value1', 'field2', 42) AS metadata
242/// ```
243///
244/// The `metadata` field will be deserialized used its `serde::Deserialize` implementation:
245///
246/// ```rust,ignore
247/// User {
248///     id: 1,
249///     name: "Name",
250///     metadata: Data {
251///         field1: "value1",
252///         field2: 42
253///     }
254/// }
255/// ```
256///
257/// By default the `#[sqlx(json)]` attribute will assume that the underlying database row is
258/// _not_ NULL. This can cause issues when your field type is an `Option<T>` because this would be
259/// represented as the _not_ NULL (in terms of DB) JSON value of `null`.
260///
261/// If you wish to describe a database row which _is_ NULLable but _cannot_ contain the JSON value `null`,
262/// use the `#[sqlx(json(nullable))]` attribute.
263///
264/// For example
265/// ```rust,ignore
266/// #[derive(serde::Deserialize)]
267/// struct Data {
268///     field1: String,
269///     field2: u64
270/// }
271///
272/// #[derive(sqlx::FromRow)]
273/// struct User {
274///     id: i32,
275///     name: String,
276///     #[sqlx(json(nullable))]
277///     metadata: Option<Data>
278/// }
279/// ```
280/// Would describe a database field which _is_ NULLable but if it exists it must be the JSON representation of `Data`
281/// and cannot be the JSON value `null`
282///
283/// ## Manual implementation
284///
285/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
286/// have a struct with a field that needs manual decoding:
287///
288///
289/// ```rust,ignore
290/// use sqlx::{FromRow, sqlite::SqliteRow, sqlx::Row};
291/// struct MyCustomType {
292///     custom: String,
293/// }
294///
295/// struct Foo {
296///     bar: MyCustomType,
297/// }
298///
299/// impl FromRow<'_, SqliteRow> for Foo {
300///     fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
301///         Ok(Self {
302///             bar: MyCustomType {
303///                 custom: row.try_get("custom")?
304///             }
305///         })
306///     }
307/// }
308/// ```
309pub trait FromRow<'r, R: Row>: Sized {
310    fn from_row(row: &'r R) -> Result<Self, Error>;
311}
312
313impl<'r, R> FromRow<'r, R> for ()
314where
315    R: Row,
316{
317    #[inline]
318    fn from_row(_: &'r R) -> Result<Self, Error> {
319        Ok(())
320    }
321}
322
323// implement FromRow for tuples of types that implement Decode
324// up to tuples of 16 values
325
326macro_rules! impl_from_row_for_tuple {
327    ($( ($idx:tt) -> $T:ident );+;) => {
328        impl<'r, R, $($T,)+> FromRow<'r, R> for ($($T,)+)
329        where
330            R: Row,
331            usize: crate::column::ColumnIndex<R>,
332            $($T: crate::decode::Decode<'r, R::Database> + crate::types::Type<R::Database>,)+
333        {
334            #[inline]
335            fn from_row(row: &'r R) -> Result<Self, Error> {
336                Ok(($(row.try_get($idx as usize)?,)+))
337            }
338        }
339    };
340}
341
342impl_from_row_for_tuple!(
343    (0) -> T1;
344);
345
346impl_from_row_for_tuple!(
347    (0) -> T1;
348    (1) -> T2;
349);
350
351impl_from_row_for_tuple!(
352    (0) -> T1;
353    (1) -> T2;
354    (2) -> T3;
355);
356
357impl_from_row_for_tuple!(
358    (0) -> T1;
359    (1) -> T2;
360    (2) -> T3;
361    (3) -> T4;
362);
363
364impl_from_row_for_tuple!(
365    (0) -> T1;
366    (1) -> T2;
367    (2) -> T3;
368    (3) -> T4;
369    (4) -> T5;
370);
371
372impl_from_row_for_tuple!(
373    (0) -> T1;
374    (1) -> T2;
375    (2) -> T3;
376    (3) -> T4;
377    (4) -> T5;
378    (5) -> T6;
379);
380
381impl_from_row_for_tuple!(
382    (0) -> T1;
383    (1) -> T2;
384    (2) -> T3;
385    (3) -> T4;
386    (4) -> T5;
387    (5) -> T6;
388    (6) -> T7;
389);
390
391impl_from_row_for_tuple!(
392    (0) -> T1;
393    (1) -> T2;
394    (2) -> T3;
395    (3) -> T4;
396    (4) -> T5;
397    (5) -> T6;
398    (6) -> T7;
399    (7) -> T8;
400);
401
402impl_from_row_for_tuple!(
403    (0) -> T1;
404    (1) -> T2;
405    (2) -> T3;
406    (3) -> T4;
407    (4) -> T5;
408    (5) -> T6;
409    (6) -> T7;
410    (7) -> T8;
411    (8) -> T9;
412);
413
414impl_from_row_for_tuple!(
415    (0) -> T1;
416    (1) -> T2;
417    (2) -> T3;
418    (3) -> T4;
419    (4) -> T5;
420    (5) -> T6;
421    (6) -> T7;
422    (7) -> T8;
423    (8) -> T9;
424    (9) -> T10;
425);
426
427impl_from_row_for_tuple!(
428    (0) -> T1;
429    (1) -> T2;
430    (2) -> T3;
431    (3) -> T4;
432    (4) -> T5;
433    (5) -> T6;
434    (6) -> T7;
435    (7) -> T8;
436    (8) -> T9;
437    (9) -> T10;
438    (10) -> T11;
439);
440
441impl_from_row_for_tuple!(
442    (0) -> T1;
443    (1) -> T2;
444    (2) -> T3;
445    (3) -> T4;
446    (4) -> T5;
447    (5) -> T6;
448    (6) -> T7;
449    (7) -> T8;
450    (8) -> T9;
451    (9) -> T10;
452    (10) -> T11;
453    (11) -> T12;
454);
455
456impl_from_row_for_tuple!(
457    (0) -> T1;
458    (1) -> T2;
459    (2) -> T3;
460    (3) -> T4;
461    (4) -> T5;
462    (5) -> T6;
463    (6) -> T7;
464    (7) -> T8;
465    (8) -> T9;
466    (9) -> T10;
467    (10) -> T11;
468    (11) -> T12;
469    (12) -> T13;
470);
471
472impl_from_row_for_tuple!(
473    (0) -> T1;
474    (1) -> T2;
475    (2) -> T3;
476    (3) -> T4;
477    (4) -> T5;
478    (5) -> T6;
479    (6) -> T7;
480    (7) -> T8;
481    (8) -> T9;
482    (9) -> T10;
483    (10) -> T11;
484    (11) -> T12;
485    (12) -> T13;
486    (13) -> T14;
487);
488
489impl_from_row_for_tuple!(
490    (0) -> T1;
491    (1) -> T2;
492    (2) -> T3;
493    (3) -> T4;
494    (4) -> T5;
495    (5) -> T6;
496    (6) -> T7;
497    (7) -> T8;
498    (8) -> T9;
499    (9) -> T10;
500    (10) -> T11;
501    (11) -> T12;
502    (12) -> T13;
503    (13) -> T14;
504    (14) -> T15;
505);
506
507impl_from_row_for_tuple!(
508    (0) -> T1;
509    (1) -> T2;
510    (2) -> T3;
511    (3) -> T4;
512    (4) -> T5;
513    (5) -> T6;
514    (6) -> T7;
515    (7) -> T8;
516    (8) -> T9;
517    (9) -> T10;
518    (10) -> T11;
519    (11) -> T12;
520    (12) -> T13;
521    (13) -> T14;
522    (14) -> T15;
523    (15) -> T16;
524);