mybatis_core/sqlite/
sqlx_value.rs

1use chrono::Utc;
2use rbson::spec::BinarySubtype;
3use rbson::{bson, to_bson, Bson};
4use sqlx_core::column::Column;
5use sqlx_core::decode::Decode;
6use sqlx_core::error::BoxDynError;
7use sqlx_core::row::Row;
8use sqlx_core::sqlite::SqliteRow;
9use sqlx_core::sqlite::{Sqlite, SqliteValue, SqliteValueRef};
10use sqlx_core::type_info::TypeInfo;
11use sqlx_core::value::ValueRef;
12
13use crate::convert::{JsonCodec, RefJsonCodec, ResultCodec};
14use crate::db::db_adapter::DataDecoder;
15use crate::to_bson_macro;
16
17impl<'c> JsonCodec for SqliteValueRef<'c> {
18    fn try_to_bson(self) -> crate::Result<Bson> {
19        let type_string = self.type_info().name().to_owned();
20        return match type_string.as_str() {
21            "NULL" => Ok(Bson::Null),
22            "TEXT" => {
23                let r: Option<String> = Decode::<'_, Sqlite>::decode(self)?;
24                return Ok(to_bson_macro!(r));
25            }
26            "BOOLEAN" => {
27                let r: Option<bool> = Decode::<'_, Sqlite>::decode(self)?;
28                return Ok(to_bson_macro!(r));
29            }
30            "INTEGER" => {
31                let r: Option<i64> = Decode::<'_, Sqlite>::decode(self)?;
32                return Ok(to_bson_macro!(r));
33            }
34            "REAL" => {
35                let r: Option<f64> = Decode::<'_, Sqlite>::decode(self)?;
36                return Ok(to_bson_macro!(r));
37            }
38            "BLOB" => {
39                let r: Option<Vec<u8>> = Decode::<'_, Sqlite>::decode(self)?;
40                if let Some(r) = r {
41                    return Ok(Bson::Binary(rbson::Binary {
42                        subtype: BinarySubtype::Generic,
43                        bytes: r,
44                    }));
45                }
46                return Ok(Bson::Null);
47            }
48            "DATE" => {
49                let r: Option<chrono::NaiveDate> = Decode::<'_, Sqlite>::decode(self)?;
50                return Ok(to_bson(&r).unwrap_or_default());
51            }
52            "TIME" => {
53                let r: Option<chrono::NaiveTime> = Decode::<'_, Sqlite>::decode(self)?;
54                return Ok(to_bson(&r).unwrap_or_default());
55            }
56            "DATETIME" => {
57                let r: Option<chrono::NaiveDateTime> = Decode::<'_, Sqlite>::decode(self)?;
58                if let Some(dt) = r {
59                    return Ok(Bson::String(dt.format("%Y-%m-%dT%H:%M:%S").to_string()));
60                }
61                return Ok(Bson::Null);
62            }
63            _ => {
64                //TODO "NUMERIC"
65                //you can use already supported types to decode this
66                let r: Option<Vec<u8>> = Decode::<'_, Sqlite>::decode(self)?;
67                if let Some(r) = r {
68                    return Ok(Bson::Binary(rbson::Binary {
69                        subtype: BinarySubtype::Generic,
70                        bytes: r,
71                    }));
72                }
73                return Ok(Bson::Null);
74            }
75        };
76    }
77}
78
79impl RefJsonCodec for Vec<SqliteRow> {
80    fn try_to_bson(&self, decoder: &dyn DataDecoder) -> crate::Result<Bson> {
81        let mut arr = Vec::with_capacity(self.len());
82        for row in self {
83            let mut m = rbson::Document::new();
84            let columns = row.columns();
85            for x in columns {
86                let key = x.name();
87                let v: SqliteValueRef = row.try_get_raw(key)?;
88                let mut bson = v.try_to_bson()?;
89                decoder.decode(key, &mut bson)?;
90                m.insert(key.to_owned(), bson);
91            }
92            arr.push(Bson::Document(m));
93        }
94        Ok(Bson::from(arr))
95    }
96}