sql_middleware/sqlite/
params.rs1use deadpool_sqlite::rusqlite;
2use deadpool_sqlite::rusqlite::ParamsFromIter;
3use rusqlite::types::Value;
4use std::fmt::Write;
5
6use crate::middleware::{ConversionMode, ParamConverter, RowValues, SqlMiddlewareDbError};
7
8thread_local! {
10 static TIMESTAMP_BUF: std::cell::RefCell<String> = std::cell::RefCell::new(String::with_capacity(32));
11}
12
13pub fn row_value_to_sqlite_value(value: &RowValues, for_execute: bool) -> rusqlite::types::Value {
15 match value {
16 RowValues::Int(i) => rusqlite::types::Value::Integer(*i),
17 RowValues::Float(f) => rusqlite::types::Value::Real(*f),
18 RowValues::Text(s) => {
19 if for_execute {
20 rusqlite::types::Value::Text(s.clone())
22 } else {
23 rusqlite::types::Value::Text(s.clone())
25 }
26 }
27 RowValues::Bool(b) => rusqlite::types::Value::Integer(i64::from(*b)),
28 RowValues::Timestamp(dt) => {
30 TIMESTAMP_BUF.with(|buf| {
32 let mut borrow = buf.borrow_mut();
33 borrow.clear();
34 write!(borrow, "{}", dt.format("%F %T%.f")).unwrap();
36 rusqlite::types::Value::Text(borrow.clone())
37 })
38 }
39 RowValues::Null => rusqlite::types::Value::Null,
40 RowValues::JSON(jval) => {
41 let json_str = jval.to_string();
43 rusqlite::types::Value::Text(json_str)
44 }
45 RowValues::Blob(bytes) => {
46 if for_execute {
47 rusqlite::types::Value::Blob(bytes.clone())
49 } else {
50 rusqlite::types::Value::Blob(bytes.clone())
52 }
53 }
54 }
55}
56
57pub fn convert_params(params: &[RowValues]) -> Vec<rusqlite::types::Value> {
59 let mut vec_values = Vec::with_capacity(params.len());
60 for p in params {
61 vec_values.push(row_value_to_sqlite_value(p, false));
62 }
63 vec_values
64}
65
66pub fn convert_params_for_execute<I>(iter: I) -> ParamsFromIter<std::vec::IntoIter<Value>>
68where
69 I: IntoIterator<Item = RowValues>,
70{
71 let mut values = Vec::new();
73 for p in iter {
74 values.push(row_value_to_sqlite_value(&p, true));
75 }
76 #[allow(clippy::useless_conversion)]
80 rusqlite::params_from_iter(values.into_iter())
81}
82
83pub struct SqliteParamsQuery(pub Vec<rusqlite::types::Value>);
85
86pub struct SqliteParamsExecute(
88 pub rusqlite::ParamsFromIter<std::vec::IntoIter<rusqlite::types::Value>>,
89);
90
91impl ParamConverter<'_> for SqliteParamsQuery {
92 type Converted = Self;
93
94 fn convert_sql_params(
95 params: &[RowValues],
96 mode: ConversionMode,
97 ) -> Result<Self::Converted, SqlMiddlewareDbError> {
98 match mode {
99 ConversionMode::Query => Ok(SqliteParamsQuery(convert_params(params))),
101 ConversionMode::Execute => {
103 Ok(SqliteParamsQuery(convert_params(params)))
105 }
106 }
107 }
108
109 fn supports_mode(mode: ConversionMode) -> bool {
110 mode == ConversionMode::Query
112 }
113}
114
115impl ParamConverter<'_> for SqliteParamsExecute {
116 type Converted = Self;
117
118 fn convert_sql_params(
119 params: &[RowValues],
120 mode: ConversionMode,
121 ) -> Result<Self::Converted, SqlMiddlewareDbError> {
122 match mode {
123 ConversionMode::Execute => Ok(SqliteParamsExecute(convert_params_for_execute(
124 params.to_vec(),
125 ))),
126 ConversionMode::Query => Err(SqlMiddlewareDbError::ParameterError(
128 "SqliteParamsExecute can only be used with Execute mode".into(),
129 )),
130 }
131 }
132
133 fn supports_mode(mode: ConversionMode) -> bool {
134 mode == ConversionMode::Execute
136 }
137}