ActiveValue

This commit is contained in:
Chris Tsang 2021-05-28 13:09:31 +08:00
parent d3ee74cbe5
commit b1afd5da3e
4 changed files with 81 additions and 31 deletions

View File

@ -33,7 +33,7 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
Ok(quote!(
#[derive(Clone, Debug)]
pub struct ActiveModel {
#(pub #field: sea_orm::Action<#ty>),*
#(pub #field: sea_orm::ActiveValue<#ty>),*
}
impl sea_orm::ActiveModelOf<Entity> for ActiveModel {}
@ -41,7 +41,7 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
impl From<#ident> for ActiveModel {
fn from(m: #ident) -> Self {
Self {
#(#field: sea_orm::Action::Set(m.#field)),*
#(#field: sea_orm::ActiveValue::set(m.#field)),*
}
}
}
@ -49,27 +49,27 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
impl sea_orm::ActiveModelTrait for ActiveModel {
type Column = Column;
fn take(&mut self, c: Self::Column) -> sea_orm::Action<sea_orm::Value> {
fn take(&mut self, c: Self::Column) -> sea_orm::ActiveValue<sea_orm::Value> {
match c {
#(Self::Column::#name => std::mem::take(&mut self.#field).into_action_value()),*
#(Self::Column::#name => std::mem::take(&mut self.#field).into_wrapped_value()),*
}
}
fn get(&self, c: Self::Column) -> sea_orm::Action<sea_orm::Value> {
fn get(&self, c: Self::Column) -> sea_orm::ActiveValue<sea_orm::Value> {
match c {
#(Self::Column::#name => self.#field.clone().into_action_value()),*
#(Self::Column::#name => self.#field.clone().into_wrapped_value()),*
}
}
fn set(&mut self, c: Self::Column, v: sea_orm::Value) {
match c {
#(Self::Column::#name => self.#field = sea_orm::Action::Set(v.unwrap())),*
#(Self::Column::#name => self.#field = sea_orm::ActiveValue::set(v.unwrap())),*
}
}
fn unset(&mut self, c: Self::Column) {
match c {
#(Self::Column::#name => self.#field = sea_orm::Action::Unset),*
#(Self::Column::#name => self.#field = sea_orm::ActiveValue::unset()),*
}
}
}

View File

@ -1,26 +1,75 @@
use crate::{ColumnTrait, EntityTrait, Value};
use std::fmt::Debug;
#[derive(Clone, Debug, Default)]
pub struct ActiveValue<V>
where
V: Default,
{
value: V,
state: ActiveValueState,
}
#[derive(Clone, Debug)]
pub enum Action<V> {
Set(V),
pub enum ActiveValueState {
Set,
Unset,
}
impl<V> Default for Action<V> {
impl Default for ActiveValueState {
fn default() -> Self {
Self::Unset
}
}
impl<V> Action<V>
impl<V> ActiveValue<V>
where
V: Into<Value>,
V: Default,
{
pub fn into_action_value(self) -> Action<Value> {
match self {
Self::Set(v) => Action::Set(v.into()),
Self::Unset => Action::Unset,
pub fn set(value: V) -> Self {
Self {
value,
state: ActiveValueState::Set,
}
}
pub fn is_set(&self) -> bool {
matches!(self.state, ActiveValueState::Set)
}
pub fn unset() -> Self {
Self {
value: V::default(),
state: ActiveValueState::Unset,
}
}
pub fn is_unset(&self) -> bool {
matches!(self.state, ActiveValueState::Unset)
}
pub fn take(&mut self) -> V {
self.state = ActiveValueState::Unset;
std::mem::take(&mut self.value)
}
pub fn unwrap(self) -> V {
self.value
}
}
impl<V> ActiveValue<V>
where
V: Default + Into<Value>,
{
pub fn into_value(self) -> Value {
self.value.into()
}
pub fn into_wrapped_value(self) -> ActiveValue<Value> {
match self.state {
ActiveValueState::Set => ActiveValue::set(self.into_value()),
ActiveValueState::Unset => ActiveValue::unset(),
}
}
}
@ -34,9 +83,9 @@ where
pub trait ActiveModelTrait: Clone + Debug {
type Column: ColumnTrait;
fn take(&mut self, c: Self::Column) -> Action<Value>;
fn take(&mut self, c: Self::Column) -> ActiveValue<Value>;
fn get(&self, c: Self::Column) -> Action<Value>;
fn get(&self, c: Self::Column) -> ActiveValue<Value>;
fn set(&mut self, c: Self::Column, v: Value);

View File

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

View File

@ -1,4 +1,4 @@
use crate::{Action, ActiveModelOf, ActiveModelTrait, EntityTrait, Iterable, Statement};
use crate::{ActiveModelOf, ActiveModelTrait, EntityTrait, Iterable, Statement};
use core::marker::PhantomData;
use sea_query::{InsertStatement, IntoIden, QueryBuilder};
@ -36,9 +36,10 @@ where
let mut columns = Vec::new();
let mut values = Vec::new();
for col in A::Column::iter() {
if let Action::Set(val) = am.take(col) {
let av = am.take(col);
if av.is_set() {
columns.push(col);
values.push(val);
values.push(av.into_value());
}
}
self.query.columns(columns);
@ -73,7 +74,7 @@ where
#[cfg(test)]
mod tests {
use crate::tests_cfg::cake;
use crate::{Action, Insert};
use crate::{ActiveValue, Insert};
use sea_query::PostgresQueryBuilder;
#[test]
@ -81,8 +82,8 @@ mod tests {
assert_eq!(
Insert::<cake::ActiveModel>::new()
.one(cake::ActiveModel {
id: Action::Unset,
name: Action::Set("Apple Pie".to_owned()),
id: ActiveValue::unset(),
name: ActiveValue::set("Apple Pie".to_owned()),
})
.build(PostgresQueryBuilder)
.to_string(),
@ -95,8 +96,8 @@ mod tests {
assert_eq!(
Insert::<cake::ActiveModel>::new()
.one(cake::ActiveModel {
id: Action::Set(1),
name: Action::Set("Apple Pie".to_owned()),
id: ActiveValue::set(1),
name: ActiveValue::set("Apple Pie".to_owned()),
})
.build(PostgresQueryBuilder)
.to_string(),