vtx_sdk/
db.rs

1use crate::bindings::vtx::api::sql::{self, DbValue};
2use crate::error::{VtxError, VtxResult};
3use serde::de::DeserializeOwned;
4
5/// Trait:用于将 Rust 类型转换为 WIT 定义的 `DbValue`
6///
7/// 适用于数据库跨边界调用参数传递。
8pub trait ToDbValue {
9    fn to_db_value(&self) -> DbValue;
10}
11
12// --- 基本类型到 DbValue 的映射实现 ---
13
14impl 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
44/// 执行非查询类 SQL(INSERT / UPDATE / DELETE)
45///
46/// # Parameters
47/// - `sql`: SQL 原始字符串,支持 `?` 占位符
48/// - `params`: 参数数组,元素需实现 `ToDbValue`
49///
50/// # Returns
51/// - 成功:返回影响行数
52/// - 失败:映射为 `VtxError::DatabaseError`
53///
54/// ⚠️ 注意:Restricted 安全策略下禁止调用该接口
55pub fn execute(sql: &str, params: &[&dyn ToDbValue]) -> VtxResult<u64> {
56    let wit_params: Vec<DbValue> = params.iter().map(|p| p.to_db_value()).collect();
57
58    sql::execute(sql, &wit_params).map_err(VtxError::DatabaseError)
59}
60
61/// 执行查询类 SQL(SELECT)并反序列化为目标类型列表
62///
63/// # Parameters
64/// - `sql`: SQL 字符串(支持 ? 占位符)
65/// - `params`: 参数数组(实现 `ToDbValue`)
66///
67/// # Returns
68/// - 成功:反序列化后的结果集合
69/// - 失败:`DatabaseError` 或 `SerializationError`
70///
71/// # Notes
72/// - 宿主接口返回的是 JSON 字符串
73/// - 为保证性能,建议单次返回控制在 1MB 内(可通过 LIMIT 分页)
74/// - 泛型 `T` 必须实现 `DeserializeOwned`(无需生命周期)
75///
76pub fn query<T: DeserializeOwned>(sql: &str, params: &[&dyn ToDbValue]) -> VtxResult<Vec<T>> {
77    let wit_params: Vec<DbValue> = params.iter().map(|p| p.to_db_value()).collect();
78
79    let json_str = sql::query_json(sql, &wit_params).map_err(VtxError::DatabaseError)?;
80
81    serde_json::from_str(&json_str).map_err(|e| VtxError::SerializationError(e.to_string()))
82}