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 {
|
impl sea_orm::PrimaryKeyToColumn<Entity> for #ident {
|
||||||
fn into_column(self) -> <Entity as EntityTrait>::Column {
|
fn into_column(self) -> <Entity as EntityTrait>::Column {
|
||||||
match self {
|
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 {
|
pub fn unset() -> Self {
|
||||||
Self {
|
Self {
|
||||||
value: V::default(),
|
value: V::default(),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ActiveModelTrait, ColumnTrait, FromQueryResult, Insert, ModelTrait,
|
ActiveModelTrait, ColumnTrait, FromQueryResult, Insert, ModelTrait, OneOrManyActiveModel,
|
||||||
OneOrManyActiveModel, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, RelationBuilder,
|
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, RelationBuilder, RelationTrait, RelationType,
|
||||||
RelationTrait, RelationType, Select,
|
Select,
|
||||||
};
|
};
|
||||||
use sea_query::{Iden, IntoValueTuple};
|
use sea_query::{Iden, IntoValueTuple};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
ActiveModelTrait, ColumnTrait, ColumnType, DeriveActiveModel, DeriveColumn,
|
ActiveModelTrait, ColumnTrait, ColumnType, DeriveActiveModel, DeriveColumn, DeriveEntity,
|
||||||
DeriveEntity, DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden,
|
DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait,
|
||||||
IdenStatic, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related,
|
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef,
|
||||||
RelationDef, RelationTrait, Select, TypeErr, Value,
|
RelationTrait, Select, TypeErr, Value,
|
||||||
};
|
};
|
||||||
|
@ -7,4 +7,6 @@ where
|
|||||||
E: EntityTrait,
|
E: EntityTrait,
|
||||||
{
|
{
|
||||||
fn into_column(self) -> E::Column;
|
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>
|
impl<A> Default for Insert<A>
|
||||||
where
|
where
|
||||||
A: ActiveModelTrait
|
A: ActiveModelTrait,
|
||||||
{
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
@ -50,7 +50,7 @@ where
|
|||||||
} else if self.columns[idx] != av.is_set() {
|
} else if self.columns[idx] != av.is_set() {
|
||||||
panic!("columns mismatch");
|
panic!("columns mismatch");
|
||||||
}
|
}
|
||||||
if !av.is_unset() {
|
if av.is_set() {
|
||||||
columns.push(col);
|
columns.push(col);
|
||||||
values.push(av.into_value());
|
values.push(av.into_value());
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ mod json;
|
|||||||
mod result;
|
mod result;
|
||||||
mod select;
|
mod select;
|
||||||
mod traits;
|
mod traits;
|
||||||
// mod update;
|
mod update;
|
||||||
|
|
||||||
// pub use combine::*;
|
// pub use combine::*;
|
||||||
pub use helper::*;
|
pub use helper::*;
|
||||||
@ -18,4 +18,4 @@ pub use json::*;
|
|||||||
pub use result::*;
|
pub use result::*;
|
||||||
pub use select::*;
|
pub use select::*;
|
||||||
pub use traits::*;
|
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