Save custom ActiveModel

This commit is contained in:
Chris Tsang 2021-06-05 21:36:33 +08:00
parent cf0127d89f
commit 890464f913
10 changed files with 85 additions and 18 deletions

View File

@ -4,15 +4,15 @@ mod example_cake;
mod example_cake_filling; mod example_cake_filling;
mod example_filling; mod example_filling;
mod example_fruit; mod example_fruit;
mod select;
mod operation; mod operation;
mod select;
use example_cake as cake; use example_cake as cake;
use example_cake_filling as cake_filling; use example_cake_filling as cake_filling;
use example_filling as filling; use example_filling as filling;
use example_fruit as fruit; use example_fruit as fruit;
use select::*;
use operation::*; use operation::*;
use select::*;
#[async_std::main] #[async_std::main]
async fn main() { async fn main() {

View File

@ -2,6 +2,14 @@ use crate::*;
use sea_orm::{entity::*, query::*, Database}; use sea_orm::{entity::*, query::*, Database};
pub async fn all_about_operation(db: &Database) -> Result<(), ExecErr> { pub async fn all_about_operation(db: &Database) -> Result<(), ExecErr> {
save_active_model(db).await?;
save_custom_active_model(db).await?;
Ok(())
}
pub async fn save_active_model(db: &Database) -> Result<(), ExecErr> {
let banana = fruit::ActiveModel { let banana = fruit::ActiveModel {
name: Val::set("banana".to_owned()), name: Val::set("banana".to_owned()),
..Default::default() ..Default::default()
@ -20,3 +28,30 @@ pub async fn all_about_operation(db: &Database) -> Result<(), ExecErr> {
Ok(()) Ok(())
} }
mod form {
use super::fruit::*;
use sea_orm::entity::prelude::*;
#[derive(
Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, DeriveActiveModelBehavior,
)]
pub struct Model {
pub id: i32,
pub name: String,
}
}
async fn save_custom_active_model(db: &Database) -> Result<(), ExecErr> {
let pineapple = form::ActiveModel {
id: Val::unset(),
name: Val::set("pineapple".to_owned()),
};
let pineapple = pineapple.save(db).await?;
println!();
println!("Updated: {:?}\n", pineapple);
Ok(())
}

View File

@ -11,7 +11,7 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
}) => named.named, }) => named.named,
_ => { _ => {
return Ok(quote_spanned! { return Ok(quote_spanned! {
ident.span() => compile_error!("you can only derive DeriveModel on structs"); ident.span() => compile_error!("you can only derive DeriveActiveModel on structs");
}) })
} }
}; };
@ -48,8 +48,8 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
} }
} }
impl From<#ident> for ActiveModel { impl From<<Entity as EntityTrait>::Model> for ActiveModel {
fn from(m: #ident) -> Self { fn from(m: <Entity as EntityTrait>::Model) -> Self {
Self { Self {
#(#field: sea_orm::unchanged_active_value_not_intended_for_public_use(m.#field)),* #(#field: sea_orm::unchanged_active_value_not_intended_for_public_use(m.#field)),*
} }
@ -61,31 +61,36 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
fn take(&mut self, c: <Self::Entity as EntityTrait>::Column) -> sea_orm::ActiveValue<sea_orm::Value> { fn take(&mut self, c: <Self::Entity as EntityTrait>::Column) -> sea_orm::ActiveValue<sea_orm::Value> {
match c { match c {
#(<Self::Entity as EntityTrait>::Column::#name => std::mem::take(&mut self.#field).into_wrapped_value()),* #(<Self::Entity as EntityTrait>::Column::#name => std::mem::take(&mut self.#field).into_wrapped_value(),)*
_ => sea_orm::ActiveValue::unset(),
} }
} }
fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> sea_orm::ActiveValue<sea_orm::Value> { fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> sea_orm::ActiveValue<sea_orm::Value> {
match c { match c {
#(<Self::Entity as EntityTrait>::Column::#name => self.#field.clone().into_wrapped_value()),* #(<Self::Entity as EntityTrait>::Column::#name => self.#field.clone().into_wrapped_value(),)*
_ => sea_orm::ActiveValue::unset(),
} }
} }
fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: sea_orm::Value) { fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: sea_orm::Value) {
match c { match c {
#(<Self::Entity as EntityTrait>::Column::#name => self.#field = sea_orm::ActiveValue::set(v.unwrap())),* #(<Self::Entity as EntityTrait>::Column::#name => self.#field = sea_orm::ActiveValue::set(v.unwrap()),)*
_ => panic!("This ActiveModel does not have this field"),
} }
} }
fn unset(&mut self, c: <Self::Entity as EntityTrait>::Column) { fn unset(&mut self, c: <Self::Entity as EntityTrait>::Column) {
match c { match c {
#(<Self::Entity as EntityTrait>::Column::#name => self.#field = sea_orm::ActiveValue::unset()),* #(<Self::Entity as EntityTrait>::Column::#name => self.#field = sea_orm::ActiveValue::unset(),)*
_ => {},
} }
} }
fn is_unset(&self, c: <Self::Entity as EntityTrait>::Column) -> bool { fn is_unset(&self, c: <Self::Entity as EntityTrait>::Column) -> bool {
match c { match c {
#(<Self::Entity as EntityTrait>::Column::#name => self.#field.is_unset()),* #(<Self::Entity as EntityTrait>::Column::#name => self.#field.is_unset(),)*
_ => panic!("This ActiveModel does not have this field"),
} }
} }

