Skip to main content

drizzle_core/sql/
owned.rs

1use crate::prelude::*;
2use crate::{OwnedParam, SQL, SQLChunk, SQLColumnInfo, SQLParam, SQLTableInfo, ToSQL, Token};
3use smallvec::SmallVec;
4
5/// Owned version of SQLChunk with 'static lifetime
6#[derive(Debug, Clone)]
7pub enum OwnedSQLChunk<V: SQLParam> {
8    Token(Token),
9    Ident(String),
10    Raw(String),
11    Param(OwnedParam<V>),
12    Table(&'static dyn SQLTableInfo),
13    Column(&'static dyn SQLColumnInfo),
14}
15
16impl<V: SQLParam> OwnedSQLChunk<V> {
17    /// Creates a token chunk.
18    #[inline]
19    pub const fn token(t: Token) -> Self {
20        Self::Token(t)
21    }
22
23    /// Creates a table chunk.
24    #[inline]
25    pub const fn table(table: &'static dyn SQLTableInfo) -> Self {
26        Self::Table(table)
27    }
28
29    /// Creates a column chunk.
30    #[inline]
31    pub const fn column(column: &'static dyn SQLColumnInfo) -> Self {
32        Self::Column(column)
33    }
34
35    /// Creates a quoted identifier from a runtime string.
36    #[inline]
37    pub fn ident(name: impl Into<String>) -> Self {
38        Self::Ident(name.into())
39    }
40
41    /// Creates raw SQL text from a runtime string.
42    #[inline]
43    pub fn raw(text: impl Into<String>) -> Self {
44        Self::Raw(text.into())
45    }
46
47    /// Creates a parameter chunk with owned value.
48    #[inline]
49    pub fn param(value: OwnedParam<V>) -> Self {
50        Self::Param(value)
51    }
52}
53
54impl<'a, V: SQLParam> From<SQLChunk<'a, V>> for OwnedSQLChunk<V> {
55    fn from(value: SQLChunk<'a, V>) -> Self {
56        match value {
57            SQLChunk::Token(token) => Self::Token(token),
58            SQLChunk::Ident(cow) => Self::Ident(cow.into_owned()),
59            SQLChunk::Raw(cow) => Self::Raw(cow.into_owned()),
60            SQLChunk::Param(param) => Self::Param(param.into()),
61            SQLChunk::Table(table) => Self::Table(table),
62            SQLChunk::Column(column) => Self::Column(column),
63        }
64    }
65}
66
67impl<V: SQLParam> From<OwnedSQLChunk<V>> for SQLChunk<'static, V> {
68    fn from(value: OwnedSQLChunk<V>) -> Self {
69        match value {
70            OwnedSQLChunk::Token(token) => SQLChunk::Token(token),
71            OwnedSQLChunk::Ident(s) => SQLChunk::Ident(Cow::Owned(s)),
72            OwnedSQLChunk::Raw(s) => SQLChunk::Raw(Cow::Owned(s)),
73            OwnedSQLChunk::Param(param) => SQLChunk::Param(param.into()),
74            OwnedSQLChunk::Table(table) => SQLChunk::Table(table),
75            OwnedSQLChunk::Column(column) => SQLChunk::Column(column),
76        }
77    }
78}
79
80/// Owned version of SQL with 'static lifetime
81#[derive(Debug, Clone)]
82pub struct OwnedSQL<V: SQLParam> {
83    pub chunks: SmallVec<[OwnedSQLChunk<V>; 8]>,
84}
85
86impl<V: SQLParam> Default for OwnedSQL<V> {
87    fn default() -> Self {
88        Self {
89            chunks: SmallVec::new(),
90        }
91    }
92}
93
94impl<'a, V: SQLParam> From<SQL<'a, V>> for OwnedSQL<V> {
95    fn from(value: SQL<'a, V>) -> Self {
96        Self {
97            chunks: value.chunks.into_iter().map(Into::into).collect(),
98        }
99    }
100}
101
102impl<V: SQLParam> OwnedSQL<V> {
103    /// Creates an empty SQL fragment with const-friendly initialization.
104    #[inline]
105    pub const fn empty() -> Self {
106        Self {
107            chunks: SmallVec::new_const(),
108        }
109    }
110
111    /// Creates an empty SQL fragment with pre-allocated chunk capacity.
112    #[inline]
113    pub fn with_capacity_chunks(capacity: usize) -> Self {
114        Self {
115            chunks: SmallVec::with_capacity(capacity),
116        }
117    }
118
119    /// Convert to SQL with 'static lifetime
120    pub fn to_sql(&self) -> SQL<'static, V> {
121        SQL {
122            chunks: self.chunks.iter().cloned().map(Into::into).collect(),
123        }
124    }
125
126    /// Convert into SQL with 'static lifetime (consuming)
127    pub fn into_sql(self) -> SQL<'static, V> {
128        SQL {
129            chunks: self.chunks.into_iter().map(Into::into).collect(),
130        }
131    }
132}
133
134impl<V: SQLParam> ToSQL<'static, V> for OwnedSQL<V> {
135    fn to_sql(&self) -> SQL<'static, V> {
136        OwnedSQL::to_sql(self)
137    }
138
139    fn into_sql(self) -> SQL<'static, V> {
140        self.into_sql()
141    }
142}