drizzle_postgres/values/
insert.rs1use super::{OwnedPostgresValue, PostgresValue};
4use crate::prelude::*;
5use core::marker::PhantomData;
6use drizzle_core::{
7 ToSQL, TypedPlaceholder, param::Param, placeholder::Placeholder, sql::SQL, sql::SQLChunk,
8 traits::SQLParam,
9};
10
11#[cfg(feature = "uuid")]
12use uuid::Uuid;
13
14#[doc(hidden)]
19#[derive(Debug, Clone)]
20pub struct ValueWrapper<'a, V: SQLParam, T> {
21 pub value: SQL<'a, V>,
22 pub _phantom: PhantomData<T>,
23}
24
25impl<'a, V: SQLParam, T> ValueWrapper<'a, V, T> {
26 pub const fn new<U>(value: SQL<'a, V>) -> ValueWrapper<'a, V, U> {
27 ValueWrapper {
28 value,
29 _phantom: PhantomData,
30 }
31 }
32}
33
34#[derive(Debug, Clone, Default)]
36#[allow(clippy::large_enum_variant)]
37pub enum PostgresInsertValue<'a, V: SQLParam, T> {
38 #[default]
40 Omit,
41 Null,
43 Value(ValueWrapper<'a, V, T>),
45}
46
47impl<'a, T> PostgresInsertValue<'a, PostgresValue<'a>, T> {
48 #[must_use]
50 pub fn into_owned(self) -> PostgresInsertValue<'static, PostgresValue<'static>, T> {
51 match self {
52 PostgresInsertValue::Omit => PostgresInsertValue::Omit,
53 PostgresInsertValue::Null => PostgresInsertValue::Null,
54 PostgresInsertValue::Value(wrapper) => {
55 let static_sql = match wrapper.value.chunks.first() {
57 Some(SQLChunk::Param(param)) => param.value.as_ref().map_or_else(
58 || SQL::param(PostgresValue::Null),
59 |postgres_val| {
60 let owned_postgres_val =
61 OwnedPostgresValue::from(postgres_val.as_ref().clone());
62 let static_postgres_val = PostgresValue::from(owned_postgres_val);
63 SQL::param(static_postgres_val)
64 },
65 ),
66 _ => SQL::param(PostgresValue::Null),
68 };
69 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
70 static_sql,
71 ))
72 }
73 }
74 }
75}
76
77impl<'a, T> From<T> for PostgresInsertValue<'a, PostgresValue<'a>, T>
83where
84 T: TryInto<PostgresValue<'a>>,
85{
86 fn from(value: T) -> Self {
87 let sql = value.try_into().map_or_else(
88 |_| SQL::from(PostgresValue::Null),
89 |v: PostgresValue<'a>| SQL::from(v),
90 );
91 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(sql))
92 }
93}
94
95impl<'a> From<&str> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
97 fn from(value: &str) -> Self {
98 let postgres_value = SQL::param(Cow::Owned(PostgresValue::from(value.to_string())));
99 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(
100 postgres_value,
101 ))
102 }
103}
104
105impl<'a, T> From<Placeholder> for PostgresInsertValue<'a, PostgresValue<'a>, T> {
107 fn from(placeholder: Placeholder) -> Self {
108 let chunk = SQLChunk::Param(Param {
109 placeholder,
110 value: None,
111 });
112 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(
113 core::iter::once(chunk).collect(),
114 ))
115 }
116}
117
118impl<'a, M: drizzle_core::types::DataType, N: drizzle_core::expr::Nullability, T>
119 From<TypedPlaceholder<M, N>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
120{
121 fn from(typed: TypedPlaceholder<M, N>) -> Self {
122 Placeholder::from(typed).into()
123 }
124}
125
126impl<'a, T> From<Option<T>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
128where
129 T: ToSQL<'a, PostgresValue<'a>>,
130{
131 fn from(value: Option<T>) -> Self {
132 value.map_or(PostgresInsertValue::Omit, |v| {
133 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(v.to_sql()))
134 })
135 }
136}
137
138#[cfg(feature = "uuid")]
140impl<'a> From<Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
141 fn from(value: Uuid) -> Self {
142 let postgres_value = PostgresValue::Uuid(value);
143 let sql = SQL::param(postgres_value);
144 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
145 }
146}
147
148#[cfg(feature = "uuid")]
149impl<'a> From<&'a Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
150 fn from(value: &'a Uuid) -> Self {
151 let postgres_value = PostgresValue::Uuid(*value);
152 let sql = SQL::param(postgres_value);
153 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
154 }
155}