View File

@ -0,0 +1,11 @@
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::Data;
pub fn expand_derive_active_model_behavior(_ident: Ident, _data: Data) -> syn::Result<TokenStream> {
Ok(quote!(
impl sea_orm::ActiveModelBehavior for ActiveModel {
type Entity = Entity;
}
))
}

View File

@ -1,4 +1,5 @@
mod active_model; mod active_model;
mod active_model_behavior;
mod column; mod column;
mod entity; mod entity;
mod from_query_result; mod from_query_result;
@ -6,6 +7,7 @@ mod model;
mod primary_key; mod primary_key;
pub use active_model::*; pub use active_model::*;
pub use active_model_behavior::*;
pub use column::*; pub use column::*;
pub use entity::*; pub use entity::*;
pub use from_query_result::*; pub use from_query_result::*;

View File

@ -33,13 +33,15 @@ pub fn expand_derive_model(ident: Ident, data: Data) -> syn::Result<TokenStream>
fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> sea_orm::Value { fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> sea_orm::Value {
match c { match c {
#(<Self::Entity as EntityTrait>::Column::#name => self.#field.clone().into()),* #(<Self::Entity as EntityTrait>::Column::#name => self.#field.clone().into(),)*
_ => panic!("This Model does not have this field"),
} }
} }
fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: sea_orm::Value) { fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: sea_orm::Value) {
match c { match c {
#(<Self::Entity as EntityTrait>::Column::#name => self.#field = v.unwrap()),* #(<Self::Entity as EntityTrait>::Column::#name => self.#field = v.unwrap(),)*
_ => panic!("This Model does not have this field"),
} }
} }
} }

View File

@ -55,6 +55,16 @@ pub fn derive_active_model(input: TokenStream) -> TokenStream {
} }
} }
#[proc_macro_derive(DeriveActiveModelBehavior)]
pub fn derive_active_model_behavior(input: TokenStream) -> TokenStream {
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
match derives::expand_derive_active_model_behavior(ident, data) {
Ok(ts) => ts.into(),
Err(e) => e.to_compile_error().into(),
}
}
#[proc_macro_derive(FromQueryResult)] #[proc_macro_derive(FromQueryResult)]
pub fn derive_from_query_result(input: TokenStream) -> TokenStream { pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
let DeriveInput { ident, data, .. } = parse_macro_input!(input); let DeriveInput { ident, data, .. } = parse_macro_input!(input);

View File

@ -1,6 +1,7 @@
pub use crate::{ pub use crate::{
ActiveModelBehavior, ActiveModelTrait, ColumnTrait, ColumnType, DeriveActiveModel, ActiveModelBehavior, ActiveModelTrait, ColumnTrait, ColumnType, DeriveActiveModel,
DeriveColumn, DeriveEntity, DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, DeriveActiveModelBehavior, DeriveColumn, DeriveEntity, DeriveModel, DerivePrimaryKey,
Iden, IdenStatic, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait, PrimaryKeyToColumn,
Related, RelationDef, RelationTrait, Select, TypeErr, Value, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select,
TypeErr, Value,
}; };

View File

@ -13,7 +13,8 @@ pub use entity::*;
pub use query::*; pub use query::*;
pub use sea_orm_macros::{ pub use sea_orm_macros::{
DeriveActiveModel, DeriveColumn, DeriveEntity, DeriveModel, DerivePrimaryKey, FromQueryResult, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveEntity, DeriveModel,
DerivePrimaryKey, FromQueryResult,
}; };
pub use sea_query; pub use sea_query;
pub use sea_query::Iden; pub use sea_query::Iden;

View File

@ -20,4 +20,4 @@ pub use select::*;
pub use traits::*; pub use traits::*;
pub use update::*; pub use update::*;
pub use crate::connector::{QueryErr, ExecErr}; pub use crate::connector::{ExecErr, QueryErr};