From c70c9417127ff784f41aef556a585951c94d99e8 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 10 Jun 2021 01:45:59 +0800 Subject: [PATCH] Refactor Insert one & many --- sea-orm-macros/src/derives/active_model.rs | 6 ++ src/entity/active_model.rs | 16 ++++ src/entity/base.rs | 4 +- src/query/combine.rs | 2 +- src/query/insert.rs | 95 ++++++++++++---------- src/query/update.rs | 16 ++-- 6 files changed, 86 insertions(+), 53 deletions(-) diff --git a/sea-orm-macros/src/derives/active_model.rs b/sea-orm-macros/src/derives/active_model.rs index 76b89639..8fc18874 100644 --- a/sea-orm-macros/src/derives/active_model.rs +++ b/sea-orm-macros/src/derives/active_model.rs @@ -56,6 +56,12 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result for Model { + fn into_active_model(self) -> ActiveModel { + self.into() + } + } + impl sea_orm::ActiveModelTrait for ActiveModel { type Entity = Entity; diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs index d6680ff5..5d9aa7b2 100644 --- a/src/entity/active_model.rs +++ b/src/entity/active_model.rs @@ -92,6 +92,22 @@ pub trait ActiveModelBehavior: ActiveModelTrait { } } +pub trait IntoActiveModel +where + A: ActiveModelTrait, +{ + fn into_active_model(self) -> A; +} + +impl IntoActiveModel for A +where + A: ActiveModelTrait, +{ + fn into_active_model(self) -> A { + self + } +} + impl ActiveValue where V: Into + Default, diff --git a/src/entity/base.rs b/src/entity/base.rs index 98c94ff2..497e22f2 100644 --- a/src/entity/base.rs +++ b/src/entity/base.rs @@ -167,7 +167,7 @@ pub trait EntityTrait: EntityName { where A: ActiveModelTrait, { - Insert::new().one(model) + Insert::one(model) } /// ``` @@ -193,7 +193,7 @@ pub trait EntityTrait: EntityName { A: ActiveModelTrait, I: IntoIterator, { - Insert::new().many(models) + Insert::many(models) } /// ``` diff --git a/src/query/combine.rs b/src/query/combine.rs index 2df02a0f..2cde583f 100644 --- a/src/query/combine.rs +++ b/src/query/combine.rs @@ -70,7 +70,7 @@ where #[cfg(test)] mod tests { use crate::tests_cfg::{cake, fruit}; - use crate::{ColumnTrait, EntityTrait, QueryFilter, QueryTrait, QuerySelect}; + use crate::{ColumnTrait, EntityTrait, QueryFilter, QuerySelect, QueryTrait}; use sea_query::MysqlQueryBuilder; #[test] diff --git a/src/query/insert.rs b/src/query/insert.rs index 769c753e..5ed11a46 100644 --- a/src/query/insert.rs +++ b/src/query/insert.rs @@ -1,4 +1,4 @@ -use crate::{ActiveModelTrait, EntityTrait, Iterable, QueryTrait}; +use crate::{ActiveModelTrait, EntityTrait, IntoActiveModel, Iterable, QueryTrait}; use core::marker::PhantomData; use sea_query::{InsertStatement, IntoIden}; @@ -36,14 +36,13 @@ where } /// Insert one Model or ActiveModel - /// + /// /// Model /// ``` /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder}; - /// + /// /// assert_eq!( - /// Insert::::new() - /// .one(cake::Model { + /// Insert::one(cake::Model { /// id: 1, /// name: "Apple Pie".to_owned(), /// }) @@ -55,10 +54,9 @@ where /// ActiveModel /// ``` /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder}; - /// + /// /// assert_eq!( - /// Insert::::new() - /// .one(cake::ActiveModel { + /// Insert::one(cake::ActiveModel { /// id: Unset(None), /// name: Set("Apple Pie".to_owned()), /// }) @@ -67,11 +65,48 @@ where /// r#"INSERT INTO "cake" ("name") VALUES ('Apple Pie')"#, /// ); /// ``` - pub fn one(mut self, m: M) -> Self + pub fn one(m: M) -> Insert where - M: Into, + M: IntoActiveModel, { - let mut am: A = m.into(); + Self::new().add(m) + } + + /// Insert many Model or ActiveModel + /// + /// ``` + /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder}; + /// + /// assert_eq!( + /// Insert::many(vec![ + /// cake::Model { + /// id: 1, + /// name: "Apple Pie".to_owned(), + /// }, + /// cake::Model { + /// id: 2, + /// name: "Orange Scone".to_owned(), + /// } + /// ]) + /// .build(PostgresQueryBuilder) + /// .to_string(), + /// r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie'), (2, 'Orange Scone')"#, + /// ); + /// ``` + pub fn many(models: I) -> Self + where + M: IntoActiveModel, + I: IntoIterator, + { + Self::new().add_many(models) + } + + #[allow(clippy::should_implement_trait)] + pub fn add(mut self, m: M) -> Self + where + M: IntoActiveModel, + { + let mut am: A = m.into_active_model(); let mut columns = Vec::new(); let mut values = Vec::new(); let columns_empty = self.columns.is_empty(); @@ -93,35 +128,13 @@ where self } - /// Insert many Model or ActiveModel - /// - /// ``` - /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder}; - /// - /// assert_eq!( - /// Insert::::new() - /// .many(vec![ - /// cake::Model { - /// id: 1, - /// name: "Apple Pie".to_owned(), - /// }, - /// cake::Model { - /// id: 2, - /// name: "Orange Scone".to_owned(), - /// } - /// ]) - /// .build(PostgresQueryBuilder) - /// .to_string(), - /// r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie'), (2, 'Orange Scone')"#, - /// ); - /// ``` - pub fn many(mut self, models: I) -> Self + pub fn add_many(mut self, models: I) -> Self where - M: Into, + M: IntoActiveModel, I: IntoIterator, { for model in models.into_iter() { - self = self.one(model); + self = self.add(model); } self } @@ -156,7 +169,7 @@ mod tests { fn insert_1() { assert_eq!( Insert::::new() - .one(cake::ActiveModel { + .add(cake::ActiveModel { id: ActiveValue::unset(), name: ActiveValue::set("Apple Pie".to_owned()), }) @@ -170,7 +183,7 @@ mod tests { fn insert_2() { assert_eq!( Insert::::new() - .one(cake::ActiveModel { + .add(cake::ActiveModel { id: ActiveValue::set(1), name: ActiveValue::set("Apple Pie".to_owned()), }) @@ -184,7 +197,7 @@ mod tests { fn insert_3() { assert_eq!( Insert::::new() - .one(cake::Model { + .add(cake::Model { id: 1, name: "Apple Pie".to_owned(), }) @@ -198,7 +211,7 @@ mod tests { fn insert_4() { assert_eq!( Insert::::new() - .many(vec![ + .add_many(vec![ cake::Model { id: 1, name: "Apple Pie".to_owned(), @@ -227,7 +240,7 @@ mod tests { }; assert_eq!( Insert::::new() - .many(vec![apple, orange]) + .add_many(vec![apple, orange]) .build(PostgresQueryBuilder) .to_string(), r#"INSERT INTO "cake" ("id", "name") VALUES (NULL, 'Apple'), (2, 'Orange')"#, diff --git a/src/query/update.rs b/src/query/update.rs index f03c4a5d..d4815e2d 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -2,8 +2,8 @@ use crate::{ ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter, QueryTrait, }; -use sea_query::{IntoIden, SimpleExpr, UpdateStatement}; use core::marker::PhantomData; +use sea_query::{IntoIden, SimpleExpr, UpdateStatement}; #[derive(Clone, Debug)] pub struct Update; @@ -46,9 +46,7 @@ impl Update { E: EntityTrait, { UpdateMany { - query: UpdateStatement::new() - .table(entity.into_iden()) - .to_owned(), + query: UpdateStatement::new().table(entity.into_iden()).to_owned(), entity: PhantomData, } } @@ -158,7 +156,7 @@ where mod tests { use crate::tests_cfg::{cake, fruit}; use crate::{entity::*, query::*}; - use sea_query::{PostgresQueryBuilder, Expr, Value}; + use sea_query::{Expr, PostgresQueryBuilder, Value}; #[test] fn update_1() { @@ -205,10 +203,10 @@ mod tests { 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(), + .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%'"#, ); }