use std::sync::Arc;
use crate::adapters::params::convert_params;
use crate::middleware::{ConversionMode, SqlMiddlewareDbError};
use crate::types::RowValues;
use super::{SqliteConnection, run_blocking};
use crate::sqlite::config::SqliteManager;
use crate::sqlite::params::Params;
use bb8::PooledConnection;
impl SqliteConnection {
pub async fn execute_batch(&mut self, query: &str) -> Result<(), SqlMiddlewareDbError> {
self.ensure_not_in_tx("execute batch")?;
let sql_owned = query.to_owned();
run_blocking(self.conn_handle(), move |guard| {
if guard.is_autocommit() {
let tx = guard
.transaction()
.map_err(SqlMiddlewareDbError::SqliteError)?;
tx.execute_batch(&sql_owned)
.map_err(SqlMiddlewareDbError::SqliteError)?;
tx.commit().map_err(SqlMiddlewareDbError::SqliteError)
} else {
guard
.execute_batch(&sql_owned)
.map_err(SqlMiddlewareDbError::SqliteError)
}
})
.await
}
pub async fn execute_dml(
&mut self,
query: &str,
params: &[rusqlite::types::Value],
) -> Result<usize, SqlMiddlewareDbError> {
self.ensure_not_in_tx("execute dml")?;
let sql_owned = query.to_owned();
let params_owned = params.to_vec();
run_blocking(self.conn_handle(), move |guard| {
let mut stmt = guard
.prepare_cached(&sql_owned)
.map_err(SqlMiddlewareDbError::SqliteError)?;
let refs: Vec<&dyn rusqlite::ToSql> = params_owned
.iter()
.map(|v| v as &dyn rusqlite::ToSql)
.collect();
let affected = stmt
.execute(&refs[..])
.map_err(SqlMiddlewareDbError::SqliteError)?;
Ok(affected)
})
.await
}
pub async fn execute_dml_in_tx(
&mut self,
query: &str,
params: &[rusqlite::types::Value],
) -> Result<usize, SqlMiddlewareDbError> {
if !self.in_transaction {
return Err(SqlMiddlewareDbError::ExecutionError(
"SQLite transaction not active".into(),
));
}
let sql_owned = query.to_owned();
let params_owned = params.to_vec();
run_blocking(self.conn_handle(), move |guard| {
let mut stmt = guard
.prepare_cached(&sql_owned)
.map_err(SqlMiddlewareDbError::SqliteError)?;
let refs: Vec<&dyn rusqlite::ToSql> = params_owned
.iter()
.map(|v| v as &dyn rusqlite::ToSql)
.collect();
let affected = stmt
.execute(&refs[..])
.map_err(SqlMiddlewareDbError::SqliteError)?;
Ok(affected)
})
.await
}
pub async fn execute_batch_in_tx(&mut self, sql: &str) -> Result<(), SqlMiddlewareDbError> {
if !self.in_transaction {
return Err(SqlMiddlewareDbError::ExecutionError(
"SQLite transaction not active".into(),
));
}
let sql_owned = sql.to_owned();
run_blocking(self.conn_handle(), move |guard| {
guard
.execute_batch(&sql_owned)
.map_err(SqlMiddlewareDbError::SqliteError)
})
.await
}
}
pub async fn dml(
conn: &mut PooledConnection<'static, SqliteManager>,
query: &str,
params: &[RowValues],
) -> Result<usize, SqlMiddlewareDbError> {
let converted = convert_params::<Params>(params, ConversionMode::Execute)?.0;
let sql_owned = query.to_owned();
let params_owned = converted.clone();
let handle = Arc::clone(&*conn);
run_blocking(handle, move |guard| {
let mut stmt = guard
.prepare_cached(&sql_owned)
.map_err(SqlMiddlewareDbError::SqliteError)?;
let refs: Vec<&dyn rusqlite::ToSql> = params_owned
.iter()
.map(|v| v as &dyn rusqlite::ToSql)
.collect();
let affected = stmt
.execute(&refs[..])
.map_err(SqlMiddlewareDbError::SqliteError)?;
Ok(affected)
})
.await
}