From bdfdcb98d39d1887b08748e1ea629f0a83f340a4 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Wed, 30 Jun 2021 13:22:31 -0600 Subject: impl Insertable for models --- tosin-macros/src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'tosin-macros/src') 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> + } + }) + .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() } -- cgit v1.2.3