Do nothing on conflict (#1712)
* added Conflicted to TryInsertResult clippy changes fmt change from basic if statement to matches * changed to early return
This commit is contained in:
parent
f7398d1c5c
commit
6e7950158a
@ -30,9 +30,9 @@ where
|
|||||||
/// The types of results for an INSERT operation
|
/// The types of results for an INSERT operation
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TryInsertResult<T> {
|
pub enum TryInsertResult<T> {
|
||||||
/// The INSERT operation did not insert any value
|
/// The INSERT statement did not have any value to insert
|
||||||
Empty,
|
Empty,
|
||||||
/// Reserved
|
/// The INSERT operation did not insert any valid value
|
||||||
Conflicted,
|
Conflicted,
|
||||||
/// Successfully inserted
|
/// Successfully inserted
|
||||||
Inserted(T),
|
Inserted(T),
|
||||||
@ -50,10 +50,13 @@ where
|
|||||||
A: 'a,
|
A: 'a,
|
||||||
{
|
{
|
||||||
if self.insert_struct.columns.is_empty() {
|
if self.insert_struct.columns.is_empty() {
|
||||||
TryInsertResult::Empty
|
return TryInsertResult::Empty;
|
||||||
} else {
|
|
||||||
TryInsertResult::Inserted(self.insert_struct.exec(db).await)
|
|
||||||
}
|
}
|
||||||
|
let temp = self.insert_struct.exec(db).await;
|
||||||
|
if matches!(temp, Err(DbErr::RecordNotInserted)) {
|
||||||
|
return TryInsertResult::Conflicted;
|
||||||
|
}
|
||||||
|
TryInsertResult::Inserted(temp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute an insert operation without returning (don't use `RETURNING` syntax)
|
/// Execute an insert operation without returning (don't use `RETURNING` syntax)
|
||||||
@ -68,10 +71,13 @@ where
|
|||||||
A: 'a,
|
A: 'a,
|
||||||
{
|
{
|
||||||
if self.insert_struct.columns.is_empty() {
|
if self.insert_struct.columns.is_empty() {
|
||||||
TryInsertResult::Empty
|
return TryInsertResult::Empty;
|
||||||
} else {
|
|
||||||
TryInsertResult::Inserted(self.insert_struct.exec_without_returning(db).await)
|
|
||||||
}
|
}
|
||||||
|
let temp = self.insert_struct.exec_without_returning(db).await;
|
||||||
|
if matches!(temp, Err(DbErr::RecordNotInserted)) {
|
||||||
|
return TryInsertResult::Conflicted;
|
||||||
|
}
|
||||||
|
TryInsertResult::Inserted(temp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute an insert operation and return the inserted model (use `RETURNING` syntax if database supported)
|
/// Execute an insert operation and return the inserted model (use `RETURNING` syntax if database supported)
|
||||||
@ -85,10 +91,13 @@ where
|
|||||||
A: 'a,
|
A: 'a,
|
||||||
{
|
{
|
||||||
if self.insert_struct.columns.is_empty() {
|
if self.insert_struct.columns.is_empty() {
|
||||||
TryInsertResult::Empty
|
return TryInsertResult::Empty;
|
||||||
} else {
|
|
||||||
TryInsertResult::Inserted(self.insert_struct.exec_with_returning(db).await)
|
|
||||||
}
|
}
|
||||||
|
let temp = self.insert_struct.exec_with_returning(db).await;
|
||||||
|
if matches!(temp, Err(DbErr::RecordNotInserted)) {
|
||||||
|
return TryInsertResult::Conflicted;
|
||||||
|
}
|
||||||
|
TryInsertResult::Inserted(temp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +211,14 @@ where
|
|||||||
|
|
||||||
/// Allow insert statement return safely if inserting nothing.
|
/// Allow insert statement return safely if inserting nothing.
|
||||||
/// The database will not be affected.
|
/// The database will not be affected.
|
||||||
|
pub fn do_nothing(self) -> TryInsert<A>
|
||||||
|
where
|
||||||
|
A: ActiveModelTrait,
|
||||||
|
{
|
||||||
|
TryInsert::from_insert(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// alias to do_nothing
|
||||||
pub fn on_empty_do_nothing(self) -> TryInsert<A>
|
pub fn on_empty_do_nothing(self) -> TryInsert<A>
|
||||||
where
|
where
|
||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
@ -309,7 +317,7 @@ where
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function for on_empty_do_nothing in Insert<A>
|
// helper function for do_nothing in Insert<A>
|
||||||
pub fn from_insert(insert: Insert<A>) -> Self {
|
pub fn from_insert(insert: Insert<A>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
insert_struct: insert,
|
insert_struct: insert,
|
||||||
|
@ -3,6 +3,7 @@ pub mod common;
|
|||||||
pub use common::{features::*, setup::*, TestContext};
|
pub use common::{features::*, setup::*, TestContext};
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
use sea_orm::TryInsertResult;
|
||||||
use sea_orm::{sea_query::OnConflict, Set};
|
use sea_orm::{sea_query::OnConflict, Set};
|
||||||
|
|
||||||
#[sea_orm_macros::test]
|
#[sea_orm_macros::test]
|
||||||
@ -50,11 +51,24 @@ pub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr>
|
|||||||
ActiveModel { id: Set(3) },
|
ActiveModel { id: Set(3) },
|
||||||
ActiveModel { id: Set(4) },
|
ActiveModel { id: Set(4) },
|
||||||
])
|
])
|
||||||
.on_conflict(on_conflict)
|
.on_conflict(on_conflict.clone())
|
||||||
.exec(db)
|
.exec(db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
assert_eq!(res.err(), Some(DbErr::RecordNotInserted));
|
assert_eq!(res.err(), Some(DbErr::RecordNotInserted));
|
||||||
|
|
||||||
|
let res = Entity::insert_many([
|
||||||
|
ActiveModel { id: Set(1) },
|
||||||
|
ActiveModel { id: Set(2) },
|
||||||
|
ActiveModel { id: Set(3) },
|
||||||
|
ActiveModel { id: Set(4) },
|
||||||
|
])
|
||||||
|
.on_conflict(on_conflict)
|
||||||
|
.do_nothing()
|
||||||
|
.exec(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert!(matches!(res, TryInsertResult::Conflicted));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user