Add upsert conflict capability

This commit is contained in:
2025-09-20 20:40:00 -06:00
parent fcd437d608
commit d4274e2bd2
6 changed files with 42 additions and 2 deletions
Generated
+1 -1
View File
@@ -1211,7 +1211,7 @@ dependencies = [
[[package]] [[package]]
name = "seamantic" name = "seamantic"
version = "0.0.5" version = "0.0.6"
dependencies = [ dependencies = [
"sea-orm", "sea-orm",
"sea-orm-migration", "sea-orm-migration",
+1
View File
@@ -13,4 +13,5 @@ A library to enhance SeaORM
- example: `cargo run --example=migrations --features=sqlite` - example: `cargo run --example=migrations --features=sqlite`
- fmt: `cargo fmt --check` - fmt: `cargo fmt --check`
- docs: `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features` - docs: `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features`
- semver: `cargo semver-checks --all-features`
- publish: `cargo publish --dry-run -p seamantic` - publish: `cargo publish --dry-run -p seamantic`
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "seamantic" name = "seamantic"
version = "0.0.5" version = "0.0.6"
categories = [] categories = []
description = "A library to enhance SeaORM" description = "A library to enhance SeaORM"
+1
View File
@@ -6,6 +6,7 @@ pub use sea_orm;
pub use sea_orm_migration; pub use sea_orm_migration;
pub mod model; pub mod model;
pub mod orm;
pub mod schema; pub mod schema;
/// A macro for defining a Migrator with a custom migration table while /// A macro for defining a Migrator with a custom migration table while
+4
View File
@@ -0,0 +1,4 @@
//! Helpers for working with SeaORM
mod upsert;
pub use upsert::UpsertTrait;
+34
View File
@@ -0,0 +1,34 @@
use sea_orm::sea_query::{IntoColumnRef, OnConflict};
use sea_orm::{ActiveModelTrait, EntityTrait, Insert, Iterable};
/// This trait add a method on [Insert] to allow for upsert behavior
pub trait UpsertTrait: private::Sealed {
/// Set ON CONFLICT on primary key to update all other columns
fn on_conflict_upsert(self) -> Self;
}
fn primary_key_iter<A: ActiveModelTrait>()
-> impl Iterator<Item = <A::Entity as EntityTrait>::PrimaryKey> {
<A::Entity as EntityTrait>::PrimaryKey::iter()
}
fn column_iter<A: ActiveModelTrait>() -> impl Iterator<Item = <A::Entity as EntityTrait>::Column> {
<<A as ActiveModelTrait>::Entity as EntityTrait>::Column::iter()
}
impl<A: ActiveModelTrait> UpsertTrait for Insert<A> {
fn on_conflict_upsert(self) -> Self {
self.on_conflict(
OnConflict::columns(primary_key_iter::<A>())
.update_columns(column_iter::<A>().filter(|col| {
!primary_key_iter::<A>().any(|pk| pk.into_column_ref() == col.into_column_ref())
}))
.to_owned(),
)
}
}
mod private {
pub trait Sealed {}
impl<A: ::sea_orm::ActiveModelTrait> Sealed for ::sea_orm::Insert<A> {}
}