1use crate::prelude::*;
7use crate::values::{OwnedSQLiteValue, SQLiteValue, SQLiteValueRef};
8use drizzle_core::conv::checked_float_to_int;
9use drizzle_core::error::DrizzleError;
10
11pub trait SQLiteAffinity: drizzle_core::types::DataType {
13 const SQL_TYPE: &'static str;
15}
16
17macro_rules! impl_sqlite_affinity {
18 ($($marker:ty => $sql_type:literal),+ $(,)?) => {
19 $(
20 impl SQLiteAffinity for $marker {
21 const SQL_TYPE: &'static str = $sql_type;
22 }
23 )+
24 };
25}
26
27impl_sqlite_affinity! {
28 crate::types::Integer => "INTEGER",
29 crate::types::Text => "TEXT",
30 crate::types::Blob => "BLOB",
31 crate::types::Real => "REAL",
32 crate::types::Numeric => "NUMERIC",
33 crate::types::Any => "ANY",
34}
35
36#[diagnostic::on_unimplemented(
56 message = "`{Self}` cannot be used as a SQLite column type",
57 note = "add #[derive(SQLiteEnum)] for enum types, or use a supported primitive type"
58)]
59pub trait DrizzleSQLiteColumn: Sized {
60 type SQLType: SQLiteAffinity;
65
66 const SQL_TYPE: &'static str = <Self::SQLType as SQLiteAffinity>::SQL_TYPE;
73
74 fn decode(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError>;
84
85 fn encode(&self) -> SQLiteValue<'_>;
87
88 fn encode_owned(self) -> OwnedSQLiteValue {
94 self.encode().into_owned()
95 }
96
97 #[cfg(feature = "query")]
105 fn decode_json(value: &serde_json::Value) -> Result<Self, DrizzleError> {
106 let value = decode_projected_sqlite_value(value)?;
107 let value = value.as_value();
108 Self::decode(value.as_ref())
109 }
110}
111
112#[cfg(feature = "query")]
124pub fn decode_projected_sqlite_value(
125 value: &serde_json::Value,
126) -> Result<OwnedSQLiteValue, DrizzleError> {
127 if value.is_null() {
128 return Ok(OwnedSQLiteValue::Null);
129 }
130
131 let object = value.as_object().ok_or_else(|| {
132 DrizzleError::ConversionError("SQLite query value is missing its storage tag".into())
133 })?;
134 let storage = object
135 .get("$drizzle_storage")
136 .and_then(serde_json::Value::as_str)
137 .ok_or_else(|| {
138 DrizzleError::ConversionError("SQLite query value has no valid $drizzle_storage".into())
139 })?;
140 let value = object.get("$drizzle_value").ok_or_else(|| {
141 DrizzleError::ConversionError("SQLite query value has no $drizzle_value".into())
142 })?;
143
144 match storage {
145 "integer" => value
146 .as_i64()
147 .map(OwnedSQLiteValue::Integer)
148 .ok_or_else(|| {
149 DrizzleError::ConversionError(
150 "SQLite INTEGER query value is not a JSON integer".into(),
151 )
152 }),
153 "real" => value.as_f64().map(OwnedSQLiteValue::Real).ok_or_else(|| {
154 DrizzleError::ConversionError("SQLite REAL query value is not a JSON number".into())
155 }),
156 "text" => value
157 .as_str()
158 .map(|value| OwnedSQLiteValue::Text(value.to_owned()))
159 .ok_or_else(|| {
160 DrizzleError::ConversionError("SQLite TEXT query value is not a JSON string".into())
161 }),
162 "blob" => value
163 .as_str()
164 .ok_or_else(|| {
165 DrizzleError::ConversionError("SQLite BLOB query value is not a hex string".into())
166 })
167 .and_then(decode_projected_blob)
168 .map(|value| OwnedSQLiteValue::Blob(value.into_boxed_slice())),
169 other => Err(DrizzleError::ConversionError(
170 format!("unknown SQLite query storage class `{other}`").into(),
171 )),
172 }
173}
174
175#[cfg(feature = "query")]
176fn decode_projected_blob(value: &str) -> Result<Vec<u8>, DrizzleError> {
177 let (chunks, remainder) = value.as_bytes().as_chunks::<2>();
178 let mut bytes = Vec::with_capacity(value.len() / 2);
179 for chunk in chunks {
180 let high = decode_hex_nibble(chunk[0])?;
181 let low = decode_hex_nibble(chunk[1])?;
182 bytes.push((high << 4) | low);
183 }
184 if !remainder.is_empty() {
185 return Err(DrizzleError::ConversionError(
186 "hex-encoded SQLite BLOB has odd length".into(),
187 ));
188 }
189 Ok(bytes)
190}
191
192#[cfg(feature = "query")]
193fn decode_hex_nibble(value: u8) -> Result<u8, DrizzleError> {
194 match value {
195 b'0'..=b'9' => Ok(value - b'0'),
196 b'a'..=b'f' => Ok(value - b'a' + 10),
197 b'A'..=b'F' => Ok(value - b'A' + 10),
198 _ => Err(DrizzleError::ConversionError(
199 "SQLite BLOB query value contains a non-hex byte".into(),
200 )),
201 }
202}
203
204impl<'a, T> From<T> for SQLiteValue<'a>
205where
206 T: DrizzleSQLiteColumn,
207{
208 fn from(value: T) -> Self {
209 value.encode_owned().into()
210 }
211}
212
213pub trait FromSQLiteValue: Sized {
224 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError>;
230
231 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError>;
237
238 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError>;
244
245 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError>;
251
252 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
259 match value {
260 SQLiteValueRef::Integer(value) => Self::from_sqlite_integer(value),
261 SQLiteValueRef::Text(value) => Self::from_sqlite_text(value),
262 SQLiteValueRef::Real(value) => Self::from_sqlite_real(value),
263 SQLiteValueRef::Blob(value) => Self::from_sqlite_blob(value),
264 SQLiteValueRef::Null => Self::from_sqlite_null(),
265 }
266 }
267
268 fn from_sqlite_null() -> Result<Self, DrizzleError> {
275 Err(DrizzleError::ConversionError(
276 "unexpected NULL value".into(),
277 ))
278 }
279
280 #[cfg(feature = "rusqlite")]
287 fn from_value_ref(value: ::rusqlite::types::ValueRef<'_>) -> Result<Self, DrizzleError> {
288 let value = SQLiteValueRef::try_from_rusqlite_value_ref(value)?;
289 Self::from_sqlite_ref(value)
290 }
291}
292
293impl<T> FromSQLiteValue for T
294where
295 T: DrizzleSQLiteColumn,
296{
297 fn from_sqlite_ref(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
298 T::decode(value)
299 }
300
301 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
302 T::decode(SQLiteValueRef::Integer(value))
303 }
304
305 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
306 T::decode(SQLiteValueRef::Text(value))
307 }
308
309 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
310 T::decode(SQLiteValueRef::Real(value))
311 }
312
313 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
314 T::decode(SQLiteValueRef::Blob(value))
315 }
316
317 fn from_sqlite_null() -> Result<Self, DrizzleError> {
318 T::decode(SQLiteValueRef::Null)
319 }
320}
321
322pub trait DrizzleRowByIndex {
324 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError>;
331}
332
333pub trait DrizzleRowByName: DrizzleRowByIndex {
335 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError>;
342}
343
344macro_rules! impl_from_sqlite_value_int {
350 (i64) => {
352 impl FromSQLiteValue for i64 {
353 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
354 Ok(value)
355 }
356
357 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
358 value.parse().map_err(|e| {
359 DrizzleError::ConversionError(format!("cannot parse '{}' as i64: {}", value, e).into())
360 })
361 }
362
363 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
364 checked_float_to_int(value, "i64")
365 }
366
367 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
368 Err(DrizzleError::ConversionError("cannot convert BLOB to i64".into()))
369 }
370 }
371 };
372 ($($ty:ty),+ $(,)?) => {
374 $(
375 impl FromSQLiteValue for $ty {
376 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
377 value.try_into().map_err(|e| {
378 DrizzleError::ConversionError(
379 format!("i64 {} out of range for {}: {}", value, stringify!($ty), e).into(),
380 )
381 })
382 }
383
384 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
385 value.parse().map_err(|e| {
386 DrizzleError::ConversionError(
387 format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
388 )
389 })
390 }
391
392 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
393 checked_float_to_int(value, stringify!($ty))
394 }
395
396 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
397 Err(DrizzleError::ConversionError(
398 concat!("cannot convert BLOB to ", stringify!($ty)).into()
399 ))
400 }
401 }
402 )+
403 };
404}
405
406#[inline]
409fn i64_to_f64(i: i64) -> f64 {
410 let high = i32::try_from(i >> 32).expect("sign-extended high word fits in i32");
411 let low = u32::try_from(i & 0xFFFF_FFFF).expect("masked low word fits in u32");
412 f64::from(high) * 4_294_967_296.0_f64 + f64::from(low)
413}
414
415impl_from_sqlite_value_int!(i64);
417impl_from_sqlite_value_int!(i8, i16, i32, isize, u8, u16, u32, u64, usize);
418
419impl FromSQLiteValue for f64 {
422 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
423 Ok(i64_to_f64(value))
424 }
425
426 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
427 value.parse().map_err(|e| {
428 DrizzleError::ConversionError(format!("cannot parse '{value}' as f64: {e}").into())
429 })
430 }
431
432 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
433 Ok(value)
434 }
435
436 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
437 Err(DrizzleError::ConversionError(
438 "cannot convert BLOB to f64".into(),
439 ))
440 }
441}
442
443fn narrow_to_f32(value: f64) -> Result<f32, DrizzleError> {
444 format!("{value}").parse::<f32>().map_err(|e| {
448 DrizzleError::ConversionError(format!("cannot convert REAL {value} to f32: {e}").into())
449 })
450}
451
452impl FromSQLiteValue for f32 {
456 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
457 narrow_to_f32(i64_to_f64(value))
459 }
460
461 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
462 value.parse().map_err(|e| {
463 DrizzleError::ConversionError(format!("cannot parse '{value}' as f32: {e}").into())
464 })
465 }
466
467 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
468 narrow_to_f32(value)
469 }
470
471 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
472 Err(DrizzleError::ConversionError(
473 "cannot convert BLOB to f32".into(),
474 ))
475 }
476}
477
478impl FromSQLiteValue for bool {
479 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
480 Ok(value != 0)
481 }
482
483 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
484 match value.to_lowercase().as_str() {
485 "true" | "1" | "yes" | "on" => Ok(true),
486 "false" | "0" | "no" | "off" => Ok(false),
487 _ => Err(DrizzleError::ConversionError(
488 format!("cannot parse '{value}' as bool").into(),
489 )),
490 }
491 }
492
493 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
494 Ok(value != 0.0)
495 }
496
497 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
498 Err(DrizzleError::ConversionError(
499 "cannot convert BLOB to bool".into(),
500 ))
501 }
502}
503
504impl FromSQLiteValue for String {
505 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
506 Ok(value.to_string())
507 }
508
509 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
510 Ok(value.to_string())
511 }
512
513 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
514 Ok(value.to_string())
515 }
516
517 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
518 Self::from_utf8(value.to_vec()).map_err(|e| {
519 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
520 })
521 }
522}
523
524impl FromSQLiteValue for compact_str::CompactString {
525 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
526 Ok(Self::new(value.to_string()))
527 }
528
529 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
530 Ok(Self::new(value))
531 }
532
533 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
534 Ok(Self::new(value.to_string()))
535 }
536
537 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
538 let s = String::from_utf8(value.to_vec()).map_err(|e| {
539 DrizzleError::ConversionError(format!("invalid UTF-8 in BLOB: {e}").into())
540 })?;
541 Ok(Self::new(s))
542 }
543}
544
545impl FromSQLiteValue for Box<String> {
546 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
547 String::from_sqlite_integer(value).map(Self::new)
548 }
549
550 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
551 String::from_sqlite_text(value).map(Self::new)
552 }
553
554 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
555 String::from_sqlite_real(value).map(Self::new)
556 }
557
558 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
559 String::from_sqlite_blob(value).map(Self::new)
560 }
561}
562
563impl FromSQLiteValue for Rc<String> {
564 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
565 String::from_sqlite_integer(value).map(Self::new)
566 }
567
568 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
569 String::from_sqlite_text(value).map(Self::new)
570 }
571
572 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
573 String::from_sqlite_real(value).map(Self::new)
574 }
575
576 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
577 String::from_sqlite_blob(value).map(Self::new)
578 }
579}
580
581impl FromSQLiteValue for Arc<String> {
582 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
583 String::from_sqlite_integer(value).map(Self::new)
584 }
585
586 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
587 String::from_sqlite_text(value).map(Self::new)
588 }
589
590 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
591 String::from_sqlite_real(value).map(Self::new)
592 }
593
594 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
595 String::from_sqlite_blob(value).map(Self::new)
596 }
597}
598
599impl FromSQLiteValue for Box<str> {
600 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
601 String::from_sqlite_integer(value).map(String::into_boxed_str)
602 }
603
604 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
605 String::from_sqlite_text(value).map(String::into_boxed_str)
606 }
607
608 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
609 String::from_sqlite_real(value).map(String::into_boxed_str)
610 }
611
612 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
613 String::from_sqlite_blob(value).map(String::into_boxed_str)
614 }
615}
616
617impl FromSQLiteValue for Rc<str> {
618 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
619 String::from_sqlite_integer(value).map(Self::from)
620 }
621
622 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
623 String::from_sqlite_text(value).map(Self::from)
624 }
625
626 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
627 String::from_sqlite_real(value).map(Self::from)
628 }
629
630 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
631 String::from_sqlite_blob(value).map(Self::from)
632 }
633}
634
635impl FromSQLiteValue for Arc<str> {
636 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
637 String::from_sqlite_integer(value).map(Self::from)
638 }
639
640 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
641 String::from_sqlite_text(value).map(Self::from)
642 }
643
644 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
645 String::from_sqlite_real(value).map(Self::from)
646 }
647
648 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
649 String::from_sqlite_blob(value).map(Self::from)
650 }
651}
652
653impl FromSQLiteValue for Vec<u8> {
654 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
655 Ok(value.to_le_bytes().to_vec())
656 }
657
658 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
659 Ok(value.as_bytes().to_vec())
660 }
661
662 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
663 Ok(value.to_le_bytes().to_vec())
664 }
665
666 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
667 Ok(value.to_vec())
668 }
669}
670
671#[cfg(feature = "bytes")]
672impl FromSQLiteValue for bytes::Bytes {
673 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
674 Vec::<u8>::from_sqlite_integer(value).map(Self::from)
675 }
676
677 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
678 Vec::<u8>::from_sqlite_text(value).map(Self::from)
679 }
680
681 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
682 Vec::<u8>::from_sqlite_real(value).map(Self::from)
683 }
684
685 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
686 Ok(Self::copy_from_slice(value))
687 }
688}
689
690#[cfg(feature = "bytes")]
691impl FromSQLiteValue for bytes::BytesMut {
692 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
693 Vec::<u8>::from_sqlite_integer(value).map(|v| Self::from(v.as_slice()))
694 }
695
696 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
697 Vec::<u8>::from_sqlite_text(value).map(|v| Self::from(v.as_slice()))
698 }
699
700 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
701 Vec::<u8>::from_sqlite_real(value).map(|v| Self::from(v.as_slice()))
702 }
703
704 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
705 Ok(Self::from(value))
706 }
707}
708
709#[cfg(feature = "smallvec")]
710impl<const N: usize> FromSQLiteValue for smallvec::SmallVec<[u8; N]> {
711 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
712 Err(DrizzleError::ConversionError(
713 "cannot convert INTEGER to SmallVec<u8>, use BLOB".into(),
714 ))
715 }
716
717 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
718 Err(DrizzleError::ConversionError(
719 "cannot convert TEXT to SmallVec<u8>, use BLOB".into(),
720 ))
721 }
722
723 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
724 Err(DrizzleError::ConversionError(
725 "cannot convert REAL to SmallVec<u8>, use BLOB".into(),
726 ))
727 }
728
729 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
730 let mut out = Self::new();
731 out.extend_from_slice(value);
732 Ok(out)
733 }
734}
735
736impl FromSQLiteValue for Box<Vec<u8>> {
737 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
738 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
739 }
740
741 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
742 Vec::<u8>::from_sqlite_text(value).map(Self::new)
743 }
744
745 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
746 Vec::<u8>::from_sqlite_real(value).map(Self::new)
747 }
748
749 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
750 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
751 }
752}
753
754impl FromSQLiteValue for Rc<Vec<u8>> {
755 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
756 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
757 }
758
759 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
760 Vec::<u8>::from_sqlite_text(value).map(Self::new)
761 }
762
763 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
764 Vec::<u8>::from_sqlite_real(value).map(Self::new)
765 }
766
767 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
768 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
769 }
770}
771
772impl FromSQLiteValue for Arc<Vec<u8>> {
773 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
774 Vec::<u8>::from_sqlite_integer(value).map(Self::new)
775 }
776
777 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
778 Vec::<u8>::from_sqlite_text(value).map(Self::new)
779 }
780
781 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
782 Vec::<u8>::from_sqlite_real(value).map(Self::new)
783 }
784
785 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
786 Vec::<u8>::from_sqlite_blob(value).map(Self::new)
787 }
788}
789
790impl<T: FromSQLiteValue> FromSQLiteValue for Option<T> {
792 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
793 T::from_sqlite_integer(value).map(Some)
794 }
795
796 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
797 T::from_sqlite_text(value).map(Some)
798 }
799
800 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
801 T::from_sqlite_real(value).map(Some)
802 }
803
804 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
805 T::from_sqlite_blob(value).map(Some)
806 }
807
808 fn from_sqlite_null() -> Result<Self, DrizzleError> {
809 Ok(None)
810 }
811}
812
813#[cfg(feature = "rusqlite")]
818impl DrizzleRowByIndex for rusqlite::Row<'_> {
819 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
820 let value_ref = self.get_ref(idx)?;
821 match value_ref {
822 rusqlite::types::ValueRef::Integer(i) => T::from_sqlite_integer(i),
823 rusqlite::types::ValueRef::Text(s) => {
824 let s = core::str::from_utf8(s).map_err(|e| {
825 DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into())
826 })?;
827 T::from_sqlite_text(s)
828 }
829 rusqlite::types::ValueRef::Real(r) => T::from_sqlite_real(r),
830 rusqlite::types::ValueRef::Blob(b) => T::from_sqlite_blob(b),
831 rusqlite::types::ValueRef::Null => T::from_sqlite_null(),
832 }
833 }
834}
835
836#[cfg(feature = "rusqlite")]
837impl DrizzleRowByName for rusqlite::Row<'_> {
838 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
839 let idx = self.as_ref().column_index(name)?;
840 DrizzleRowByIndex::get_column(self, idx)
841 }
842}
843
844#[cfg(feature = "libsql")]
845impl DrizzleRowByIndex for libsql::Row {
846 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
847 let idx_i32 = i32::try_from(idx).map_err(|e| {
848 DrizzleError::ConversionError(format!("column index {idx} out of range: {e}").into())
849 })?;
850 let value = self.get_value(idx_i32)?;
851 match value {
852 libsql::Value::Integer(i) => T::from_sqlite_integer(i),
853 libsql::Value::Text(ref s) => T::from_sqlite_text(s),
854 libsql::Value::Real(r) => T::from_sqlite_real(r),
855 libsql::Value::Blob(ref b) => T::from_sqlite_blob(b),
856 libsql::Value::Null => T::from_sqlite_null(),
857 }
858 }
859}
860
861#[cfg(feature = "libsql")]
862impl DrizzleRowByName for libsql::Row {
863 fn get_column_by_name<T: FromSQLiteValue>(&self, name: &str) -> Result<T, DrizzleError> {
864 let idx = (0..self.column_count())
865 .find(|&i| self.column_name(i) == Some(name))
866 .ok_or_else(|| {
867 DrizzleError::ConversionError(format!("column '{name}' not found").into())
868 })?;
869
870 let idx_usize = usize::try_from(idx).map_err(|e| {
871 DrizzleError::ConversionError(format!("column index {idx} negative: {e}").into())
872 })?;
873 DrizzleRowByIndex::get_column(self, idx_usize)
874 }
875}
876
877#[cfg(feature = "turso")]
878impl DrizzleRowByIndex for turso::Row {
879 fn get_column<T: FromSQLiteValue>(&self, idx: usize) -> Result<T, DrizzleError> {
880 let value = self.get_value(idx)?;
881 if value.is_null() {
882 T::from_sqlite_null()
883 } else if let Some(&i) = value.as_integer() {
884 T::from_sqlite_integer(i)
885 } else if let Some(s) = value.as_text() {
886 T::from_sqlite_text(s)
887 } else if let Some(&r) = value.as_real() {
888 T::from_sqlite_real(r)
889 } else if let Some(b) = value.as_blob() {
890 T::from_sqlite_blob(b)
891 } else {
892 Err(DrizzleError::ConversionError(
893 "unknown SQLite value type".into(),
894 ))
895 }
896 }
897}
898
899#[cfg(feature = "uuid")]
904impl FromSQLiteValue for uuid::Uuid {
905 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
906 Err(DrizzleError::ConversionError(
907 "cannot convert INTEGER to UUID".into(),
908 ))
909 }
910
911 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
912 Self::parse_str(value).map_err(|e| {
913 DrizzleError::ConversionError(format!("invalid UUID string '{value}': {e}").into())
914 })
915 }
916
917 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
918 Err(DrizzleError::ConversionError(
919 "cannot convert REAL to UUID".into(),
920 ))
921 }
922
923 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
924 Self::from_slice(value)
925 .map_err(|e| DrizzleError::ConversionError(format!("invalid UUID bytes: {e}").into()))
926 }
927}
928
929#[cfg(feature = "chrono")]
934impl FromSQLiteValue for chrono::NaiveDate {
935 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
936 Err(DrizzleError::ConversionError(
937 "cannot convert INTEGER to NaiveDate".into(),
938 ))
939 }
940
941 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
942 value.parse().map_err(|e| {
943 DrizzleError::ConversionError(
944 format!("cannot parse '{value}' as NaiveDate: {e}").into(),
945 )
946 })
947 }
948
949 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
950 Err(DrizzleError::ConversionError(
951 "cannot convert REAL to NaiveDate".into(),
952 ))
953 }
954
955 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
956 Err(DrizzleError::ConversionError(
957 "cannot convert BLOB to NaiveDate".into(),
958 ))
959 }
960}
961
962#[cfg(feature = "chrono")]
963impl FromSQLiteValue for chrono::NaiveTime {
964 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
965 Err(DrizzleError::ConversionError(
966 "cannot convert INTEGER to NaiveTime".into(),
967 ))
968 }
969
970 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
971 value.parse().map_err(|e| {
972 DrizzleError::ConversionError(
973 format!("cannot parse '{value}' as NaiveTime: {e}").into(),
974 )
975 })
976 }
977
978 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
979 Err(DrizzleError::ConversionError(
980 "cannot convert REAL to NaiveTime".into(),
981 ))
982 }
983
984 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
985 Err(DrizzleError::ConversionError(
986 "cannot convert BLOB to NaiveTime".into(),
987 ))
988 }
989}
990
991#[cfg(feature = "chrono")]
992impl FromSQLiteValue for chrono::NaiveDateTime {
993 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
994 Err(DrizzleError::ConversionError(
995 "cannot convert INTEGER to NaiveDateTime".into(),
996 ))
997 }
998
999 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1000 value.parse().map_err(|e| {
1001 DrizzleError::ConversionError(
1002 format!("cannot parse '{value}' as NaiveDateTime: {e}").into(),
1003 )
1004 })
1005 }
1006
1007 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1008 Err(DrizzleError::ConversionError(
1009 "cannot convert REAL to NaiveDateTime".into(),
1010 ))
1011 }
1012
1013 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1014 Err(DrizzleError::ConversionError(
1015 "cannot convert BLOB to NaiveDateTime".into(),
1016 ))
1017 }
1018}
1019
1020#[cfg(feature = "chrono")]
1021impl FromSQLiteValue for chrono::DateTime<chrono::FixedOffset> {
1022 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1023 Err(DrizzleError::ConversionError(
1024 "cannot convert INTEGER to DateTime<FixedOffset>".into(),
1025 ))
1026 }
1027
1028 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1029 Self::parse_from_rfc3339(value).map_err(|e| {
1030 DrizzleError::ConversionError(
1031 format!("cannot parse '{value}' as DateTime<FixedOffset>: {e}").into(),
1032 )
1033 })
1034 }
1035
1036 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1037 Err(DrizzleError::ConversionError(
1038 "cannot convert REAL to DateTime<FixedOffset>".into(),
1039 ))
1040 }
1041
1042 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1043 Err(DrizzleError::ConversionError(
1044 "cannot convert BLOB to DateTime<FixedOffset>".into(),
1045 ))
1046 }
1047}
1048
1049#[cfg(feature = "chrono")]
1050impl FromSQLiteValue for chrono::DateTime<chrono::Utc> {
1051 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1052 Err(DrizzleError::ConversionError(
1053 "cannot convert INTEGER to DateTime<Utc>".into(),
1054 ))
1055 }
1056
1057 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1058 value.parse().map_err(|e| {
1059 DrizzleError::ConversionError(
1060 format!("cannot parse '{value}' as DateTime<Utc>: {e}").into(),
1061 )
1062 })
1063 }
1064
1065 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1066 Err(DrizzleError::ConversionError(
1067 "cannot convert REAL to DateTime<Utc>".into(),
1068 ))
1069 }
1070
1071 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1072 Err(DrizzleError::ConversionError(
1073 "cannot convert BLOB to DateTime<Utc>".into(),
1074 ))
1075 }
1076}
1077
1078#[cfg(feature = "time")]
1083impl FromSQLiteValue for time::Date {
1084 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1085 Err(DrizzleError::ConversionError(
1086 "cannot convert INTEGER to time::Date".into(),
1087 ))
1088 }
1089
1090 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1091 Self::parse(value, &time::format_description::well_known::Iso8601::DATE).map_err(|e| {
1092 DrizzleError::ConversionError(
1093 format!("cannot parse '{value}' as time::Date: {e}").into(),
1094 )
1095 })
1096 }
1097
1098 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1099 Err(DrizzleError::ConversionError(
1100 "cannot convert REAL to time::Date".into(),
1101 ))
1102 }
1103
1104 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1105 Err(DrizzleError::ConversionError(
1106 "cannot convert BLOB to time::Date".into(),
1107 ))
1108 }
1109}
1110
1111#[cfg(feature = "time")]
1112impl FromSQLiteValue for time::Time {
1113 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1114 Err(DrizzleError::ConversionError(
1115 "cannot convert INTEGER to time::Time".into(),
1116 ))
1117 }
1118
1119 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1120 Self::parse(value, &time::format_description::well_known::Iso8601::TIME).map_err(|e| {
1121 DrizzleError::ConversionError(
1122 format!("cannot parse '{value}' as time::Time: {e}").into(),
1123 )
1124 })
1125 }
1126
1127 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1128 Err(DrizzleError::ConversionError(
1129 "cannot convert REAL to time::Time".into(),
1130 ))
1131 }
1132
1133 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1134 Err(DrizzleError::ConversionError(
1135 "cannot convert BLOB to time::Time".into(),
1136 ))
1137 }
1138}
1139
1140#[cfg(feature = "time")]
1141impl FromSQLiteValue for time::PrimitiveDateTime {
1142 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1143 Err(DrizzleError::ConversionError(
1144 "cannot convert INTEGER to time::PrimitiveDateTime".into(),
1145 ))
1146 }
1147
1148 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1149 Self::parse(
1150 value,
1151 &time::format_description::well_known::Iso8601::DATE_TIME,
1152 )
1153 .map_err(|e| {
1154 DrizzleError::ConversionError(
1155 format!("cannot parse '{value}' as time::PrimitiveDateTime: {e}").into(),
1156 )
1157 })
1158 }
1159
1160 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1161 Err(DrizzleError::ConversionError(
1162 "cannot convert REAL to time::PrimitiveDateTime".into(),
1163 ))
1164 }
1165
1166 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1167 Err(DrizzleError::ConversionError(
1168 "cannot convert BLOB to time::PrimitiveDateTime".into(),
1169 ))
1170 }
1171}
1172
1173#[cfg(feature = "time")]
1174impl FromSQLiteValue for time::OffsetDateTime {
1175 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1176 Err(DrizzleError::ConversionError(
1177 "cannot convert INTEGER to time::OffsetDateTime".into(),
1178 ))
1179 }
1180
1181 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1182 Self::parse(value, &time::format_description::well_known::Rfc3339).map_err(|e| {
1183 DrizzleError::ConversionError(
1184 format!("cannot parse '{value}' as time::OffsetDateTime: {e}").into(),
1185 )
1186 })
1187 }
1188
1189 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1190 Err(DrizzleError::ConversionError(
1191 "cannot convert REAL to time::OffsetDateTime".into(),
1192 ))
1193 }
1194
1195 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1196 Err(DrizzleError::ConversionError(
1197 "cannot convert BLOB to time::OffsetDateTime".into(),
1198 ))
1199 }
1200}
1201
1202#[cfg(feature = "rust-decimal")]
1207impl FromSQLiteValue for rust_decimal::Decimal {
1208 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1209 Ok(Self::from(value))
1210 }
1211
1212 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1213 value.parse().map_err(|e| {
1214 DrizzleError::ConversionError(format!("cannot parse '{value}' as Decimal: {e}").into())
1215 })
1216 }
1217
1218 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1219 Self::try_from(value).map_err(|e| {
1220 DrizzleError::ConversionError(
1221 format!("cannot convert REAL {value} to Decimal: {e}").into(),
1222 )
1223 })
1224 }
1225
1226 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1227 Err(DrizzleError::ConversionError(
1228 "cannot convert BLOB to Decimal".into(),
1229 ))
1230 }
1231}
1232
1233#[cfg(feature = "chrono")]
1238impl FromSQLiteValue for chrono::Duration {
1239 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1240 Ok(Self::seconds(value))
1241 }
1242
1243 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1244 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1246 DrizzleError::ConversionError(
1247 format!("cannot parse '{value}' as chrono::Duration: {e}").into(),
1248 )
1249 })?;
1250 Ok(Self::seconds(secs))
1251 }
1252
1253 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1254 let millis: i64 = format!("{:.0}", value * 1000.0).parse().map_err(|e| {
1255 DrizzleError::ConversionError(
1256 format!("cannot convert REAL {value} to chrono::Duration: {e}").into(),
1257 )
1258 })?;
1259 Ok(Self::milliseconds(millis))
1260 }
1261
1262 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1263 Err(DrizzleError::ConversionError(
1264 "cannot convert BLOB to chrono::Duration".into(),
1265 ))
1266 }
1267}
1268
1269#[cfg(feature = "time")]
1270impl FromSQLiteValue for time::Duration {
1271 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1272 Ok(Self::seconds(value))
1273 }
1274
1275 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1276 let secs: i64 = value.trim_end_matches('s').parse().map_err(|e| {
1278 DrizzleError::ConversionError(
1279 format!("cannot parse '{value}' as time::Duration: {e}").into(),
1280 )
1281 })?;
1282 Ok(Self::seconds(secs))
1283 }
1284
1285 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1286 Ok(Self::seconds_f64(value))
1287 }
1288
1289 fn from_sqlite_blob(_value: &[u8]) -> Result<Self, DrizzleError> {
1290 Err(DrizzleError::ConversionError(
1291 "cannot convert BLOB to time::Duration".into(),
1292 ))
1293 }
1294}
1295
1296#[cfg(feature = "serde")]
1301impl FromSQLiteValue for serde_json::Value {
1302 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1303 Ok(Self::Number(value.into()))
1304 }
1305
1306 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1307 serde_json::from_str(value).map_err(|e| {
1308 DrizzleError::ConversionError(format!("cannot parse '{value}' as JSON: {e}").into())
1309 })
1310 }
1311
1312 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1313 serde_json::Number::from_f64(value)
1314 .map(serde_json::Value::Number)
1315 .ok_or_else(|| {
1316 DrizzleError::ConversionError(
1317 format!("cannot convert non-finite REAL {value} to JSON").into(),
1318 )
1319 })
1320 }
1321
1322 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1323 serde_json::from_slice(value).map_err(|e| {
1324 DrizzleError::ConversionError(format!("cannot parse BLOB as JSON: {e}").into())
1325 })
1326 }
1327}
1328
1329#[cfg(feature = "arrayvec")]
1334impl<const N: usize> FromSQLiteValue for arrayvec::ArrayString<N> {
1335 fn from_sqlite_integer(value: i64) -> Result<Self, DrizzleError> {
1336 let s = value.to_string();
1337 Self::from(&s).map_err(|_| {
1338 DrizzleError::ConversionError(
1339 format!(
1340 "String length {} exceeds ArrayString capacity {}",
1341 s.len(),
1342 N
1343 )
1344 .into(),
1345 )
1346 })
1347 }
1348
1349 fn from_sqlite_text(value: &str) -> Result<Self, DrizzleError> {
1350 Self::from(value).map_err(|_| {
1351 DrizzleError::ConversionError(
1352 format!(
1353 "Text length {} exceeds ArrayString capacity {}",
1354 value.len(),
1355 N
1356 )
1357 .into(),
1358 )
1359 })
1360 }
1361
1362 fn from_sqlite_real(value: f64) -> Result<Self, DrizzleError> {
1363 let s = value.to_string();
1364 Self::from(&s).map_err(|_| {
1365 DrizzleError::ConversionError(
1366 format!(
1367 "String length {} exceeds ArrayString capacity {}",
1368 s.len(),
1369 N
1370 )
1371 .into(),
1372 )
1373 })
1374 }
1375
1376 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1377 let s = String::from_utf8(value.to_vec())
1378 .map_err(|e| DrizzleError::ConversionError(format!("invalid UTF-8: {e}").into()))?;
1379 Self::from(&s).map_err(|_| {
1380 DrizzleError::ConversionError(
1381 format!(
1382 "String length {} exceeds ArrayString capacity {}",
1383 s.len(),
1384 N
1385 )
1386 .into(),
1387 )
1388 })
1389 }
1390}
1391
1392#[cfg(feature = "arrayvec")]
1393impl<const N: usize> FromSQLiteValue for arrayvec::ArrayVec<u8, N> {
1394 fn from_sqlite_integer(_value: i64) -> Result<Self, DrizzleError> {
1395 Err(DrizzleError::ConversionError(
1396 "cannot convert INTEGER to ArrayVec<u8>, use BLOB".into(),
1397 ))
1398 }
1399
1400 fn from_sqlite_text(_value: &str) -> Result<Self, DrizzleError> {
1401 Err(DrizzleError::ConversionError(
1402 "cannot convert TEXT to ArrayVec<u8>, use BLOB".into(),
1403 ))
1404 }
1405
1406 fn from_sqlite_real(_value: f64) -> Result<Self, DrizzleError> {
1407 Err(DrizzleError::ConversionError(
1408 "cannot convert REAL to ArrayVec<u8>, use BLOB".into(),
1409 ))
1410 }
1411
1412 fn from_sqlite_blob(value: &[u8]) -> Result<Self, DrizzleError> {
1413 Self::try_from(value).map_err(|_| {
1414 DrizzleError::ConversionError(
1415 format!(
1416 "Blob length {} exceeds ArrayVec capacity {}",
1417 value.len(),
1418 N
1419 )
1420 .into(),
1421 )
1422 })
1423 }
1424}