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/// #### `default`
69///
70/// When your struct contains a field that is not present in your query,
71/// if the field type has an implementation for [`Default`],
72/// you can use the `default` attribute to assign the default value to said field.
73/// For example:
74///
75/// ```rust,ignore
76/// #[derive(sqlx::FromRow)]
77/// struct User {
78///     id: i32,
79///     name: String,
80///     #[sqlx(default)]
81///     location: Option<String>
82/// }
83/// ```
84///
85/// Given a query such as:
86///
87/// ```sql
88/// SELECT id, name FROM users;
89/// ```
90///
91/// will set the value of the field `location` to the default value of `Option<String>`,
92/// which is `None`.
93///
94/// Moreover, if the struct has an implementation for [`Default`], you can use the `default`
95/// attribute at the struct level rather than for each single field. If a field does not appear in the result,
96/// its value is taken from the `Default` implementation for the struct.
97/// For example:
98///
99/// ```rust, ignore
100/// #[derive(Default, sqlx::FromRow)]
101/// #[sqlx(default)]
102/// struct Options {
103///     option_a: Option<i32>,
104///     option_b: Option<String>,
105///     option_c: Option<bool>,
106/// }
107/// ```
108///
109/// For a derived `Default` implementation this effectively populates each missing field
110/// with `Default::default()`, but a manual `Default` implementation can provide
111/// different placeholder values, if applicable.
112///
113/// This is similar to how `#[serde(default)]` behaves.
114/// ### `flatten`
115///
116/// If you want to handle a field that implements [`FromRow`],
117/// you can use the `flatten` attribute to specify that you want
118/// it to use [`FromRow`] for parsing rather than the usual method.
119/// For example:
120///
121/// ```rust,ignore
122/// #[derive(sqlx::FromRow)]
123/// struct Address {
124///     country: String,
125///     city: String,
126///     road: String,
127/// }
128///
129/// #[derive(sqlx::FromRow)]
130/// struct User {
131///     id: i32,
132///     name: String,
133///     #[sqlx(flatten)]
134///     address: Address,
135/// }
136/// ```
137/// Given a query such as:
138///
139/// ```sql
140/// SELECT id, name, country, city, road FROM users;
141/// ```
142///
143/// This field is compatible with the `default` attribute.
144///
145/// #### `skip`
146///
147/// This is a variant of the `default` attribute which instead always takes the value from
148/// the `Default` implementation for this field type ignoring any results in your query.
149/// This can be useful, if some field does not satifisfy the trait bounds (i.e.
150/// `sqlx::decode::Decode`, `sqlx::type::Type`), in particular in case of nested structures.
151/// For example:
152///
153/// ```rust,ignore
154/// #[derive(sqlx::FromRow)]
155/// struct Address {
156///     user_name: String,
157///     street: String,
158///     city: String,
159/// }
160///
161/// #[derive(sqlx::FromRow)]
162/// struct User {
163///     name: String,
164///     #[sqlx(skip)]
165///     addresses: Vec<Address>,
166/// }
167/// ```
168///
169/// Then when querying into `User`, only `name` needs to be set:
170///
171/// ```rust,ignore
172/// let user: User = sqlx::query_as("SELECT name FROM users")
173///    .fetch_one(&mut some_connection)
174///    .await?;
175///
176/// // `Default` for `Vec<Address>` is an empty vector.
177/// assert!(user.addresses.is_empty());
178/// ```
179///
180/// ## Manual implementation
181///
182/// You can also implement the [`FromRow`] trait by hand. This can be useful if you
183/// have a struct with a field that needs manual decoding:
184///
185///
186/// ```rust,ignore
187/// use sqlx::{FromRow, sqlite::SqliteRow, sqlx::Row};
188/// struct MyCustomType {
189///     custom: String,
190/// }
191///
192/// struct Foo {
193///     bar: MyCustomType,
194/// }
195///
196/// impl FromRow<'_, SqliteRow> for Foo {
197///     fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
198///         Ok(Self {
199///             bar: MyCustomType {
200///                 custom: row.try_get("custom")?
201///             }
202///         })
203///     }
204/// }
205/// ```
206///
207/// #### `try_from`
208///
209/// When your struct contains a field whose type is not matched with the database type,
210/// if the field type has an implementation [`TryFrom`] for the database type,
211/// you can use the `try_from` attribute to convert the database type to the field type.
212/// For example:
213///
214/// ```rust,ignore
215/// #[derive(sqlx::FromRow)]
216/// struct User {
217///     id: i32,
218///     name: String,
219///     #[sqlx(try_from = "i64")]
220///     bigIntInMySql: u64
221/// }
222/// ```
223///
224/// Given a query such as:
225///
226/// ```sql
227/// SELECT id, name, bigIntInMySql FROM users;
228/// ```
229///
230/// In MySql, `BigInt` type matches `i64`, but you can convert it to `u64` by `try_from`.
231///
232/// #### `json`
233///
234/// If your database supports a JSON type, you can leverage `#[sqlx(json)]`
235/// to automatically integrate JSON deserialization in your [`FromRow`] implementation using [`serde`](https://docs.rs/serde/latest/serde/).
236///
237/// ```rust,ignore
238/// #[derive(serde::Deserialize)]
239/// struct Data {
240///     field1: String,
241///     field2: u64
242/// }
243///
244/// #[derive(sqlx::FromRow)]
245/// struct User {
246///     id: i32,
247///     name: String,
248///     #[sqlx(json)]
249///     metadata: Data
250/// }
251/// ```
252///
253/// Given a query like the following:
254///
255/// ```sql
256/// SELECT
257///     1 AS id,
258///     'Name' AS name,
259///     JSON_OBJECT('field1', 'value1', 'field2', 42) AS metadata
260/// ```
261///
262/// The `metadata` field will be deserialized used its `serde::Deserialize` implementation:
263///
264/// ```rust,ignore
265/// User {
266///     id: 1,
267///     name: "Name",
268///     metadata: Data {
269///         field1: "value1",
270///         field2: 42
271///     }
272/// }
273/// ```
274pub trait FromRow<'r, R: Row>: Sized {
275    fn from_row(row: &'r R) -> Result<Self, Error>;
276}
277
278impl<'r, R> FromRow<'r, R> for ()
279where
280    R: Row,
281{
282    #[inline]
283    fn from_row(_: &'r R) -> Result<Self, Error> {
284        Ok(())
285    }
286}
287
288// implement FromRow for tuples of types that implement Decode
289// up to tuples of 9 values
290
291macro_rules! impl_from_row_for_tuple {
292    ($( ($idx:tt) -> $T:ident );+;) => {
293        impl<'r, R, $($T,)+> FromRow<'r, R> for ($($T,)+)
294        where
295            R: Row,
296            usize: crate::column::ColumnIndex<R>,
297            $($T: crate::decode::Decode<'r, R::Database> + crate::types::Type<R::Database>,)+
298        {
299            #[inline]
300            fn from_row(row: &'r R) -> Result<Self, Error> {
301                Ok(($(row.try_get($idx as usize)?,)+))
302            }
303        }
304    };
305}
306
307impl_from_row_for_tuple!(
308    (0) -> T1;
309);
310
311impl_from_row_for_tuple!(
312    (0) -> T1;
313    (1) -> T2;
314);
315
316impl_from_row_for_tuple!(
317    (0) -> T1;
318    (1) -> T2;
319    (2) -> T3;
320);
321
322impl_from_row_for_tuple!(
323    (0) -> T1;
324    (1) -> T2;
325    (2) -> T3;
326    (3) -> T4;
327);
328
329impl_from_row_for_tuple!(
330    (0) -> T1;
331    (1) -> T2;
332    (2) -> T3;
333    (3) -> T4;
334    (4) -> T5;
335);
336
337impl_from_row_for_tuple!(
338    (0) -> T1;
339    (1) -> T2;
340    (2) -> T3;
341    (3) -> T4;
342    (4) -> T5;
343    (5) -> T6;
344);
345
346impl_from_row_for_tuple!(
347    (0) -> T1;
348    (1) -> T2;
349    (2) -> T3;
350    (3) -> T4;
351    (4) -> T5;
352    (5) -> T6;
353    (6) -> T7;
354);
355
356impl_from_row_for_tuple!(
357    (0) -> T1;
358    (1) -> T2;
359    (2) -> T3;
360    (3) -> T4;
361    (4) -> T5;
362    (5) -> T6;
363    (6) -> T7;
364    (7) -> T8;
365);
366
367impl_from_row_for_tuple!(
368    (0) -> T1;
369    (1) -> T2;
370    (2) -> T3;
371    (3) -> T4;
372    (4) -> T5;
373    (5) -> T6;
374    (6) -> T7;
375    (7) -> T8;
376    (8) -> T9;
377);
378
379impl_from_row_for_tuple!(
380    (0) -> T1;
381    (1) -> T2;
382    (2) -> T3;
383    (3) -> T4;
384    (4) -> T5;
385    (5) -> T6;
386    (6) -> T7;
387    (7) -> T8;
388    (8) -> T9;
389    (9) -> T10;
390);
391
392impl_from_row_for_tuple!(
393    (0) -> T1;
394    (1) -> T2;
395    (2) -> T3;
396    (3) -> T4;
397    (4) -> T5;
398    (5) -> T6;
399    (6) -> T7;
400    (7) -> T8;
401    (8) -> T9;
402    (9) -> T10;
403    (10) -> T11;
404);
405
406impl_from_row_for_tuple!(
407    (0) -> T1;
408    (1) -> T2;
409    (2) -> T3;
410    (3) -> T4;
411    (4) -> T5;
412    (5) -> T6;
413    (6) -> T7;
414    (7) -> T8;
415    (8) -> T9;
416    (9) -> T10;
417    (10) -> T11;
418    (11) -> T12;
419);
420
421impl_from_row_for_tuple!(
422    (0) -> T1;
423    (1) -> T2;
424    (2) -> T3;
425    (3) -> T4;
426    (4) -> T5;
427    (5) -> T6;
428    (6) -> T7;
429    (7) -> T8;
430    (8) -> T9;
431    (9) -> T10;
432    (10) -> T11;
433    (11) -> T12;
434    (12) -> T13;
435);
436
437impl_from_row_for_tuple!(
438    (0) -> T1;
439    (1) -> T2;
440    (2) -> T3;
441    (3) -> T4;
442    (4) -> T5;
443    (5) -> T6;
444    (6) -> T7;
445    (7) -> T8;
446    (8) -> T9;
447    (9) -> T10;
448    (10) -> T11;
449    (11) -> T12;
450    (12) -> T13;
451    (13) -> T14;
452);
453
454impl_from_row_for_tuple!(
455    (0) -> T1;
456    (1) -> T2;
457    (2) -> T3;
458    (3) -> T4;
459    (4) -> T5;
460    (5) -> T6;
461    (6) -> T7;
462    (7) -> T8;
463    (8) -> T9;
464    (9) -> T10;
465    (10) -> T11;
466    (11) -> T12;
467    (12) -> T13;
468    (13) -> T14;
469    (14) -> T15;
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    (14) -> T15;
488    (15) -> T16;
489);