Update Statement
This commit is contained in:
parent
2169d1284f
commit
f706eb261d
@ -50,7 +50,14 @@ pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenS
|
||||
impl sea_orm::PrimaryKeyToColumn<Entity> for #ident {
|
||||
fn into_column(self) -> <Entity as EntityTrait>::Column {
|
||||
match self {
|
||||
#(Self::#variant => Column::#variant),*
|
||||
#(Self::#variant => Column::#variant,)*
|
||||
}
|
||||
}
|
||||
|
||||
fn from_column(col: <Entity as EntityTrait>::Column) -> Option<Self> {
|
||||
match col {
|
||||
#(Column::#variant => Some(Self::#variant),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unchanged(&self) -> bool {
|
||||
matches!(self.state, ActiveValueState::Unchanged)
|
||||
}
|
||||
|
||||
pub fn unset() -> Self {
|
||||
Self {
|
||||
value: V::default(),
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
ActiveModelTrait, ColumnTrait, FromQueryResult, Insert, ModelTrait,
|
||||
OneOrManyActiveModel, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, RelationBuilder,
|
||||
RelationTrait, RelationType, Select,
|
||||
ActiveModelTrait, ColumnTrait, FromQueryResult, Insert, ModelTrait, OneOrManyActiveModel,
|
||||
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, RelationBuilder, RelationTrait, RelationType,
|
||||
Select,
|
||||
};
|
||||
use sea_query::{Iden, IntoValueTuple};
|
||||
use std::fmt::Debug;
|
||||
|
@ -1,6 +1,6 @@
|
||||
pub use crate::{
|
||||
ActiveModelTrait, ColumnTrait, ColumnType, DeriveActiveModel, DeriveColumn,
|
||||
DeriveEntity, DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden,
|
||||
IdenStatic, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related,
|
||||
RelationDef, RelationTrait, Select, TypeErr, Value,
|
||||
ActiveModelTrait, ColumnTrait, ColumnType, DeriveActiveModel, DeriveColumn, DeriveEntity,
|
||||
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait,
|
||||
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef,
|
||||
RelationTrait, Select, TypeErr, Value,
|
||||
};
|
||||
|
@ -7,4 +7,6 @@ where
|
||||
E: EntityTrait,
|
||||
{
|
||||
fn into_column(self) -> E::Column;
|
||||
|
||||
fn from_column(col: E::Column) -> Option<Self> where Self: std::marker::Sized;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ where
|
||||
|
||||
impl<A> Default for Insert<A>
|
||||
where
|
||||
A: ActiveModelTrait
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
@ -50,7 +50,7 @@ where
|
||||
} else if self.columns[idx] != av.is_set() {
|
||||
panic!("columns mismatch");
|
||||
}
|
||||
if !av.is_unset() {
|
||||
if av.is_set() {
|
||||
columns.push(col);
|
||||
values.push(av.into_value());
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ mod json;
|
||||
mod result;
|
||||
mod select;
|
||||
mod traits;
|
||||
// mod update;
|
||||
mod update;
|
||||
|
||||
// pub use combine::*;
|
||||
pub use helper::*;
|
||||
@ -18,4 +18,4 @@ pub use json::*;
|
||||
pub use result::*;
|
||||
pub use select::*;
|
||||
pub use traits::*;
|
||||
// pub use update::*;
|
||||
pub use update::*;
|
||||
|
132
src/query/update.rs
Normal file
132
src/query/update.rs
Normal file
@ -0,0 +1,132 @@
|
||||
use crate::{
|
||||
ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter,
|
||||
QueryTrait,
|
||||
};
|
||||
use sea_query::{IntoIden, UpdateStatement};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Update<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
pub(crate) query: UpdateStatement,
|
||||
pub(crate) model: A,
|
||||
}
|
||||
|
||||
impl<A> Update<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
pub fn new<M>(model: M) -> Self
|
||||
where
|
||||
M: Into<A>,
|
||||
{
|
||||
let myself = Self {
|
||||
query: UpdateStatement::new()
|
||||
.table(A::Entity::default().into_iden())
|
||||
.to_owned(),
|
||||
model: model.into(),
|
||||
};
|
||||
myself.prepare()
|
||||
}
|
||||
|
||||
pub(crate) fn prepare(mut self) -> Self {
|
||||
for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {
|
||||
let col = key.into_column();
|
||||
let av = self.model.get(col);
|
||||
if av.is_set() || av.is_unchanged() {
|
||||
self = self.filter(col.eq(av.unwrap()));
|
||||
} else {
|
||||
panic!("PrimaryKey is not set");
|
||||
}
|
||||
}
|
||||
for col in <A::Entity as EntityTrait>::Column::iter() {
|
||||
if <A::Entity as EntityTrait>::PrimaryKey::from_column(col).is_some() {
|
||||
continue;
|
||||
}
|
||||
let av = self.model.get(col);
|
||||
if av.is_set() {
|
||||
self.query.value(col, av.unwrap());
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> QueryFilter for Update<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
type QueryStatement = UpdateStatement;
|
||||
|
||||
fn query(&mut self) -> &mut UpdateStatement {
|
||||
&mut self.query
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> QueryTrait for Update<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
type QueryStatement = UpdateStatement;
|
||||
|
||||
fn query(&mut self) -> &mut UpdateStatement {
|
||||
&mut self.query
|
||||
}
|
||||
|
||||
fn as_query(&self) -> &UpdateStatement {
|
||||
&self.query
|
||||
}
|
||||
|
||||
fn into_query(self) -> UpdateStatement {
|
||||
self.query
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::tests_cfg::{cake, fruit};
|
||||
use crate::{Update, QueryTrait, Val};
|
||||
use sea_query::PostgresQueryBuilder;
|
||||
|
||||
#[test]
|
||||
fn update_1() {
|
||||
assert_eq!(
|
||||
Update::<cake::ActiveModel>::new(cake::ActiveModel {
|
||||
id: Val::set(1),
|
||||
name: Val::set("Apple Pie".to_owned()),
|
||||
})
|
||||
.build(PostgresQueryBuilder)
|
||||
.to_string(),
|
||||
r#"UPDATE "cake" SET "name" = 'Apple Pie' WHERE "cake"."id" = 1"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_2() {
|
||||
assert_eq!(
|
||||
Update::<fruit::ActiveModel>::new(fruit::ActiveModel {
|
||||
id: Val::set(1),
|
||||
name: Val::set("Orange".to_owned()),
|
||||
cake_id: Val::unset(),
|
||||
})
|
||||
.build(PostgresQueryBuilder)
|
||||
.to_string(),
|
||||
r#"UPDATE "fruit" SET "name" = 'Orange' WHERE "fruit"."id" = 1"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_3() {
|
||||
assert_eq!(
|
||||
Update::<fruit::ActiveModel>::new(fruit::ActiveModel {
|
||||
id: Val::set(2),
|
||||
name: Val::unset(),
|
||||
cake_id: Val::set(Some(3)),
|
||||
})
|
||||
.build(PostgresQueryBuilder)
|
||||
.to_string(),
|
||||
r#"UPDATE "fruit" SET "cake_id" = 3 WHERE "fruit"."id" = 2"#,
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user