drizzle_sqlite/values/
mod.rs1mod conversions;
6mod drivers;
7#[cfg(any(feature = "chrono", feature = "time"))]
8pub(crate) mod duration;
9mod insert;
10#[cfg(feature = "serde")]
11mod json;
12pub mod owned;
13mod update;
14
15pub use insert::*;
16pub use owned::*;
17pub use update::*;
18
19use crate::prelude::*;
20use crate::traits::FromSQLiteValue;
21use drizzle_core::{dialect::Dialect, error::DrizzleError, sql::SQL, traits::SQLParam};
22
23#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
33pub enum SQLiteValue<'a> {
34 Integer(i64),
36 Real(f64),
38 Text(Cow<'a, str>),
40 Blob(Cow<'a, [u8]>),
42 #[default]
44 Null,
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
53pub enum SQLiteValueRef<'a> {
54 Integer(i64),
56 Real(f64),
58 Text(&'a str),
60 Blob(&'a [u8]),
62 #[default]
64 Null,
65}
66
67impl<'a> SQLiteValueRef<'a> {
68 #[inline]
70 #[must_use]
71 pub const fn into_value(self) -> SQLiteValue<'a> {
72 match self {
73 Self::Integer(value) => SQLiteValue::Integer(value),
74 Self::Real(value) => SQLiteValue::Real(value),
75 Self::Text(value) => SQLiteValue::Text(Cow::Borrowed(value)),
76 Self::Blob(value) => SQLiteValue::Blob(Cow::Borrowed(value)),
77 Self::Null => SQLiteValue::Null,
78 }
79 }
80
81 #[cfg(feature = "rusqlite")]
89 #[inline]
90 pub fn try_from_rusqlite_value_ref(
91 value: ::rusqlite::types::ValueRef<'a>,
92 ) -> Result<Self, DrizzleError> {
93 match value {
94 ::rusqlite::types::ValueRef::Null => Ok(Self::Null),
95 ::rusqlite::types::ValueRef::Integer(value) => Ok(Self::Integer(value)),
96 ::rusqlite::types::ValueRef::Real(value) => Ok(Self::Real(value)),
97 ::rusqlite::types::ValueRef::Text(value) => {
98 let value = core::str::from_utf8(value).map_err(|e| {
99 DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into())
100 })?;
101 Ok(Self::Text(value))
102 }
103 ::rusqlite::types::ValueRef::Blob(value) => Ok(Self::Blob(value)),
104 }
105 }
106}
107
108impl<'a> From<SQLiteValueRef<'a>> for SQLiteValue<'a> {
109 #[inline]
110 fn from(value: SQLiteValueRef<'a>) -> Self {
111 value.into_value()
112 }
113}
114
115impl<'a> From<&'a SQLiteValue<'_>> for SQLiteValueRef<'a> {
116 #[inline]
117 fn from(value: &'a SQLiteValue<'_>) -> Self {
118 value.as_ref()
119 }
120}
121
122impl SQLiteValue<'_> {
123 #[inline]
125 #[must_use]
126 pub const fn is_null(&self) -> bool {
127 matches!(self, SQLiteValue::Null)
128 }
129
130 #[inline]
132 #[must_use]
133 pub const fn as_i64(&self) -> Option<i64> {
134 match self {
135 SQLiteValue::Integer(value) => Some(*value),
136 _ => None,
137 }
138 }
139
140 #[inline]
142 #[must_use]
143 pub const fn as_f64(&self) -> Option<f64> {
144 match self {
145 SQLiteValue::Real(value) => Some(*value),
146 _ => None,
147 }
148 }
149
150 #[inline]
152 #[must_use]
153 pub fn as_str(&self) -> Option<&str> {
154 match self {
155 SQLiteValue::Text(value) => Some(value.as_ref()),
156 _ => None,
157 }
158 }
159
160 #[inline]
162 #[must_use]
163 pub fn as_bytes(&self) -> Option<&[u8]> {
164 match self {
165 SQLiteValue::Blob(value) => Some(value.as_ref()),
166 _ => None,
167 }
168 }
169
170 #[inline]
172 #[must_use]
173 pub fn as_ref(&self) -> SQLiteValueRef<'_> {
174 match self {
175 SQLiteValue::Integer(value) => SQLiteValueRef::Integer(*value),
176 SQLiteValue::Real(value) => SQLiteValueRef::Real(*value),
177 SQLiteValue::Text(value) => SQLiteValueRef::Text(value.as_ref()),
178 SQLiteValue::Blob(value) => SQLiteValueRef::Blob(value.as_ref()),
179 SQLiteValue::Null => SQLiteValueRef::Null,
180 }
181 }
182
183 #[inline]
185 #[must_use]
186 pub fn into_owned(self) -> OwnedSQLiteValue {
187 self.into()
188 }
189
190 pub fn convert<T: FromSQLiteValue>(self) -> Result<T, DrizzleError> {
206 T::from_sqlite_ref(self.as_ref())
207 }
208
209 pub fn convert_ref<T: FromSQLiteValue>(&self) -> Result<T, DrizzleError> {
217 T::from_sqlite_ref(self.as_ref())
218 }
219}
220
221impl core::fmt::Display for SQLiteValue<'_> {
222 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
223 let value = match self {
224 SQLiteValue::Integer(i) => i.to_string(),
225 SQLiteValue::Real(r) => r.to_string(),
226 SQLiteValue::Text(cow) => cow.to_string(),
227 SQLiteValue::Blob(cow) => String::from_utf8_lossy(cow).to_string(),
228 SQLiteValue::Null => String::new(),
229 };
230 write!(f, "{value}")
231 }
232}
233
234impl SQLParam for SQLiteValue<'_> {
236 const DIALECT: Dialect = Dialect::SQLite;
237 type DialectMarker = drizzle_core::dialect::SQLiteDialect;
238
239 fn write_literal(&self, buf: &mut String) -> bool {
240 use core::fmt::Write;
241 match self {
242 SQLiteValue::Null => buf.push_str("NULL"),
243 SQLiteValue::Integer(value) => {
244 let _ = write!(buf, "{value}");
245 }
246 SQLiteValue::Real(value) if value.is_nan() => return false,
250 SQLiteValue::Real(value) if value.is_infinite() => {
251 buf.push_str(if value.is_sign_positive() {
252 "9e999"
253 } else {
254 "-9e999"
255 });
256 }
257 SQLiteValue::Real(value) => {
258 let _ = write!(buf, "{value:?}");
259 }
260 SQLiteValue::Text(text) if text.contains('\0') => return false,
261 SQLiteValue::Text(text) => {
262 buf.push('\'');
263 buf.push_str(&text.replace('\'', "''"));
264 buf.push('\'');
265 }
266 SQLiteValue::Blob(bytes) => {
267 buf.push_str("X'");
268 for byte in bytes.iter() {
269 let _ = write!(buf, "{byte:02X}");
270 }
271 buf.push('\'');
272 }
273 }
274 true
275 }
276}
277
278impl<'a> From<SQLiteValue<'a>> for SQL<'a, SQLiteValue<'a>> {
279 fn from(value: SQLiteValue<'a>) -> Self {
280 SQL::param(value)
281 }
282}
283
284impl FromIterator<OwnedSQLiteValue> for Vec<SQLiteValue<'_>> {
285 fn from_iter<T: IntoIterator<Item = OwnedSQLiteValue>>(iter: T) -> Self {
286 iter.into_iter().map(SQLiteValue::from).collect()
287 }
288}
289
290impl<'a> FromIterator<&'a OwnedSQLiteValue> for Vec<SQLiteValue<'a>> {
291 fn from_iter<T: IntoIterator<Item = &'a OwnedSQLiteValue>>(iter: T) -> Self {
292 iter.into_iter().map(SQLiteValue::from).collect()
293 }
294}