diff options
author | Melody Horn <melody@boringcactus.com> | 2021-06-30 13:22:31 -0600 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2021-06-30 13:22:31 -0600 |
commit | bdfdcb98d39d1887b08748e1ea629f0a83f340a4 (patch) | |
tree | 90e3318a04c9f383b3bedd0519ba26be933467f0 /tosin-macros | |
parent | 41d2d919ac27e4f9148d84855c1e591c0b100a11 (diff) | |
download | tosin-bdfdcb98d39d1887b08748e1ea629f0a83f340a4.tar.gz tosin-bdfdcb98d39d1887b08748e1ea629f0a83f340a4.zip |
impl Insertable for models
Diffstat (limited to 'tosin-macros')
-rw-r--r-- | tosin-macros/src/lib.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/tosin-macros/src/lib.rs b/tosin-macros/src/lib.rs index 60803ae..ff62f3d 100644 --- a/tosin-macros/src/lib.rs +++ b/tosin-macros/src/lib.rs @@ -173,6 +173,30 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream { diesel_columns, diesel_types, } = ast_data.fields.iter().map(to_field_spec).collect(); + + let insertable_types: Vec<_> = ast_data + .fields + .iter() + .filter(|field| !is_id(field)) + .map(|field| { + let ident = &field.ident; + let ty = &field.ty; + quote! { + Option<tosin::db::dsl::Eq<#lowercase_name::#ident, &'insert #ty>> + } + }) + .collect(); + let insertable_values: Vec<_> = ast_data + .fields + .iter() + .filter(|field| !is_id(field)) + .map(|field| { + let ident = &field.ident; + quote! { + Some(#lowercase_name::#ident.eq(&self.#ident)) + } + }) + .collect(); let gen = quote! { impl #name { pub const META: ::tosin::db::models::ModelMeta = ::tosin::db::models::ModelMeta { @@ -186,6 +210,19 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream { #(#field_names),* } } + + pub fn save_mut(&mut self, connection: &mut tosin::db::backend::Connection) { + if self.id.is_none() { + // no id yet, so not from db, so insert + let new_self = tosin::db::insert_into(#lowercase_name::table) + .values(&self) + .get_result(connection) + .expect("error saving to database"); // TODO propagate error + *self = new_self; + } else { + todo!("update existing db item"); + } + } } impl<__DB: tosin::db::diesel_backend::Backend, __ST> tosin::db::Queryable<__ST, __DB> for #name @@ -204,6 +241,14 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream { #(#diesel_columns,)* } } + + impl<'insert> tosin::db::Insertable<#lowercase_name::table> for &'insert #name { + type Values = <(#(#insertable_types,)*) as tosin::db::Insertable<#lowercase_name::table>>::Values; + + fn values(self) -> Self::Values { + (#(#insertable_values,)*).values() + } + } }; gen.into() } |