Skip to main content

drizzle_mysql/values/
update.rs

1//! The field type of generated `MySQL` update models.
2
3use super::{MySQLValue, insert::ValueWrapper};
4use crate::prelude::*;
5use crate::types::Any;
6use drizzle_core::{
7    MySQLDialect, SQL, SQLChunk, SQLParam, ToSQL, TypedPlaceholder,
8    expr::{AcceptsNullability, ColumnBinOp, ColumnNeg, Expr, Null, Nullability, SQLExpr, Scalar},
9    param::Param,
10    placeholder::Placeholder,
11    types::{Assignable, DataType},
12};
13
14/// One field of a generated update model: unchanged, `NULL`, or a new value.
15///
16/// You rarely build this directly. The `with_*` setters on a generated
17/// `UpdateX` model convert their arguments into it.
18#[derive(Debug, Clone, Default)]
19#[allow(clippy::large_enum_variant)]
20pub enum MySQLUpdateValue<
21    'a,
22    V: SQLParam,
23    T,
24    Target: DataType = Any,
25    TargetNull: Nullability = Null,
26> {
27    /// Leave the column out of the SET clause.
28    #[default]
29    Skip,
30    /// Assign SQL `NULL`.
31    Null,
32    /// Assign a value, placeholder, or typed SQL expression.
33    Value(ValueWrapper<'a, V, (T, Target, TargetNull)>),
34}
35
36impl<V: SQLParam, T, Target: DataType, TargetNull: Nullability>
37    MySQLUpdateValue<'_, V, T, Target, TargetNull>
38{
39    /// Returns `true` if the column is left out of the SET clause.
40    #[must_use]
41    pub const fn is_skip(&self) -> bool {
42        matches!(self, Self::Skip)
43    }
44}
45
46impl<'a, T, Target, TargetNull> From<T>
47    for MySQLUpdateValue<'a, MySQLValue<'a>, T, Target, TargetNull>
48where
49    T: Into<MySQLValue<'a>>,
50    Target: DataType,
51    TargetNull: Nullability,
52{
53    fn from(value: T) -> Self {
54        let sql = SQL::param(value.into());
55        Self::Value(ValueWrapper::<MySQLValue<'a>, T>::new(sql))
56    }
57}
58
59impl<'a, Target, TargetNull> From<&str>
60    for MySQLUpdateValue<'a, MySQLValue<'a>, String, Target, TargetNull>
61where
62    Target: DataType,
63    TargetNull: Nullability,
64{
65    fn from(value: &str) -> Self {
66        Self::Value(ValueWrapper::<MySQLValue<'a>, String>::new(SQL::param(
67            MySQLValue::from(String::from(value)),
68        )))
69    }
70}
71
72impl<'a, T, Target, TargetNull> From<Placeholder>
73    for MySQLUpdateValue<'a, MySQLValue<'a>, T, Target, TargetNull>
74where
75    Target: DataType,
76    TargetNull: Nullability,
77{
78    fn from(placeholder: Placeholder) -> Self {
79        Self::Value(ValueWrapper::<MySQLValue<'a>, T>::new(
80            core::iter::once(SQLChunk::Param(Param {
81                placeholder,
82                value: None,
83            }))
84            .collect(),
85        ))
86    }
87}
88
89impl<'a, M, N, T, Target, TargetNull> From<TypedPlaceholder<M, N>>
90    for MySQLUpdateValue<'a, MySQLValue<'a>, T, Target, TargetNull>
91where
92    M: DataType,
93    N: Nullability,
94    Target: DataType + Assignable<M>,
95    TargetNull: Nullability + AcceptsNullability<N>,
96{
97    fn from(value: TypedPlaceholder<M, N>) -> Self {
98        Placeholder::from(value).into()
99    }
100}
101
102impl<'a, T, Target, TargetNull, Actual, ActualNull, Sources>
103    From<SQLExpr<'a, MySQLValue<'a>, Actual, ActualNull, Scalar, Sources>>
104    for MySQLUpdateValue<'a, MySQLValue<'a>, T, Target, TargetNull>
105where
106    Target: DataType + Assignable<Actual>,
107    TargetNull: Nullability + AcceptsNullability<ActualNull>,
108    Actual: DataType,
109    ActualNull: Nullability,
110{
111    fn from(value: SQLExpr<'a, MySQLValue<'a>, Actual, ActualNull, Scalar, Sources>) -> Self {
112        Self::Value(ValueWrapper::<MySQLValue<'a>, T>::new(
113            value.into_expr_sql(),
114        ))
115    }
116}
117
118impl<'a, T, Target, TargetNull, L, R, Op, Actual, ActualNull>
119    From<ColumnBinOp<L, R, Op, MySQLDialect, Actual, ActualNull>>
120    for MySQLUpdateValue<'a, MySQLValue<'a>, T, Target, TargetNull>
121where
122    Target: DataType + Assignable<Actual>,
123    TargetNull: Nullability + AcceptsNullability<ActualNull>,
124    Actual: DataType,
125    ActualNull: Nullability,
126    ColumnBinOp<L, R, Op, MySQLDialect, Actual, ActualNull>: ToSQL<'a, MySQLValue<'a>>,
127{
128    fn from(value: ColumnBinOp<L, R, Op, MySQLDialect, Actual, ActualNull>) -> Self {
129        Self::Value(ValueWrapper::<MySQLValue<'a>, T>::new(value.into_sql()))
130    }
131}
132
133impl<'a, T, Target, TargetNull, E, Actual, ActualNull>
134    From<ColumnNeg<E, MySQLDialect, Actual, ActualNull>>
135    for MySQLUpdateValue<'a, MySQLValue<'a>, T, Target, TargetNull>
136where
137    Target: DataType + Assignable<Actual>,
138    TargetNull: Nullability + AcceptsNullability<ActualNull>,
139    Actual: DataType,
140    ActualNull: Nullability,
141    ColumnNeg<E, MySQLDialect, Actual, ActualNull>: ToSQL<'a, MySQLValue<'a>>,
142{
143    fn from(value: ColumnNeg<E, MySQLDialect, Actual, ActualNull>) -> Self {
144        Self::Value(ValueWrapper::<MySQLValue<'a>, T>::new(value.into_sql()))
145    }
146}