Support for #[sqlx(default)]

This commit is contained in:
OriolMunoz
2020-07-07 21:51:30 +02:00
committed by Ryan Leckey
parent d58f20f77a
commit 993352e9d4
3 changed files with 41 additions and 5 deletions

View File

@@ -42,6 +42,7 @@ pub struct SqlxContainerAttributes {
pub struct SqlxChildAttributes {
pub rename: Option<String>,
pub default: bool,
}
pub fn parse_container_attributes(input: &[Attribute]) -> syn::Result<SqlxContainerAttributes> {
@@ -116,6 +117,7 @@ pub fn parse_container_attributes(input: &[Attribute]) -> syn::Result<SqlxContai
pub fn parse_child_attributes(input: &[Attribute]) -> syn::Result<SqlxChildAttributes> {
let mut rename = None;
let mut default = false;
for attr in input {
let meta = attr
@@ -132,7 +134,7 @@ pub fn parse_child_attributes(input: &[Attribute]) -> syn::Result<SqlxChildAttri
lit: Lit::Str(val),
..
}) if path.is_ident("rename") => try_set!(rename, val.value(), value),
Meta::Path(path) if path.is_ident("default") => default = true,
u => fail!(u, "unexpected attribute"),
},
u => fail!(u, "unexpected attribute"),
@@ -143,7 +145,7 @@ pub fn parse_child_attributes(input: &[Attribute]) -> syn::Result<SqlxChildAttri
}
}
Ok(SqlxChildAttributes { rename })
Ok(SqlxChildAttributes { rename, default })
}
pub fn check_transparent_attributes(

View File

@@ -81,9 +81,20 @@ fn expand_derive_from_row_struct(
};
let ty = &field.ty;
Some(parse_quote!(
let #id: #ty = row.try_get(#id_s)?;
))
if attributes.default {
Some(
parse_quote!(let #id: #ty = row.try_get(#id_s).or_else(|e| match e {
sqlx_core::error::Error::ColumnNotFound(_) => {
Ok(Default::default())
},
e => Err(e)
})?;),
)
} else {
Some(parse_quote!(
let #id: #ty = row.try_get(#id_s)?;
))
}
});
let names = fields.iter().map(|field| &field.ident);

View File

@@ -381,3 +381,26 @@ async fn test_from_row_with_rename() -> anyhow::Result<()> {
Ok(())
}
#[cfg(feature = "macros")]
#[sqlx_macros::test]
async fn test_default() -> anyhow::Result<()> {
#[derive(Debug, sqlx::FromRow)]
struct HasDefault {
not_default: i32,
#[sqlx(default)]
default: Option<i32>,
}
let mut conn = new::<Postgres>().await?;
let has_default: HasDefault = sqlx::query_as(r#"SELECT 1 AS not_default"#)
.fetch_one(&mut conn)
.await?;
println!("{:?}", has_default);
assert_eq!(has_default.not_default, 1);
assert_eq!(has_default.default, None);
Ok(())
}