Added delete_by_id (#590)
* Added delete_by_id * Added an integration test * Added composite key example * Remove extra find_by_id in delete_by_id test * Added unit test with composite primary key
This commit is contained in:
parent
7a86ac0239
commit
12f66618f9
@ -745,10 +745,124 @@ pub trait EntityTrait: EntityName {
|
||||
fn delete_many() -> DeleteMany<Self> {
|
||||
Delete::many(Self::default())
|
||||
}
|
||||
|
||||
/// Delete a model based on primary key
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use sea_orm::{error::*, tests_cfg::*, *};
|
||||
/// #
|
||||
/// # #[smol_potat::main]
|
||||
/// # #[cfg(feature = "mock")]
|
||||
/// # pub async fn main() -> Result<(), DbErr> {
|
||||
/// #
|
||||
/// # let db = MockDatabase::new(DbBackend::Postgres)
|
||||
/// # .append_exec_results(vec![
|
||||
/// # MockExecResult {
|
||||
/// # last_insert_id: 0,
|
||||
/// # rows_affected: 1,
|
||||
/// # },
|
||||
/// # ])
|
||||
/// # .into_connection();
|
||||
/// #
|
||||
/// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
|
||||
///
|
||||
/// let delete_result = fruit::Entity::delete_by_id(1).exec(&db).await?;
|
||||
///
|
||||
/// assert_eq!(delete_result.rows_affected, 1);
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// db.into_transaction_log(),
|
||||
/// vec![Transaction::from_sql_and_values(
|
||||
/// DbBackend::Postgres,
|
||||
/// r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
|
||||
/// vec![1i32.into()]
|
||||
/// )]
|
||||
/// );
|
||||
/// #
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
/// Delete by composite key
|
||||
/// ```
|
||||
/// # use sea_orm::{error::*, tests_cfg::*, *};
|
||||
/// #
|
||||
/// # #[smol_potat::main]
|
||||
/// # #[cfg(feature = "mock")]
|
||||
/// # pub async fn main() -> Result<(), DbErr> {
|
||||
///
|
||||
/// # let db = MockDatabase::new(DbBackend::Postgres)
|
||||
/// # .append_exec_results(vec![
|
||||
/// # MockExecResult {
|
||||
/// # last_insert_id: 0,
|
||||
/// # rows_affected: 1,
|
||||
/// # },
|
||||
/// # ])
|
||||
/// # .into_connection();
|
||||
/// #
|
||||
/// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};
|
||||
///
|
||||
/// let delete_result = cake_filling::Entity::delete_by_id((2, 3)).exec(&db).await?;
|
||||
///
|
||||
/// assert_eq!(delete_result.rows_affected, 1);
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// db.into_transaction_log(),
|
||||
/// vec![Transaction::from_sql_and_values(
|
||||
/// DbBackend::Postgres,
|
||||
/// r#"DELETE FROM "cake_filling" WHERE "cake_filling"."cake_id" = $1 AND "cake_filling"."filling_id" = $2"#,
|
||||
/// vec![2i32.into(), 3i32.into()]
|
||||
/// )]
|
||||
/// );
|
||||
/// #
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn delete_by_id(values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType) -> DeleteMany<Self> {
|
||||
let mut delete = Self::delete_many();
|
||||
let mut keys = Self::PrimaryKey::iter();
|
||||
for v in values.into_value_tuple() {
|
||||
if let Some(key) = keys.next() {
|
||||
let col = key.into_column();
|
||||
delete = delete.filter(col.eq(v));
|
||||
} else {
|
||||
panic!("primary key arity mismatch");
|
||||
}
|
||||
}
|
||||
if keys.next().is_some() {
|
||||
panic!("primary key arity mismatch");
|
||||
}
|
||||
delete
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn test_delete_by_id_1() {
|
||||
use crate::tests_cfg::cake;
|
||||
use crate::{entity::*, query::*, DbBackend};
|
||||
assert_eq!(
|
||||
cake::Entity::delete_by_id(1)
|
||||
.build(DbBackend::Sqlite)
|
||||
.to_string(),
|
||||
r#"DELETE FROM "cake" WHERE "cake"."id" = 1"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_by_id_2() {
|
||||
use crate::tests_cfg::cake_filling_price;
|
||||
use crate::{entity::*, query::*, DbBackend};
|
||||
assert_eq!(
|
||||
cake_filling_price::Entity::delete_by_id((1, 2))
|
||||
.build(DbBackend::Sqlite)
|
||||
.to_string(),
|
||||
r#"DELETE FROM "public"."cake_filling_price" WHERE "cake_filling_price"."cake_id" = 1 AND "cake_filling_price"."filling_id" = 2"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "macros")]
|
||||
fn entity_model_1() {
|
||||
|
@ -11,7 +11,7 @@ pub struct Deleter {
|
||||
}
|
||||
|
||||
/// The result of a DELETE operation
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct DeleteResult {
|
||||
/// The number of rows affected by the DELETE operation
|
||||
pub rows_affected: u64,
|
||||
|
57
tests/delete_by_id_tests.rs
Normal file
57
tests/delete_by_id_tests.rs
Normal file
@ -0,0 +1,57 @@
|
||||
pub mod common;
|
||||
pub use common::{features::*, setup::*, TestContext};
|
||||
use sea_orm::{entity::prelude::*, DatabaseConnection, IntoActiveModel};
|
||||
|
||||
#[sea_orm_macros::test]
|
||||
#[cfg(any(
|
||||
feature = "sqlx-mysql",
|
||||
feature = "sqlx-sqlite",
|
||||
feature = "sqlx-postgres"
|
||||
))]
|
||||
async fn main() -> Result<(), DbErr> {
|
||||
let ctx = TestContext::new("delete_by_id_tests").await;
|
||||
create_tables(&ctx.db).await?;
|
||||
create_and_delete_applog(&ctx.db).await?;
|
||||
|
||||
ctx.delete().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn create_and_delete_applog(db: &DatabaseConnection) -> Result<(), DbErr> {
|
||||
let log1 = applog::Model {
|
||||
id: 1,
|
||||
action: "Testing".to_owned(),
|
||||
json: Json::String("HI".to_owned()),
|
||||
created_at: "2021-09-17T17:50:20+08:00".parse().unwrap(),
|
||||
};
|
||||
|
||||
Applog::insert(log1.clone().into_active_model())
|
||||
.exec(db)
|
||||
.await?;
|
||||
|
||||
let log2 = applog::Model {
|
||||
id: 2,
|
||||
action: "Tests".to_owned(),
|
||||
json: Json::String("HELLO".to_owned()),
|
||||
created_at: "2022-09-17T17:50:20+08:00".parse().unwrap(),
|
||||
};
|
||||
|
||||
Applog::insert(log2.clone().into_active_model())
|
||||
.exec(db)
|
||||
.await?;
|
||||
|
||||
let delete_res = Applog::delete_by_id(2).exec(db).await?;
|
||||
assert_eq!(delete_res.rows_affected, 1);
|
||||
|
||||
let find_res = Applog::find_by_id(1).all(db).await?;
|
||||
assert_eq!(find_res, vec![log1]);
|
||||
|
||||
let find_res = Applog::find_by_id(2).all(db).await?;
|
||||
assert_eq!(find_res, vec![]);
|
||||
|
||||
let delete_res = Applog::delete_by_id(3).exec(db).await?;
|
||||
assert_eq!(delete_res.rows_affected, 0);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user