rquickjs_extra_sqlite/
value.rs

1use rquickjs::{Ctx, Exception, IntoJs, Result, String, TypedArray};
2use rquickjs_extra_utils::result::ResultExt;
3use sqlx::sqlite::{SqliteColumn, SqliteRow};
4use sqlx::{Column as _, Decode, Row as _, TypeInfo as _, ValueRef};
5
6pub enum Value<'q> {
7    Null,
8    Integer(i64),
9    Real(f64),
10    Text(&'q str),
11    Blob(&'q [u8]),
12}
13
14impl<'q, 'js> IntoJs<'js> for Value<'q>
15where
16    'js: 'q,
17{
18    fn into_js(self, ctx: &Ctx<'js>) -> Result<rquickjs::Value<'js>> {
19        match self {
20            Value::Null => Ok(rquickjs::Value::new_null(ctx.clone())),
21            Value::Integer(int) => Ok(int.into_js(ctx)?),
22            Value::Real(float) => Ok(float.into_js(ctx)?),
23            Value::Text(s) => Ok(String::from_str(ctx.clone(), s)?.into_value()),
24            Value::Blob(b) => Ok(TypedArray::<u8>::new_copy(ctx.clone(), b)?.into_value()),
25        }
26    }
27}
28
29impl<'q> Value<'q> {
30    pub fn try_read(ctx: &Ctx<'_>, column: &'q SqliteColumn, row: &'q SqliteRow) -> Result<Self> {
31        let value = row.try_get_raw(column.ordinal()).or_throw(ctx)?;
32
33        // This is annoying since in theory sqlx can change the string representation
34        // but we don't really have a better way to get that information.
35        // Also note that only base types will be present in that call, if we want to
36        // get more fancy (boolean, datetime, etc) we need to use the column type info.
37        // See https://github.com/launchbadge/sqlx/issues/606
38        match value.type_info().name() {
39            "NULL" => Ok(Value::Null),
40            "INTEGER" => Ok(Value::Integer(Decode::decode(value).or_throw(ctx)?)),
41            "REAL" => Ok(Value::Real(Decode::decode(value).or_throw(ctx)?)),
42            "TEXT" => Ok(Value::Text(Decode::decode(value).or_throw(ctx)?)),
43            "BLOB" => Ok(Value::Blob(Decode::decode(value).or_throw(ctx)?)),
44            name => Err(Exception::throw_message(
45                ctx,
46                &["Unsupported type: ", name].concat(),
47            )),
48        }
49    }
50}