use super::{Insert, Statement};
use crate::schema::Model;
use std::{fmt, marker::PhantomData};
use toasty_core::stmt;
pub struct Upsert<M> {
pub(crate) untyped: stmt::Insert,
_p: PhantomData<M>,
}
impl<M: Model> Upsert<M> {
#[doc(hidden)]
pub fn blank(target: impl IntoIterator<Item = usize>) -> Self {
let mut insert = Insert::<M>::blank_single().untyped;
insert.upsert = Some(Box::new(stmt::Upsert {
target: stmt::UpsertTarget::Fields(
target
.into_iter()
.map(stmt::Projection::from_index)
.collect(),
),
shared: stmt::Assignments::new(),
defaults: stmt::Assignments::new(),
update_defaults: stmt::Assignments::new(),
create: stmt::Assignments::new(),
update: stmt::Assignments::new(),
action: stmt::UpsertAction::Update,
}));
Self {
untyped: insert,
_p: PhantomData,
}
}
#[doc(hidden)]
pub fn untyped_mut(&mut self) -> &mut stmt::Insert {
&mut self.untyped
}
#[doc(hidden)]
pub fn into_untyped(self) -> stmt::Statement {
self.untyped.into()
}
}
impl<M> From<Upsert<M>> for Statement<M> {
fn from(value: Upsert<M>) -> Self {
Statement::from_untyped_stmt(value.untyped.into())
}
}
impl<M> Clone for Upsert<M> {
fn clone(&self) -> Self {
Self {
untyped: self.untyped.clone(),
_p: PhantomData,
}
}
}
impl<M> fmt::Debug for Upsert<M> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.untyped.fmt(f)
}
}