From f4d1a52791d1a62c134ea317fa30d005fec8b5a5 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Tue, 7 Sep 2021 11:11:23 +0800 Subject: [PATCH] Change update behavior, add ActiveModel insert & update --- README.md | 2 +- examples/async-std/src/operation.rs | 2 +- sea-orm-macros/src/derives/active_model.rs | 8 ++++++ src/entity/active_model.rs | 9 ++++--- src/entity/base_entity.rs | 2 +- src/lib.rs | 2 +- src/query/update.rs | 30 ++++++++++++++-------- tests/crud/updates.rs | 12 ++++----- 8 files changed, 43 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index ef69b5d1..4dbf6110 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ let mut pear: fruit::ActiveModel = pear.unwrap().into(); pear.name = Set("Sweet pear".to_owned()); // update one -let pear: fruit::ActiveModel = Fruit::update(pear).exec(db).await?; +let pear: fruit::ActiveModel = pear.update(db).await?; // update many: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%' Fruit::update_many() diff --git a/examples/async-std/src/operation.rs b/examples/async-std/src/operation.rs index 3fa5cc85..34e5441f 100644 --- a/examples/async-std/src/operation.rs +++ b/examples/async-std/src/operation.rs @@ -33,7 +33,7 @@ pub async fn insert_and_update(db: &DbConn) -> Result<(), DbErr> { let mut pear: fruit::ActiveModel = pear.unwrap().into(); pear.name = Set("Sweet pear".to_owned()); - let pear: fruit::ActiveModel = Fruit::update(pear).exec(db).await?; + let pear: fruit::ActiveModel = pear.update(db).await?; println!(); println!("Updated: {:?}\n", pear); diff --git a/sea-orm-macros/src/derives/active_model.rs b/sea-orm-macros/src/derives/active_model.rs index 98bc0aec..bf04421b 100644 --- a/sea-orm-macros/src/derives/active_model.rs +++ b/sea-orm-macros/src/derives/active_model.rs @@ -37,6 +37,14 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result Result { + sea_orm::insert_and_select_active_model::(self, db).await + } + + pub async fn update(self, db: &sea_orm::DatabaseConnection) -> Result { + sea_orm::update_active_model::(self, db).await + } + pub async fn save(self, db: &sea_orm::DatabaseConnection) -> Result { sea_orm::save_active_model::(self, db).await } diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs index f823411c..7eee81f3 100644 --- a/src/entity/active_model.rs +++ b/src/entity/active_model.rs @@ -212,7 +212,10 @@ where Ok(am) } -async fn insert_and_select_active_model(am: A, db: &DatabaseConnection) -> Result +pub async fn insert_and_select_active_model( + am: A, + db: &DatabaseConnection, +) -> Result where A: ActiveModelTrait, E::Model: IntoActiveModel, @@ -240,12 +243,12 @@ where } } -async fn update_active_model(am: A, db: &DatabaseConnection) -> Result +pub async fn update_active_model(am: A, db: &DatabaseConnection) -> Result where A: ActiveModelTrait, E: EntityTrait, { - let exec = E::update(am).exec(db); + let exec = E::update(am).prepare_filters().exec(db); exec.await } diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs index e0f92b09..e09fa0a8 100644 --- a/src/entity/base_entity.rs +++ b/src/entity/base_entity.rs @@ -386,7 +386,7 @@ pub trait EntityTrait: EntityName { /// # let _: Result<(), DbErr> = smol::block_on(async { /// # /// assert_eq!( - /// fruit::Entity::update(orange.clone()).exec(&db).await?, // Clone here because we need to assert_eq + /// orange.clone().update(&db).await?, // Clone here because we need to assert_eq /// orange /// ); /// # diff --git a/src/lib.rs b/src/lib.rs index c1caa60e..44c1be64 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,7 +126,7 @@ //! pear.name = Set("Sweet pear".to_owned()); //! //! // update one -//! let pear: fruit::ActiveModel = Fruit::update(pear).exec(db).await?; +//! let pear: fruit::ActiveModel = pear.update(db).await?; //! //! // update many: UPDATE "fruit" SET "cake_id" = NULL WHERE "fruit"."name" LIKE '%Apple%' //! Fruit::update_many() diff --git a/src/query/update.rs b/src/query/update.rs index 8cd66c37..3500b759 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -37,6 +37,7 @@ impl Update { /// id: ActiveValue::set(1), /// name: ActiveValue::set("Apple Pie".to_owned()), /// }) + /// .filter(cake::Column::Id.eq(1)) /// .build(DbBackend::Postgres) /// .to_string(), /// r#"UPDATE "cake" SET "name" = 'Apple Pie' WHERE "cake"."id" = 1"#, @@ -53,7 +54,7 @@ impl Update { .to_owned(), model, }; - myself.prepare() + myself.prepare_values() } /// Update many ActiveModel @@ -85,16 +86,7 @@ impl UpdateOne where A: ActiveModelTrait, { - pub(crate) fn prepare(mut self) -> Self { - for key in ::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"); - } - } + pub(crate) fn prepare_values(mut self) -> Self { for col in ::Column::iter() { if ::PrimaryKey::from_column(col).is_some() { continue; @@ -106,6 +98,19 @@ where } self } + + pub(crate) fn prepare_filters(mut self) -> Self { + for key in ::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"); + } + } + self + } } impl QueryFilter for UpdateOne @@ -194,6 +199,7 @@ mod tests { id: ActiveValue::set(1), name: ActiveValue::set("Apple Pie".to_owned()), }) + .filter(cake::Column::Id.eq(1)) .build(DbBackend::Postgres) .to_string(), r#"UPDATE "cake" SET "name" = 'Apple Pie' WHERE "cake"."id" = 1"#, @@ -208,6 +214,7 @@ mod tests { name: ActiveValue::set("Orange".to_owned()), cake_id: ActiveValue::unset(), }) + .filter(fruit::Column::Id.eq(1)) .build(DbBackend::Postgres) .to_string(), r#"UPDATE "fruit" SET "name" = 'Orange' WHERE "fruit"."id" = 1"#, @@ -222,6 +229,7 @@ mod tests { name: ActiveValue::unchanged("Apple".to_owned()), cake_id: ActiveValue::set(Some(3)), }) + .filter(fruit::Column::Id.eq(2)) .build(DbBackend::Postgres) .to_string(), r#"UPDATE "fruit" SET "cake_id" = 3 WHERE "fruit"."id" = 2"#, diff --git a/tests/crud/updates.rs b/tests/crud/updates.rs index 83b9a5d3..f4570e5d 100644 --- a/tests/crud/updates.rs +++ b/tests/crud/updates.rs @@ -42,8 +42,8 @@ pub async fn test_update_cake(db: &DbConn) { cake_am.name = Set("Extra chocolate mud cake".to_owned()); cake_am.price = Set(dec!(20.00)); - let _cake_update_res: cake::ActiveModel = Cake::update(cake_am) - .exec(db) + let _cake_update_res: cake::ActiveModel = cake_am + .update(db) .await .expect("could not update cake"); @@ -81,8 +81,8 @@ pub async fn test_update_bakery(db: &DbConn) { bakery_am.name = Set("SeaBreeze Bakery".to_owned()); bakery_am.profit_margin = Set(12.00); - let _bakery_update_res: bakery::ActiveModel = Bakery::update(bakery_am) - .exec(db) + let _bakery_update_res: bakery::ActiveModel = bakery_am + .update(db) .await .expect("could not update bakery"); @@ -123,8 +123,8 @@ pub async fn test_update_deleted_customer(db: &DbConn) { ..Default::default() }; - let _customer_update_res: customer::ActiveModel = Customer::update(customer) - .exec(db) + let _customer_update_res: customer::ActiveModel = customer + .update(db) .await .expect("could not update customer");