sqlmodel_frankensqlite/
value.rs1use fsqlite_types::value::SqliteValue;
4use sqlmodel_core::value::Value;
5
6#[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)]
8pub fn value_to_sqlite(v: &Value) -> SqliteValue {
9 match v {
10 Value::Null | Value::Default => SqliteValue::Null,
11 Value::Bool(b) => SqliteValue::Integer(i64::from(*b)),
12 Value::TinyInt(i) => SqliteValue::Integer(i64::from(*i)),
13 Value::SmallInt(i) => SqliteValue::Integer(i64::from(*i)),
14 Value::Int(i) => SqliteValue::Integer(i64::from(*i)),
15 Value::BigInt(i) => SqliteValue::Integer(*i),
16 Value::Float(f) => SqliteValue::Float(f64::from(*f)),
17 Value::Double(f) => SqliteValue::Float(*f),
18 Value::Decimal(s) => {
19 if let Ok(i) = s.parse::<i64>() {
21 SqliteValue::Integer(i)
22 } else if let Ok(f) = s.parse::<f64>() {
23 SqliteValue::Float(f)
24 } else {
25 SqliteValue::Text(s.clone())
26 }
27 }
28 Value::Text(s) => SqliteValue::Text(s.clone()),
29 Value::Bytes(b) => SqliteValue::Blob(b.clone()),
30 Value::Date(d) => SqliteValue::Integer(i64::from(*d)),
31 Value::Time(t) => SqliteValue::Integer(*t),
32 Value::Timestamp(ts) => SqliteValue::Integer(*ts),
33 Value::TimestampTz(ts) => SqliteValue::Integer(*ts),
34 Value::Uuid(bytes) => SqliteValue::Blob(bytes.to_vec()),
35 Value::Json(v) => SqliteValue::Text(serde_json::to_string(v).unwrap_or_default()),
36 Value::Array(_) => SqliteValue::Null, }
38}
39
40pub fn sqlite_to_value(sv: &SqliteValue) -> Value {
42 match sv {
43 SqliteValue::Null => Value::Null,
44 SqliteValue::Integer(i) => Value::BigInt(*i),
45 SqliteValue::Float(f) => Value::Double(*f),
46 SqliteValue::Text(s) => Value::Text(s.clone()),
47 SqliteValue::Blob(b) => Value::Bytes(b.clone()),
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn null_roundtrip() {
57 assert!(matches!(value_to_sqlite(&Value::Null), SqliteValue::Null));
58 assert!(matches!(sqlite_to_value(&SqliteValue::Null), Value::Null));
59 }
60
61 #[test]
62 fn bool_to_integer() {
63 assert_eq!(value_to_sqlite(&Value::Bool(true)), SqliteValue::Integer(1));
64 assert_eq!(
65 value_to_sqlite(&Value::Bool(false)),
66 SqliteValue::Integer(0)
67 );
68 }
69
70 #[test]
71 fn integer_variants() {
72 assert_eq!(
73 value_to_sqlite(&Value::TinyInt(42)),
74 SqliteValue::Integer(42)
75 );
76 assert_eq!(
77 value_to_sqlite(&Value::SmallInt(1000)),
78 SqliteValue::Integer(1000)
79 );
80 assert_eq!(
81 value_to_sqlite(&Value::Int(100_000)),
82 SqliteValue::Integer(100_000)
83 );
84 assert_eq!(
85 value_to_sqlite(&Value::BigInt(i64::MAX)),
86 SqliteValue::Integer(i64::MAX)
87 );
88 }
89
90 #[test]
91 fn float_variants() {
92 let sv = value_to_sqlite(&Value::Float(3.14));
93 assert!(matches!(sv, SqliteValue::Float(_)));
94
95 assert_eq!(
96 value_to_sqlite(&Value::Double(2.718)),
97 SqliteValue::Float(2.718)
98 );
99 }
100
101 #[test]
102 fn text_roundtrip() {
103 let v = Value::Text("hello".into());
104 let sv = value_to_sqlite(&v);
105 assert_eq!(sv, SqliteValue::Text("hello".into()));
106 assert_eq!(sqlite_to_value(&sv), v);
107 }
108
109 #[test]
110 fn bytes_roundtrip() {
111 let v = Value::Bytes(vec![0xDE, 0xAD]);
112 let sv = value_to_sqlite(&v);
113 assert_eq!(sv, SqliteValue::Blob(vec![0xDE, 0xAD]));
114 assert_eq!(sqlite_to_value(&sv), v);
115 }
116
117 #[test]
118 fn json_to_text() {
119 let json = serde_json::json!({"key": "value"});
120 let sv = value_to_sqlite(&Value::Json(json.clone()));
121 assert!(matches!(sv, SqliteValue::Text(_)));
122 }
123
124 #[test]
125 fn uuid_to_blob() {
126 let uuid = [1u8; 16];
127 let sv = value_to_sqlite(&Value::Uuid(uuid));
128 assert_eq!(sv, SqliteValue::Blob(uuid.to_vec()));
129 }
130
131 #[test]
132 fn decimal_string_to_integer() {
133 let sv = value_to_sqlite(&Value::Decimal("42".into()));
134 assert_eq!(sv, SqliteValue::Integer(42));
135 }
136
137 #[test]
138 fn decimal_string_to_float() {
139 let sv = value_to_sqlite(&Value::Decimal("3.14".into()));
140 assert!(matches!(sv, SqliteValue::Float(_)));
141 }
142
143 #[test]
144 fn timestamp_to_integer() {
145 let v = Value::Timestamp(1_700_000_000_000_000);
146 let sv = value_to_sqlite(&v);
147 assert_eq!(sv, SqliteValue::Integer(1_700_000_000_000_000));
148 }
149
150 #[test]
151 fn default_to_null() {
152 assert!(matches!(
153 value_to_sqlite(&Value::Default),
154 SqliteValue::Null
155 ));
156 }
157
158 #[test]
159 fn sqlite_integer_to_bigint() {
160 let v = sqlite_to_value(&SqliteValue::Integer(42));
161 assert_eq!(v, Value::BigInt(42));
162 }
163
164 #[test]
165 fn sqlite_float_to_double() {
166 let v = sqlite_to_value(&SqliteValue::Float(3.14));
167 assert_eq!(v, Value::Double(3.14));
168 }
169}