drizzle_sqlite/values/
insert.rs

1//------------------------------------------------------------------------------
2// InsertValue Definition - SQL-based value for inserts
3//------------------------------------------------------------------------------
4
5use std::marker::PhantomData;
6
7use drizzle_core::{Placeholder, SQL, SQLParam};
8
9use crate::{OwnedSQLiteValue, SQLiteValue};
10
11/// Wrapper for SQL with type information
12#[derive(Debug, Clone)]
13pub struct ValueWrapper<'a, V: SQLParam, T> {
14    pub value: SQL<'a, V>,
15    pub _phantom: PhantomData<T>,
16}
17
18impl<'a, V: SQLParam, T> ValueWrapper<'a, V, T> {
19    pub const fn new<U>(value: SQL<'a, V>) -> ValueWrapper<'a, V, U> {
20        ValueWrapper {
21            value,
22            _phantom: PhantomData,
23        }
24    }
25}
26
27/// Represents a value for INSERT operations that can be omitted, null, or a SQL expression
28#[derive(Debug, Clone, Default)]
29#[allow(clippy::large_enum_variant)]
30pub enum SQLiteInsertValue<'a, V: SQLParam, T> {
31    /// Omit this column from the INSERT (use database default)
32    #[default]
33    Omit,
34    /// Explicitly insert NULL
35    Null,
36    /// Insert a SQL expression (value, placeholder, etc.)
37    Value(ValueWrapper<'a, V, T>),
38}
39
40impl<'a, T> SQLiteInsertValue<'a, SQLiteValue<'a>, T> {
41    /// Converts this InsertValue to an owned version with 'static lifetime
42    pub fn into_owned(self) -> SQLiteInsertValue<'static, SQLiteValue<'static>, T> {
43        match self {
44            SQLiteInsertValue::Omit => SQLiteInsertValue::Omit,
45            SQLiteInsertValue::Null => SQLiteInsertValue::Null,
46            SQLiteInsertValue::Value(wrapper) => {
47                // Extract the parameter value, convert to owned, then back to static SQLiteValue
48                if let Some(drizzle_core::SQLChunk::Param(param)) = wrapper.value.chunks.first() {
49                    if let Some(ref val) = param.value {
50                        let owned_val = OwnedSQLiteValue::from(val.as_ref().clone());
51                        let static_val: SQLiteValue<'static> = owned_val.into();
52                        let static_sql = drizzle_core::SQL::param(static_val);
53                        SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'static>, T>::new(
54                            static_sql,
55                        ))
56                    } else {
57                        SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'static>, T>::new(
58                            drizzle_core::SQL::param(SQLiteValue::Null),
59                        ))
60                    }
61                } else {
62                    SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'static>, T>::new(
63                        drizzle_core::SQL::param(SQLiteValue::Null),
64                    ))
65                }
66            }
67        }
68    }
69}
70
71impl<'a, T, U> From<T> for SQLiteInsertValue<'a, SQLiteValue<'a>, U>
72where
73    T: TryInto<SQLiteValue<'a>>,
74    T: TryInto<U>,
75    U: TryInto<SQLiteValue<'a>>,
76{
77    fn from(value: T) -> Self {
78        let sql = TryInto::<U>::try_into(value)
79            .map(|v| v.try_into().unwrap_or_default())
80            .map(|v: SQLiteValue<'a>| SQL::from(v))
81            .unwrap_or_else(|_| SQL::from(SQLiteValue::Null));
82        SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(sql))
83    }
84}
85
86impl<'a, T> From<Placeholder> for SQLiteInsertValue<'a, SQLiteValue<'a>, T> {
87    fn from(placeholder: Placeholder) -> Self {
88        use drizzle_core::{Param, SQLChunk};
89        let chunk = SQLChunk::Param(Param {
90            placeholder,
91            value: None,
92        });
93        SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(
94            std::iter::once(chunk).collect(),
95        ))
96    }
97}
98
99// Array conversion for Vec<u8> InsertValue - support flexible input types
100impl<'a, const N: usize> From<[u8; N]> for SQLiteInsertValue<'a, SQLiteValue<'a>, Vec<u8>> {
101    fn from(value: [u8; N]) -> Self {
102        let sqlite_value = SQLiteValue::Blob(std::borrow::Cow::Owned(value.to_vec()));
103        let sql = SQL::param(sqlite_value);
104        SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'a>, Vec<u8>>::new(sql))
105    }
106}