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_filling;
mod example_fruit;
mod select;
mod operation;
mod select;
use example_cake as cake;
use example_cake_filling as cake_filling;
use example_filling as filling;
use example_fruit as fruit;
use select::*;
use operation::*;
use select::*;
#[async_std::main]
async fn main() {

View File

@ -2,6 +2,14 @@ use crate::*;
use sea_orm::{entity::*, query::*, Database};
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 {
name: Val::set("banana".to_owned()),
..Default::default()
@ -19,4 +27,31 @@ pub async fn all_about_operation(db: &Database) -> Result<(), ExecErr> {
println!("Updated: {:?}\n", banana);
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,
_ => {
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 {
fn from(m: #ident) -> Self {
impl From<<Entity as EntityTrait>::Model> for ActiveModel {
fn from(m: <Entity as EntityTrait>::Model) -> Self {
Self {
#(#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> {
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> {
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) {
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) {
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 {
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_behavior;
mod column;
mod entity;
mod from_query_result;
@ -6,6 +7,7 @@ mod model;
mod primary_key;
pub use active_model::*;
pub use active_model_behavior::*;
pub use column::*;
pub use entity::*;
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 {
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) {
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)]
pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
let DeriveInput { ident, data, .. } = parse_macro_input!(input);

View File

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

View File

@ -13,7 +13,8 @@ pub use entity::*;
pub use query::*;
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::Iden;

View File

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