Update Many

This commit is contained in:
Chris Tsang 2021-06-10 00:07:35 +08:00
parent 6809e6ec17
commit 00cad59a0e
4 changed files with 104 additions and 21 deletions

View File

@ -1,4 +1,4 @@
use crate::{ActiveModelTrait, Connection, Database, ExecErr, Statement, Update}; use crate::{ActiveModelTrait, Connection, Database, ExecErr, Statement, UpdateOne};
use sea_query::{QueryBuilder, UpdateStatement}; use sea_query::{QueryBuilder, UpdateStatement};
use std::future::Future; use std::future::Future;
@ -12,7 +12,7 @@ pub struct UpdateResult {
pub rows_affected: u64, pub rows_affected: u64,
} }
impl<'a, A: 'a> Update<A> impl<'a, A: 'a> UpdateOne<A>
where where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
ActiveModelTrait, ColumnTrait, FromQueryResult, Insert, ModelTrait, OneOrManyActiveModel, ActiveModelTrait, ColumnTrait, FromQueryResult, Insert, ModelTrait, OneOrManyActiveModel,
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, RelationBuilder, RelationTrait, RelationType, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, RelationBuilder, RelationTrait, RelationType,
Select, Update, Select, Update, UpdateOne,
}; };
use sea_query::{Iden, IntoValueTuple}; use sea_query::{Iden, IntoValueTuple};
use std::fmt::Debug; use std::fmt::Debug;
@ -211,10 +211,10 @@ pub trait EntityTrait: EntityName {
/// r#"UPDATE "fruit" SET "name" = 'Orange' WHERE "fruit"."id" = 1"#, /// r#"UPDATE "fruit" SET "name" = 'Orange' WHERE "fruit"."id" = 1"#,
/// ); /// );
/// ``` /// ```
fn update<A>(model: A) -> Update<A> fn update<A>(model: A) -> UpdateOne<A>
where where
A: ActiveModelTrait<Entity = Self>, A: ActiveModelTrait<Entity = Self>,
{ {
Update::new(model) Update::one(model)
} }
} }

View File

@ -70,7 +70,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::tests_cfg::{cake, fruit}; use crate::tests_cfg::{cake, fruit};
use crate::{ColumnTrait, EntityTrait, QueryFilter, QueryTrait, SelectHelper}; use crate::{ColumnTrait, EntityTrait, QueryFilter, QueryTrait, QuerySelect};
use sea_query::MysqlQueryBuilder; use sea_query::MysqlQueryBuilder;
#[test] #[test]

View File

