aboutsummaryrefslogtreecommitdiff
path: root/tosin-macros
diff options
context:
space:
mode:
Diffstat (limited to 'tosin-macros')
-rw-r--r--tosin-macros/src/lib.rs101
1 files changed, 72 insertions, 29 deletions
diff --git a/tosin-macros/src/lib.rs b/tosin-macros/src/lib.rs
index 92945ed..df12069 100644
--- a/tosin-macros/src/lib.rs
+++ b/tosin-macros/src/lib.rs
@@ -207,7 +207,10 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream {
);
*self = new_self;
} else {
- todo!("update existing db item");
+ diesel::update(self as &Self)
+ .set(self as &Self)
+ .execute(connection)
+ .unwrap();
}
}
};
@@ -302,37 +305,76 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream {
}
};
+ // used for both insertable and aschangeset
+ let dsl_eq_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, &'a #ty>>
+ }
+ })
+ .collect();
+ let dsl_eq_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 impl_insertable = {
- 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>>
+ quote! {
+ impl<'a> tosin::db::Insertable<#lowercase_name::table> for &'a #name {
+ type Values = <(#(#dsl_eq_types,)*) as tosin::db::Insertable<#lowercase_name::table>>::Values;
+
+ fn values(self) -> Self::Values {
+ use diesel::ExpressionMethods;
+ (#(#dsl_eq_values,)*).values()
}
- })
- .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))
+ }
+ }
+ };
+
+ let impl_identifiable = {
+ quote! {
+ impl<'a> tosin::db::Identifiable for &'a #name {
+ type Id = Id;
+ fn id(self) -> Id {
+ // TODO this probably isn't good
+ self.id.expect("not actually identifiable if you haven't saved yet")
}
- })
- .collect();
+ }
+ }
+ };
+
+ let impl_has_table = {
quote! {
- impl<'insert> tosin::db::Insertable<#lowercase_name::table> for &'insert #name {
- type Values = <(#(#insertable_types,)*) as tosin::db::Insertable<#lowercase_name::table>>::Values;
+ impl tosin::db::associations::HasTable for #name {
+ type Table = #lowercase_name::table;
+ fn table() -> #lowercase_name::table {
+ #lowercase_name::table
+ }
+ }
+ }
+ };
- fn values(self) -> Self::Values {
+ let impl_as_changeset = {
+ quote! {
+ impl<'a> tosin::db::query_builder::AsChangeset for &'a #name {
+ type Target = #lowercase_name::table;
+ type Changeset = <(#(#dsl_eq_types,)*) as tosin::db::query_builder::AsChangeset>::Changeset;
+
+ fn as_changeset(self) -> Self::Changeset {
use diesel::ExpressionMethods;
- (#(#insertable_values,)*).values()
+ (#(#dsl_eq_values,)*).as_changeset()
}
}
}
@@ -350,11 +392,12 @@ fn impl_model(ast: &syn::DeriveInput) -> TokenStream {
#(#setters)*
}
- #impl_queryable
-
#diesel_table
-
+ #impl_queryable
#impl_insertable
+ #impl_identifiable
+ #impl_has_table
+ #impl_as_changeset
};
gen.into()
}