spin_sdk/
sqlite.rs

1use super::wit::v2::sqlite;
2
3#[doc(inline)]
4pub use sqlite::{Connection, Error, QueryResult, RowResult, Value};
5
6impl sqlite::Connection {
7    /// Open a connection to the default database
8    pub fn open_default() -> Result<Self, Error> {
9        Self::open("default")
10    }
11}
12
13impl sqlite::QueryResult {
14    /// Get all the rows for this query result
15    pub fn rows(&self) -> impl Iterator<Item = Row<'_>> {
16        self.rows.iter().map(|r| Row {
17            columns: self.columns.as_slice(),
18            result: r,
19        })
20    }
21}
22
23/// A database row result
24pub struct Row<'a> {
25    columns: &'a [String],
26    result: &'a sqlite::RowResult,
27}
28
29impl<'a> Row<'a> {
30    /// Get a value by its column name
31    pub fn get<T: TryFrom<&'a Value>>(&self, column: &str) -> Option<T> {
32        let i = self.columns.iter().position(|c| c == column)?;
33        self.result.get(i)
34    }
35}
36
37impl sqlite::RowResult {
38    /// Get a value by its index
39    pub fn get<'a, T: TryFrom<&'a Value>>(&'a self, index: usize) -> Option<T> {
40        self.values.get(index).and_then(|c| c.try_into().ok())
41    }
42}
43
44impl<'a> TryFrom<&'a Value> for bool {
45    type Error = ();
46
47    fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
48        match value {
49            Value::Integer(i) => Ok(*i != 0),
50            _ => Err(()),
51        }
52    }
53}
54
55macro_rules! int_conversions {
56    ($($t:ty),*) => {
57        $(impl<'a> TryFrom<&'a Value> for $t {
58            type Error = ();
59
60            fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
61                match value {
62                    Value::Integer(i) => (*i).try_into().map_err(|_| ()),
63                    _ => Err(()),
64                }
65            }
66        })*
67    };
68}
69
70int_conversions!(u8, u16, u32, u64, i8, i16, i32, i64, usize, isize);
71
72impl<'a> TryFrom<&'a Value> for f64 {
73    type Error = ();
74
75    fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
76        match value {
77            Value::Real(f) => Ok(*f),
78            _ => Err(()),
79        }
80    }
81}
82
83impl<'a> TryFrom<&'a Value> for &'a str {
84    type Error = ();
85
86    fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
87        match value {
88            Value::Text(s) => Ok(s.as_str()),
89            Value::Blob(b) => std::str::from_utf8(b).map_err(|_| ()),
90            _ => Err(()),
91        }
92    }
93}
94
95impl<'a> TryFrom<&'a Value> for &'a [u8] {
96    type Error = ();
97
98    fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
99        match value {
100            Value::Blob(b) => Ok(b.as_slice()),
101            Value::Text(s) => Ok(s.as_bytes()),
102            _ => Err(()),
103        }
104    }
105}