@ -2,10 +2,14 @@ use crate::{
ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter, ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter,
QueryTrait, QueryTrait,
}; };
use sea_query::{IntoIden, UpdateStatement}; use sea_query::{IntoIden, SimpleExpr, UpdateStatement};
use core::marker::PhantomData;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Update<A> pub struct Update;
#[derive(Clone, Debug)]
pub struct UpdateOne<A>
where where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
@ -13,23 +17,47 @@ where
pub(crate) model: A, pub(crate) model: A,
} }
impl<A> Update<A> #[derive(Clone, Debug)]
pub struct UpdateMany<E>
where where
A: ActiveModelTrait, E: EntityTrait,
{ {
pub fn new<M>(model: M) -> Self pub(crate) query: UpdateStatement,
pub(crate) entity: PhantomData<E>,
}
impl Update {
pub fn one<E, A>(model: A) -> UpdateOne<A>
where where
M: Into<A>, E: EntityTrait,
A: ActiveModelTrait<Entity = E>,
{ {
let myself = Self { let myself = UpdateOne {
query: UpdateStatement::new() query: UpdateStatement::new()
.table(A::Entity::default().into_iden()) .table(A::Entity::default().into_iden())
.to_owned(), .to_owned(),
model: model.into(), model,
}; };
myself.prepare() myself.prepare()
} }
pub fn many<E>(entity: E) -> UpdateMany<E>
where
E: EntityTrait,
{
UpdateMany {
query: UpdateStatement::new()
.table(entity.into_iden())
.to_owned(),
entity: PhantomData,
}
}
}
impl<A> UpdateOne<A>
where
A: ActiveModelTrait,
{
pub(crate) fn prepare(mut self) -> Self { pub(crate) fn prepare(mut self) -> Self {
for key in <A::Entity as EntityTrait>::PrimaryKey::iter() { for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {
let col = key.into_column(); let col = key.into_column();
@ -53,7 +81,7 @@ where
} }
} }
impl<A> QueryFilter for Update<A> impl<A> QueryFilter for UpdateOne<A>
where where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
@ -64,7 +92,18 @@ where
} }
} }
impl<A> QueryTrait for Update<A> impl<E> QueryFilter for UpdateMany<E>
where
E: EntityTrait,
{
type QueryStatement = UpdateStatement;
fn query(&mut self) -> &mut UpdateStatement {
&mut self.query
}
}
impl<A> QueryTrait for UpdateOne<A>
where where
A: ActiveModelTrait, A: ActiveModelTrait,
{ {
@ -83,16 +122,48 @@ where
} }
} }
impl<E> QueryTrait for UpdateMany<E>
where
E: EntityTrait,
{
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
}
}
impl<E> UpdateMany<E>
where
E: EntityTrait,
{
pub fn col_expr<T>(mut self, col: T, expr: SimpleExpr) -> Self
where
T: IntoIden,
{
self.query.col_expr(col, expr);
self
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::tests_cfg::{cake, fruit}; use crate::tests_cfg::{cake, fruit};
use crate::{ActiveValue, QueryTrait, Update}; use crate::{entity::*, query::*};
use sea_query::PostgresQueryBuilder; use sea_query::{PostgresQueryBuilder, Expr, Value};
#[test] #[test]
fn update_1() { fn update_1() {
assert_eq!( assert_eq!(
Update::<cake::ActiveModel>::new(cake::ActiveModel { Update::one(cake::ActiveModel {
id: ActiveValue::set(1), id: ActiveValue::set(1),
name: ActiveValue::set("Apple Pie".to_owned()), name: ActiveValue::set("Apple Pie".to_owned()),
}) })
@ -105,7 +176,7 @@ mod tests {
#[test] #[test]
fn update_2() { fn update_2() {
assert_eq!( assert_eq!(
Update::<fruit::ActiveModel>::new(fruit::ActiveModel { Update::one(fruit::ActiveModel {
id: ActiveValue::set(1), id: ActiveValue::set(1),
name: ActiveValue::set("Orange".to_owned()), name: ActiveValue::set("Orange".to_owned()),
cake_id: ActiveValue::unset(), cake_id: ActiveValue::unset(),
@ -119,7 +190,7 @@ mod tests {
#[test] #[test]
fn update_3() { fn update_3() {
assert_eq!( assert_eq!(
Update::<fruit::ActiveModel>::new(fruit::ActiveModel { Update::one(fruit::ActiveModel {
id: ActiveValue::set(2), id: ActiveValue::set(2),
name: ActiveValue::unchanged("Apple".to_owned()), name: ActiveValue::unchanged("Apple".to_owned()),
cake_id: ActiveValue::set(Some(3)), cake_id: ActiveValue::set(Some(3)),
@ -129,4 +200,16 @@ mod tests {
r#"UPDATE "fruit" SET "cake_id" = 3 WHERE "fruit"."id" = 2"#, r#"UPDATE "fruit" SET "cake_id" = 3 WHERE "fruit"."id" = 2"#,
); );
} }
#[test]
fn update_4() {
assert_eq!(
Update::many(fruit::Entity)
.col_expr(fruit::Column::CakeId, Expr::value(Value::Null))
.filter(fruit::Column::Name.contains("Apple"))
.build(PostgresQueryBuilder)
.to_string(),
r#"UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%'"#,
);
}
} }