1use crate::prelude::*;
7use crate::types::Any;
8use drizzle_core::expr::{
9 AcceptsNullability, ColumnBinOp, ColumnNeg, Excluded, Expr, Null, Nullability, SQLExpr, Scalar,
10};
11use drizzle_core::types::{Assignable, DataType};
12use drizzle_core::{
13 Placeholder, SQL, SQLColumnInfo, SQLParam, SQLiteDialect, ToSQL, TypedPlaceholder,
14};
15
16use super::SQLiteValue;
17use super::insert::ValueWrapper;
18
19#[derive(Debug, Clone, Default)]
24#[allow(clippy::large_enum_variant)]
25pub enum SQLiteUpdateValue<
26 'a,
27 V: SQLParam,
28 T,
29 Target: DataType = Any,
30 TargetNull: Nullability = Null,
31> {
32 #[default]
34 Skip,
35 Null,
37 Value(ValueWrapper<'a, V, (T, Target, TargetNull)>),
39}
40
41impl<V: SQLParam, T, Target: DataType, TargetNull: Nullability>
42 SQLiteUpdateValue<'_, V, T, Target, TargetNull>
43{
44 pub const fn is_skip(&self) -> bool {
46 matches!(self, Self::Skip)
47 }
48}
49
50impl<'a, T, U, Target, TargetNull> From<T>
58 for SQLiteUpdateValue<'a, SQLiteValue<'a>, U, Target, TargetNull>
59where
60 T: TryInto<SQLiteValue<'a>> + TryInto<U>,
61 U: TryInto<SQLiteValue<'a>>,
62 Target: DataType,
63 TargetNull: Nullability,
64{
65 fn from(value: T) -> Self {
66 let column_value = TryInto::<U>::try_into(value).unwrap_or_else(|_| {
69 panic!(
70 "a `{}` does not fit a `{}` column",
71 core::any::type_name::<T>(),
72 core::any::type_name::<U>()
73 )
74 });
75 let sql = SQL::from(
76 TryInto::<SQLiteValue<'a>>::try_into(column_value).unwrap_or_else(|_| {
77 panic!(
78 "could not convert a `{}` to a SQLite value",
79 core::any::type_name::<U>()
80 )
81 }),
82 );
83 SQLiteUpdateValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(sql))
84 }
85}
86
87impl<'a, T, Target, TargetNull> From<Placeholder>
89 for SQLiteUpdateValue<'a, SQLiteValue<'a>, T, Target, TargetNull>
90where
91 Target: DataType,
92 TargetNull: Nullability,
93{
94 fn from(placeholder: Placeholder) -> Self {
95 use drizzle_core::{Param, SQLChunk};
96 let chunk = SQLChunk::Param(Param {
97 placeholder,
98 value: None,
99 });
100 SQLiteUpdateValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(
101 core::iter::once(chunk).collect(),
102 ))
103 }
104}
105
106impl<'a, M, N, T, Target, TargetNull> From<TypedPlaceholder<M, N>>
107 for SQLiteUpdateValue<'a, SQLiteValue<'a>, T, Target, TargetNull>
108where
109 M: DataType,
110 N: Nullability,
111 Target: DataType + Assignable<M>,
112 TargetNull: Nullability + AcceptsNullability<N>,
113{
114 fn from(typed: TypedPlaceholder<M, N>) -> Self {
115 Placeholder::from(typed).into()
116 }
117}
118
119impl<'a, C, T, Target, TargetNull, Actual, ActualNull> From<Excluded<C>>
121 for SQLiteUpdateValue<'a, SQLiteValue<'a>, T, Target, TargetNull>
122where
123 C: SQLColumnInfo + Expr<'a, SQLiteValue<'a>, SQLType = Actual, Nullable = ActualNull>,
124 Target: DataType + Assignable<Actual>,
125 TargetNull: Nullability + AcceptsNullability<ActualNull>,
126 Actual: DataType,
127 ActualNull: Nullability,
128{
129 fn from(excluded: Excluded<C>) -> Self {
130 use drizzle_core::ToSQL;
131 let sql = excluded.to_sql();
132 SQLiteUpdateValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(sql))
133 }
134}
135
136impl<'a, const N: usize, Target, TargetNull> From<[u8; N]>
138 for SQLiteUpdateValue<'a, SQLiteValue<'a>, Vec<u8>, Target, TargetNull>
139where
140 Target: DataType,
141 TargetNull: Nullability,
142{
143 fn from(value: [u8; N]) -> Self {
144 let sqlite_value = SQLiteValue::Blob(crate::prelude::Cow::Owned(value.to_vec()));
145 let sql = SQL::param(sqlite_value);
146 SQLiteUpdateValue::Value(ValueWrapper::<SQLiteValue<'a>, Vec<u8>>::new(sql))
147 }
148}
149
150impl<'a, T, Target, TargetNull, Actual, ActualNull, Sources>
151 From<SQLExpr<'a, SQLiteValue<'a>, Actual, ActualNull, Scalar, Sources>>
152 for SQLiteUpdateValue<'a, SQLiteValue<'a>, T, Target, TargetNull>
153where
154 Target: DataType + Assignable<Actual>,
155 TargetNull: Nullability + AcceptsNullability<ActualNull>,
156 Actual: DataType,
157 ActualNull: Nullability,
158{
159 fn from(value: SQLExpr<'a, SQLiteValue<'a>, Actual, ActualNull, Scalar, Sources>) -> Self {
160 Self::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(
161 value.into_expr_sql(),
162 ))
163 }
164}
165
166impl<'a, T, Target, TargetNull, L, R, Op, Actual, ActualNull>
167 From<ColumnBinOp<L, R, Op, SQLiteDialect, Actual, ActualNull>>
168 for SQLiteUpdateValue<'a, SQLiteValue<'a>, T, Target, TargetNull>
169where
170 Target: DataType + Assignable<Actual>,
171 TargetNull: Nullability + AcceptsNullability<ActualNull>,
172 Actual: DataType,
173 ActualNull: Nullability,
174 ColumnBinOp<L, R, Op, SQLiteDialect, Actual, ActualNull>: ToSQL<'a, SQLiteValue<'a>>,
175{
176 fn from(value: ColumnBinOp<L, R, Op, SQLiteDialect, Actual, ActualNull>) -> Self {
177 Self::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(value.into_sql()))
178 }
179}
180
181impl<'a, T, Target, TargetNull, E, Actual, ActualNull>
182 From<ColumnNeg<E, SQLiteDialect, Actual, ActualNull>>
183 for SQLiteUpdateValue<'a, SQLiteValue<'a>, T, Target, TargetNull>
184where
185 Target: DataType + Assignable<Actual>,
186 TargetNull: Nullability + AcceptsNullability<ActualNull>,
187 Actual: DataType,
188 ActualNull: Nullability,
189 ColumnNeg<E, SQLiteDialect, Actual, ActualNull>: ToSQL<'a, SQLiteValue<'a>>,
190{
191 fn from(value: ColumnNeg<E, SQLiteDialect, Actual, ActualNull>) -> Self {
192 Self::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(value.into_sql()))
193 }
194}