1use crate::bindings::vtx::api::sql::{self, DbValue};
2use crate::error::{VtxError, VtxResult};
3use serde::de::DeserializeOwned;
4
5pub trait ToDbValue {
9 fn to_db_value(&self) -> DbValue;
10}
11
12impl ToDbValue for String {
15 fn to_db_value(&self) -> DbValue {
16 DbValue::Text(self.clone())
17 }
18}
19
20impl ToDbValue for &str {
21 fn to_db_value(&self) -> DbValue {
22 DbValue::Text(self.to_string())
23 }
24}
25
26impl ToDbValue for i64 {
27 fn to_db_value(&self) -> DbValue {
28 DbValue::Integer(*self)
29 }
30}
31
32impl ToDbValue for i32 {
33 fn to_db_value(&self) -> DbValue {
34 DbValue::Integer(*self as i64)
35 }
36}
37
38impl ToDbValue for f64 {
39 fn to_db_value(&self) -> DbValue {
40 DbValue::Real(*self)
41 }
42}
43
44impl ToDbValue for f32 {
45 fn to_db_value(&self) -> DbValue {
46 DbValue::Real(*self as f64)
47 }
48}
49
50impl ToDbValue for u64 {
51 fn to_db_value(&self) -> DbValue {
52 DbValue::Integer(*self as i64)
53 }
54}
55
56impl ToDbValue for u32 {
57 fn to_db_value(&self) -> DbValue {
58 DbValue::Integer(*self as i64)
59 }
60}
61
62impl ToDbValue for bool {
63 fn to_db_value(&self) -> DbValue {
64 DbValue::Integer(if *self { 1 } else { 0 })
65 }
66}
67
68impl ToDbValue for () {
69 fn to_db_value(&self) -> DbValue {
70 DbValue::NullVal
71 }
72}
73
74impl<T: ToDbValue> ToDbValue for Option<T> {
75 fn to_db_value(&self) -> DbValue {
76 match self {
77 Some(v) => v.to_db_value(),
78 None => DbValue::NullVal,
79 }
80 }
81}
82
83pub fn execute(sql: &str, params: &[&dyn ToDbValue]) -> VtxResult<u64> {
95 let wit_params: Vec<DbValue> = params.iter().map(|p| p.to_db_value()).collect();
96
97 sql::execute(sql, &wit_params).map_err(|e| {
98 if e.to_lowercase().contains("permission denied") {
99 VtxError::PermissionDenied(e)
100 } else {
101 VtxError::DatabaseError(e)
102 }
103 })
104}
105
106pub fn query<T: DeserializeOwned>(sql: &str, params: &[&dyn ToDbValue]) -> VtxResult<Vec<T>> {
122 let wit_params: Vec<DbValue> = params.iter().map(|p| p.to_db_value()).collect();
123
124 let json_str = sql::query_json(sql, &wit_params).map_err(|e| {
125 if e.to_lowercase().contains("permission denied") {
126 VtxError::PermissionDenied(e)
127 } else {
128 VtxError::DatabaseError(e)
129 }
130 })?;
131
132 serde_json::from_str(&json_str).map_err(|e| VtxError::SerializationError(e.to_string()))
133}