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