Refactor Insert one & many

This commit is contained in:
Chris Tsang 2021-06-10 01:45:59 +08:00
parent 8acba47a69
commit c70c941712
6 changed files with 86 additions and 53 deletions

View File

@ -56,6 +56,12 @@ pub fn expand_derive_active_model(ident: Ident, data: Data) -> syn::Result<Token
} }
} }
impl sea_orm::IntoActiveModel<ActiveModel> for Model {
fn into_active_model(self) -> ActiveModel {
self.into()
}
}
impl sea_orm::ActiveModelTrait for ActiveModel { impl sea_orm::ActiveModelTrait for ActiveModel {
type Entity = Entity; type Entity = Entity;

View File

@ -92,6 +92,22 @@ pub trait ActiveModelBehavior: ActiveModelTrait {
} }
} }
pub trait IntoActiveModel<A>
where
A: ActiveModelTrait,
{
fn into_active_model(self) -> A;
}
impl<A> IntoActiveModel<A> for A
where
A: ActiveModelTrait,
{
fn into_active_model(self) -> A {
self
}
}
impl<V> ActiveValue<V> impl<V> ActiveValue<V>
where where
V: Into<Value> + Default, V: Into<Value> + Default,

View File

@ -167,7 +167,7 @@ pub trait EntityTrait: EntityName {
where where
A: ActiveModelTrait<Entity = Self>, A: ActiveModelTrait<Entity = Self>,
{ {
Insert::new().one(model) Insert::one(model)
} }
/// ``` /// ```
@ -193,7 +193,7 @@ pub trait EntityTrait: EntityName {
A: ActiveModelTrait<Entity = Self>, A: ActiveModelTrait<Entity = Self>,
I: IntoIterator<Item = A>, I: IntoIterator<Item = A>,
{ {
Insert::new().many(models) Insert::many(models)
} }
/// ``` /// ```

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, QuerySelect}; use crate::{ColumnTrait, EntityTrait, QueryFilter, QuerySelect, QueryTrait};
use sea_query::MysqlQueryBuilder; use sea_query::MysqlQueryBuilder;
#[test] #[test]

View File

@ -1,4 +1,4 @@
use crate::{ActiveModelTrait, EntityTrait, Iterable, QueryTrait}; use crate::{ActiveModelTrait, EntityTrait, IntoActiveModel, Iterable, QueryTrait};
use core::marker::PhantomData; use core::marker::PhantomData;
use sea_query::{InsertStatement, IntoIden}; use sea_query::{InsertStatement, IntoIden};
@ -42,8 +42,7 @@ where
/// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder}; /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder};
/// ///
/// assert_eq!( /// assert_eq!(
/// Insert::<cake::ActiveModel>::new() /// Insert::one(cake::Model {
/// .one(cake::Model {
/// id: 1, /// id: 1,
/// name: "Apple Pie".to_owned(), /// name: "Apple Pie".to_owned(),
/// }) /// })
@ -57,8 +56,7 @@ where
/// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder}; /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder};
/// ///
/// assert_eq!( /// assert_eq!(
/// Insert::<cake::ActiveModel>::new() /// Insert::one(cake::ActiveModel {
/// .one(cake::ActiveModel {
/// id: Unset(None), /// id: Unset(None),
/// name: Set("Apple Pie".to_owned()), /// name: Set("Apple Pie".to_owned()),
/// }) /// })
@ -67,11 +65,48 @@ where
/// r#"INSERT INTO "cake" ("name") VALUES ('Apple Pie')"#, /// r#"INSERT INTO "cake" ("name") VALUES ('Apple Pie')"#,
/// ); /// );
/// ``` /// ```
pub fn one<M>(mut self, m: M) -> Self pub fn one<M>(m: M) -> Insert<A>
where where
M: Into<A>, M: IntoActiveModel<A>,
{ {
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<M, I>(models: I) -> Self
where
M: IntoActiveModel<A>,
I: IntoIterator<Item = M>,
{
Self::new().add_many(models)
}
#[allow(clippy::should_implement_trait)]
pub fn add<M>(mut self, m: M) -> Self
where
M: IntoActiveModel<A>,
{
let mut am: A = m.into_active_model();
let mut columns = Vec::new(); let mut columns = Vec::new();
let mut values = Vec::new(); let mut values = Vec::new();
let columns_empty = self.columns.is_empty(); let columns_empty = self.columns.is_empty();
@ -93,35 +128,13 @@ where
self self
} }
/// Insert many Model or ActiveModel pub fn add_many<M, I>(mut self, models: I) -> Self
///
/// ```
/// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::PostgresQueryBuilder};
///
/// assert_eq!(
/// Insert::<cake::ActiveModel>::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<M, I>(mut self, models: I) -> Self
where where
M: Into<A>, M: IntoActiveModel<A>,
I: IntoIterator<Item = M>, I: IntoIterator<Item = M>,
{ {
for model in models.into_iter() { for model in models.into_iter() {
self = self.one(model); self = self.add(model);
} }
self self
} }
@ -156,7 +169,7 @@ mod tests {
fn insert_1() { fn insert_1() {
assert_eq!( assert_eq!(
Insert::<cake::ActiveModel>::new() Insert::<cake::ActiveModel>::new()
.one(cake::ActiveModel { .add(cake::ActiveModel {
id: ActiveValue::unset(), id: ActiveValue::unset(),
name: ActiveValue::set("Apple Pie".to_owned()), name: ActiveValue::set("Apple Pie".to_owned()),
}) })
@ -170,7 +183,7 @@ mod tests {
fn insert_2() { fn insert_2() {
assert_eq!( assert_eq!(
Insert::<cake::ActiveModel>::new() Insert::<cake::ActiveModel>::new()
.one(cake::ActiveModel { .add(cake::ActiveModel {
id: ActiveValue::set(1), id: ActiveValue::set(1),
name: ActiveValue::set("Apple Pie".to_owned()), name: ActiveValue::set("Apple Pie".to_owned()),
}) })
@ -184,7 +197,7 @@ mod tests {
fn insert_3() { fn insert_3() {
assert_eq!( assert_eq!(
Insert::<cake::ActiveModel>::new() Insert::<cake::ActiveModel>::new()
.one(cake::Model { .add(cake::Model {
id: 1, id: 1,
name: "Apple Pie".to_owned(), name: "Apple Pie".to_owned(),
}) })
@ -198,7 +211,7 @@ mod tests {
fn insert_4() { fn insert_4() {
assert_eq!( assert_eq!(
Insert::<cake::ActiveModel>::new() Insert::<cake::ActiveModel>::new()
.many(vec![ .add_many(vec![
cake::Model { cake::Model {
id: 1, id: 1,
name: "Apple Pie".to_owned(), name: "Apple Pie".to_owned(),
@ -227,7 +240,7 @@ mod tests {
}; };
assert_eq!( assert_eq!(
Insert::<cake::ActiveModel>::new() Insert::<cake::ActiveModel>::new()
.many(vec![apple, orange]) .add_many(vec![apple, orange])
.build(PostgresQueryBuilder) .build(PostgresQueryBuilder)
.to_string(), .to_string(),
r#"INSERT INTO "cake" ("id", "name") VALUES (NULL, 'Apple'), (2, 'Orange')"#, r#"INSERT INTO "cake" ("id", "name") VALUES (NULL, 'Apple'), (2, 'Orange')"#,

View File

@ -2,8 +2,8 @@ use crate::{
ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter, ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter,
QueryTrait, QueryTrait,
}; };
use sea_query::{IntoIden, SimpleExpr, UpdateStatement};
use core::marker::PhantomData; use core::marker::PhantomData;
use sea_query::{IntoIden, SimpleExpr, UpdateStatement};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Update; pub struct Update;
@ -46,9 +46,7 @@ impl Update {
E: EntityTrait, E: EntityTrait,
{ {
UpdateMany { UpdateMany {
query: UpdateStatement::new() query: UpdateStatement::new().table(entity.into_iden()).to_owned(),
.table(entity.into_iden())
.to_owned(),
entity: PhantomData, entity: PhantomData,
} }
} }
@ -158,7 +156,7 @@ where
mod tests { mod tests {
use crate::tests_cfg::{cake, fruit}; use crate::tests_cfg::{cake, fruit};
use crate::{entity::*, query::*}; use crate::{entity::*, query::*};
use sea_query::{PostgresQueryBuilder, Expr, Value}; use sea_query::{Expr, PostgresQueryBuilder, Value};
#[test] #[test]
fn update_1() { fn update_1() {