Changelog with Tweaks

This commit is contained in:
Chris Tsang 2023-06-21 23:14:57 +08:00
parent 6e7950158a
commit 1f3fa1dc19
4 changed files with 39 additions and 24 deletions

View File

@ -306,12 +306,24 @@ assert_eq!(migration.status(), MigrationStatus::Pending);
* Added `TryInsert` that does not panic on empty inserts https://github.com/SeaQL/sea-orm/pull/1708 * Added `TryInsert` that does not panic on empty inserts https://github.com/SeaQL/sea-orm/pull/1708
```rust ```rust
// now, you can do: // now, you can do:
let empty_insert = Bakery::insert_many(std::iter::empty()) let res = Bakery::insert_many(std::iter::empty())
.on_empty_do_nothing() .on_empty_do_nothing()
.exec(db) .exec(db)
.await; .await;
assert!(matches!(empty_insert, TryInsertResult::Empty)); assert!(matches!(res, Ok(TryInsertResult::Empty)));
```
* On conflict do nothing not resulting in Err https://github.com/SeaQL/sea-orm/pull/1712
```rust
let on = OnConflict::column(Column::Id).do_nothing().to_owned();
// Existing behaviour
let res = Entity::insert_many([..]).on_conflict(on).exec(db).await;
assert!(matches!(res, Err(DbErr::RecordNotInserted)));
// New API; now you can:
let res = Entity::insert_many([..]).on_conflict(on).do_nothing().exec(db).await;
assert!(matches!(res, Ok(TryInsertResult::Conflicted)));
``` ```
### Upgrades ### Upgrades

View File

@ -44,19 +44,20 @@ where
{ {
/// Execute an insert operation /// Execute an insert operation
#[allow(unused_mut)] #[allow(unused_mut)]
pub async fn exec<'a, C>(self, db: &'a C) -> TryInsertResult<Result<InsertResult<A>, DbErr>> pub async fn exec<'a, C>(self, db: &'a C) -> Result<TryInsertResult<InsertResult<A>>, DbErr>
where where
C: ConnectionTrait, C: ConnectionTrait,
A: 'a, A: 'a,
{ {
if self.insert_struct.columns.is_empty() { if self.insert_struct.columns.is_empty() {
return TryInsertResult::Empty; return Ok(TryInsertResult::Empty);
} }
let temp = self.insert_struct.exec(db).await; let res = self.insert_struct.exec(db).await;
if matches!(temp, Err(DbErr::RecordNotInserted)) { match res {
return TryInsertResult::Conflicted; Ok(res) => Ok(TryInsertResult::Inserted(res)),
Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),
Err(err) => Err(err),
} }
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)
@ -64,40 +65,42 @@ where
pub async fn exec_without_returning<'a, C>( pub async fn exec_without_returning<'a, C>(
self, self,
db: &'a C, db: &'a C,
) -> TryInsertResult<Result<u64, DbErr>> ) -> Result<TryInsertResult<u64>, DbErr>
where where
<A::Entity as EntityTrait>::Model: IntoActiveModel<A>, <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
C: ConnectionTrait, C: ConnectionTrait,
A: 'a, A: 'a,
{ {
if self.insert_struct.columns.is_empty() { if self.insert_struct.columns.is_empty() {
return TryInsertResult::Empty; return Ok(TryInsertResult::Empty);
} }
let temp = self.insert_struct.exec_without_returning(db).await; let res = self.insert_struct.exec_without_returning(db).await;
if matches!(temp, Err(DbErr::RecordNotInserted)) { match res {
return TryInsertResult::Conflicted; Ok(res) => Ok(TryInsertResult::Inserted(res)),
Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),
Err(err) => Err(err),
} }
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)
pub async fn exec_with_returning<'a, C>( pub async fn exec_with_returning<'a, C>(
self, self,
db: &'a C, db: &'a C,
) -> TryInsertResult<Result<<A::Entity as EntityTrait>::Model, DbErr>> ) -> Result<TryInsertResult<<A::Entity as EntityTrait>::Model>, DbErr>
where where
<A::Entity as EntityTrait>::Model: IntoActiveModel<A>, <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
C: ConnectionTrait, C: ConnectionTrait,
A: 'a, A: 'a,
{ {
if self.insert_struct.columns.is_empty() { if self.insert_struct.columns.is_empty() {
return TryInsertResult::Empty; return Ok(TryInsertResult::Empty);
} }
let temp = self.insert_struct.exec_with_returning(db).await; let res = self.insert_struct.exec_with_returning(db).await;
if matches!(temp, Err(DbErr::RecordNotInserted)) { match res {
return TryInsertResult::Conflicted; Ok(res) => Ok(TryInsertResult::Inserted(res)),
Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),
Err(err) => Err(err),
} }
TryInsertResult::Inserted(temp)
} }
} }

View File

@ -35,12 +35,12 @@ pub async fn test(db: &DbConn) {
.exec(db) .exec(db)
.await; .await;
assert!(matches!(res, TryInsertResult::Inserted(_))); assert!(matches!(res, Ok(TryInsertResult::Inserted(_))));
let empty_insert = Bakery::insert_many(std::iter::empty::<bakery::ActiveModel>()) let empty_insert = Bakery::insert_many(std::iter::empty::<bakery::ActiveModel>())
.on_empty_do_nothing() .on_empty_do_nothing()
.exec(db) .exec(db)
.await; .await;
assert!(matches!(empty_insert, TryInsertResult::Empty)); assert!(matches!(empty_insert, Ok(TryInsertResult::Empty)));
} }

View File

@ -55,7 +55,7 @@ pub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr>
.exec(db) .exec(db)
.await; .await;
assert_eq!(res.err(), Some(DbErr::RecordNotInserted)); assert!(matches!(res, Err(DbErr::RecordNotInserted)));
let res = Entity::insert_many([ let res = Entity::insert_many([
ActiveModel { id: Set(1) }, ActiveModel { id: Set(1) },
@ -68,7 +68,7 @@ pub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr>
.exec(db) .exec(db)
.await; .await;
assert!(matches!(res, TryInsertResult::Conflicted)); assert!(matches!(res, Ok(TryInsertResult::Conflicted)));
Ok(()) Ok(())
} }