diff --git a/src/error.rs b/src/error.rs index aecc3f528..4e3dbc988 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,6 +17,10 @@ pub enum DbErr { Json(String), /// A migration error Migration(String), + /// None of the records are being inserted into the database, + /// if you insert with upcert expression that means + /// all of them conflict with existing records in the database + RecordNotInserted(String), } impl std::error::Error for DbErr {} @@ -32,6 +36,7 @@ impl std::fmt::Display for DbErr { Self::Type(s) => write!(f, "Type Error: {}", s), Self::Json(s) => write!(f, "Json Error: {}", s), Self::Migration(s) => write!(f, "Migration Error: {}", s), + Self::RecordNotInserted(s) => write!(f, "RecordNotInserted Error: {}", s), } } } diff --git a/src/executor/insert.rs b/src/executor/insert.rs index 3c7b69c80..77a43693c 100644 --- a/src/executor/insert.rs +++ b/src/executor/insert.rs @@ -116,7 +116,10 @@ where let cols = PrimaryKey::::iter() .map(|col| col.to_string()) .collect::>(); - let res = db.query_one(statement).await?.unwrap(); + let rows = db.query_all(statement).await?; + let res = rows.last().ok_or_else(|| { + DbErr::RecordNotInserted("None of the records are being inserted".to_owned()) + })?; res.try_get_many("", cols.as_ref()).ok() } false => { diff --git a/tests/upsert_tests.rs b/tests/upsert_tests.rs new file mode 100644 index 000000000..ad874e79c --- /dev/null +++ b/tests/upsert_tests.rs @@ -0,0 +1,65 @@ +pub mod common; + +pub use common::{features::*, setup::*, TestContext}; +use pretty_assertions::assert_eq; +use sea_orm::entity::prelude::*; +use sea_orm::{sea_query::OnConflict, Set}; + +#[sea_orm_macros::test] +#[cfg(feature = "sqlx-postgres")] +async fn main() -> Result<(), DbErr> { + let ctx = TestContext::new("upsert_tests").await; + create_tables(&ctx.db).await?; + create_insert_default(&ctx.db).await?; + ctx.delete().await; + + Ok(()) +} + +pub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> { + use insert_default::*; + + let on_conflict = OnConflict::column(Column::Id).do_nothing().to_owned(); + + let res = Entity::insert_many([ + ActiveModel { id: Set(1) }, + ActiveModel { id: Set(2) }, + ActiveModel { id: Set(3) }, + ]) + .on_conflict(on_conflict.clone()) + .exec(db) + .await; + + assert_eq!(res?.last_insert_id, 3); + + 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.clone()) + .exec(db) + .await; + + assert_eq!(res?.last_insert_id, 4); + + 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) + .exec(db) + .await; + + assert_eq!( + res.err(), + Some(DbErr::RecordNotInserted( + "None of the records are being inserted".to_owned() + )) + ); + + Ok(()) +}