use crate::types::{DynIden, IntoIden};
#[derive(Debug, Clone)]
pub enum OnConflictTarget {
Column(DynIden),
Columns(Vec<DynIden>),
}
#[derive(Debug, Clone)]
pub enum OnConflictAction {
DoNothing,
DoUpdate(Vec<DynIden>),
}
#[derive(Debug, Clone)]
pub struct OnConflict {
pub(crate) target: OnConflictTarget,
pub(crate) action: OnConflictAction,
}
impl OnConflict {
pub fn column<C: IntoIden>(col: C) -> Self {
Self {
target: OnConflictTarget::Column(col.into_iden()),
action: OnConflictAction::DoNothing,
}
}
pub fn columns<I, C>(cols: I) -> Self
where
I: IntoIterator<Item = C>,
C: IntoIden,
{
Self {
target: OnConflictTarget::Columns(cols.into_iter().map(|c| c.into_iden()).collect()),
action: OnConflictAction::DoNothing,
}
}
#[must_use]
pub fn do_nothing(mut self) -> Self {
self.action = OnConflictAction::DoNothing;
self
}
#[must_use]
pub fn update_columns<I, C>(mut self, cols: I) -> Self
where
I: IntoIterator<Item = C>,
C: IntoIden,
{
self.action = OnConflictAction::DoUpdate(cols.into_iter().map(|c| c.into_iden()).collect());
self
}
#[must_use]
pub fn to_owned(self) -> Self {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_on_conflict_column_do_nothing() {
let on_conflict = OnConflict::column("id").do_nothing();
assert!(matches!(on_conflict.target, OnConflictTarget::Column(_)));
assert!(matches!(on_conflict.action, OnConflictAction::DoNothing));
}
#[test]
fn test_on_conflict_column_update_columns() {
let on_conflict = OnConflict::column("id").update_columns(["name", "email"]);
assert!(matches!(on_conflict.target, OnConflictTarget::Column(_)));
match &on_conflict.action {
OnConflictAction::DoUpdate(cols) => {
assert_eq!(cols.len(), 2);
}
_ => panic!("Expected DoUpdate action"),
}
}
#[test]
fn test_on_conflict_columns_do_nothing() {
let on_conflict = OnConflict::columns(["id", "tenant_id"]).do_nothing();
match &on_conflict.target {
OnConflictTarget::Columns(cols) => {
assert_eq!(cols.len(), 2);
}
_ => panic!("Expected Columns target"),
}
assert!(matches!(on_conflict.action, OnConflictAction::DoNothing));
}
#[test]
fn test_on_conflict_columns_update_columns() {
let on_conflict =
OnConflict::columns(["id", "tenant_id"]).update_columns(["name", "email", "age"]);
match &on_conflict.target {
OnConflictTarget::Columns(cols) => {
assert_eq!(cols.len(), 2);
}
_ => panic!("Expected Columns target"),
}
match &on_conflict.action {
OnConflictAction::DoUpdate(cols) => {
assert_eq!(cols.len(), 3);
}
_ => panic!("Expected DoUpdate action"),
}
}
#[test]
fn test_on_conflict_to_owned() {
let on_conflict = OnConflict::column("id").do_nothing().to_owned();
assert!(matches!(on_conflict.target, OnConflictTarget::Column(_)));
assert!(matches!(on_conflict.action, OnConflictAction::DoNothing));
}
#[test]
fn test_on_conflict_default_action_is_do_nothing() {
let on_conflict = OnConflict::column("id");
assert!(matches!(on_conflict.action, OnConflictAction::DoNothing));
}
}