use crate::middleware::{ConversionMode, ParamConverter, RowValues, SqlMiddlewareDbError};
pub struct Params(pub turso::params::Params);
fn row_value_to_turso_value(value: &RowValues, _for_execute: bool) -> turso::Value {
match value {
RowValues::Int(i) => turso::Value::Integer(*i),
RowValues::Float(f) => turso::Value::Real(*f),
RowValues::Text(s) => turso::Value::Text(s.clone()),
RowValues::Bool(b) => turso::Value::Integer(i64::from(*b)),
RowValues::Timestamp(dt) => {
turso::Value::Text(dt.format("%F %T%.f").to_string())
}
RowValues::Null => turso::Value::Null,
RowValues::JSON(j) => turso::Value::Text(j.to_string()),
RowValues::Blob(bytes) => turso::Value::Blob(bytes.clone()),
}
}
fn convert_params(params: &[RowValues]) -> turso::params::Params {
if params.is_empty() {
turso::params::Params::None
} else {
let values: Vec<turso::Value> = params
.iter()
.map(|p| row_value_to_turso_value(p, false))
.collect();
turso::params::Params::Positional(values)
}
}
fn convert_params_for_execute(params: &[RowValues]) -> turso::params::Params {
if params.is_empty() {
turso::params::Params::None
} else {
let values: Vec<turso::Value> = params
.iter()
.map(|p| row_value_to_turso_value(p, true))
.collect();
turso::params::Params::Positional(values)
}
}
impl ParamConverter<'_> for Params {
type Converted = Params;
fn convert_sql_params(
params: &[RowValues],
mode: ConversionMode,
) -> Result<Self::Converted, SqlMiddlewareDbError> {
match mode {
ConversionMode::Query => Ok(Params(convert_params(params))),
ConversionMode::Execute => Ok(Params(convert_params_for_execute(params))),
}
}
fn supports_mode(_mode: ConversionMode) -> bool {
true
}
}
#[derive(Debug, Clone, Default)]
pub struct TursoParamsBuf {
values: Vec<turso::Value>,
}
impl TursoParamsBuf {
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
values: Vec::with_capacity(capacity),
}
}
pub fn clear(&mut self) {
self.values.clear();
}
#[must_use]
pub fn len(&self) -> usize {
self.values.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
#[must_use]
pub fn to_params(&self) -> turso::params::Params {
if self.values.is_empty() {
turso::params::Params::None
} else {
turso::params::Params::Positional(self.values.clone())
}
}
pub fn set_int(&mut self, index: usize, value: i64) {
self.set_value(index, turso::Value::Integer(value));
}
pub fn set_float(&mut self, index: usize, value: f64) {
self.set_value(index, turso::Value::Real(value));
}
pub fn set_text(&mut self, index: usize, value: impl Into<String>) {
self.set_value(index, turso::Value::Text(value.into()));
}
pub fn set_bool(&mut self, index: usize, value: bool) {
self.set_value(index, turso::Value::Integer(i64::from(value)));
}
pub fn set_timestamp(&mut self, index: usize, value: chrono::NaiveDateTime) {
self.set_value(
index,
turso::Value::Text(value.format("%F %T%.f").to_string()),
);
}
pub fn set_json(&mut self, index: usize, value: serde_json::Value) {
self.set_value(index, turso::Value::Text(value.to_string()));
}
pub fn set_blob(&mut self, index: usize, value: impl Into<Vec<u8>>) {
self.set_value(index, turso::Value::Blob(value.into()));
}
pub fn set_null(&mut self, index: usize) {
self.set_value(index, turso::Value::Null);
}
fn set_value(&mut self, index: usize, value: turso::Value) {
if self.values.len() <= index {
self.values.resize_with(index + 1, || turso::Value::Null);
}
self.values[index] = value;
}
}