@@ -103,28 +103,74 @@ impl DeriveModel {
103103 let ident = & self . ident ;
104104 let field_idents = & self . field_idents ;
105105 let column_idents = & self . column_idents ;
106- let field_values: Vec < TokenStream > = column_idents
106+ let field_types = & self . field_types ;
107+ let ignore_attrs = & self . ignore_attrs ;
108+
109+ let ( field_readers, field_unwrappers) : ( Vec < TokenStream > , Vec < TokenStream > ) = field_idents
107110 . iter ( )
108- . zip ( & self . ignore_attrs )
109- . map ( |( column_ident, ignore) | {
110- if * ignore {
111- quote ! {
112- Default :: default ( )
113- }
111+ . zip ( column_idents)
112+ . zip ( field_types)
113+ . zip ( ignore_attrs)
114+ . map ( |( ( ( field_ident, column_ident) , field_type) , & ignore) | {
115+ if ignore {
116+ let reader = quote ! {
117+ let #field_ident: Option <( ) > = None ;
118+ } ;
119+ let unwrapper = quote ! {
120+ #field_ident: Default :: default ( )
121+ } ;
122+ ( reader, unwrapper)
114123 } else {
115- quote ! {
116- row. try_get( pre, sea_orm:: IdenStatic :: as_str( & <<Self as sea_orm:: ModelTrait >:: Entity as sea_orm:: entity:: EntityTrait >:: Column :: #column_ident) . into( ) ) ?
117- }
124+ let reader = quote ! {
125+ let #field_ident =
126+ row. try_get_nullable:: <Option <#field_type>>(
127+ pre,
128+ sea_orm:: IdenStatic :: as_str(
129+ & <<Self as sea_orm:: ModelTrait >:: Entity
130+ as sea_orm:: entity:: EntityTrait >:: Column :: #column_ident
131+ ) . into( )
132+ ) ?;
133+ } ;
134+ let unwrapper = quote ! {
135+ #field_ident: #field_ident. ok_or_else( || sea_orm:: DbErr :: Type (
136+ format!(
137+ "Missing value for column '{}'" ,
138+ sea_orm:: IdenStatic :: as_str(
139+ & <<Self as sea_orm:: ModelTrait >:: Entity
140+ as sea_orm:: entity:: EntityTrait >:: Column :: #column_ident
141+ )
142+ )
143+ ) ) ?
144+ } ;
145+ ( reader, unwrapper)
118146 }
119147 } )
120- . collect ( ) ;
148+ . unzip ( ) ;
149+
150+ let all_null_check = field_idents
151+ . iter ( )
152+ . zip ( ignore_attrs. iter ( ) . cloned ( ) )
153+ . filter ( |( _, ignore) | !ignore)
154+ . fold ( quote ! { true } , |acc, ( field_ident, _) | {
155+ quote ! { #acc && #field_ident. is_none( ) }
156+ } ) ;
121157
122158 quote ! (
123159 #[ automatically_derived]
124160 impl sea_orm:: FromQueryResult for #ident {
125161 fn from_query_result( row: & sea_orm:: QueryResult , pre: & str ) -> std:: result:: Result <Self , sea_orm:: DbErr > {
162+ Self :: from_query_result_nullable( row, pre) . map_err( |e| e. into( ) )
163+ }
164+
165+ fn from_query_result_nullable( row: & sea_orm:: QueryResult , pre: & str ) -> std:: result:: Result <Self , sea_orm:: TryGetError > {
166+ #( #field_readers) *
167+
168+ if #all_null_check {
169+ return Err ( sea_orm:: TryGetError :: Null ( "All fields of nested model are null" . into( ) ) ) ;
170+ }
171+
126172 Ok ( Self {
127- #( #field_idents : #field_values ) , *
173+ #( #field_unwrappers ) , *
128174 } )
129175 }
130176 }
0 commit comments