use std::sync::Arc;
use tokio::sync::Mutex;
use crate::middleware::{ResultSet, RowValues, SqlMiddlewareDbError};
use super::{config::MssqlClient, query::build_result_set};
#[derive(Clone)]
pub struct MssqlNonTxPreparedStatement {
client: Arc<Mutex<MssqlClient>>,
sql: Arc<String>,
}
impl std::fmt::Debug for MssqlNonTxPreparedStatement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MssqlNonTxPreparedStatement")
.field("client", &"<MssqlClient>")
.field("sql", &self.sql)
.finish()
}
}
impl MssqlNonTxPreparedStatement {
pub fn prepare(client: MssqlClient, sql: &str) -> Self {
Self {
client: Arc::new(Mutex::new(client)),
sql: Arc::new(sql.to_owned()),
}
}
pub async fn query(&self, params: &[RowValues]) -> Result<ResultSet, SqlMiddlewareDbError> {
let mut client = self.client.lock().await;
build_result_set(&mut client, &self.sql, params).await
}
pub async fn execute(&self, params: &[RowValues]) -> Result<usize, SqlMiddlewareDbError> {
let mut client = self.client.lock().await;
let query_builder = super::query::bind_query_params(&self.sql, params);
let exec_result = query_builder.execute(&mut *client).await.map_err(|e| {
SqlMiddlewareDbError::ExecutionError(format!("MSSQL prepared execute error: {e}"))
})?;
let rows_affected: u64 = exec_result.rows_affected().iter().sum();
usize::try_from(rows_affected).map_err(|e| {
SqlMiddlewareDbError::ExecutionError(format!("Invalid rows affected count: {e}"))
})
}
#[must_use]
pub fn sql(&self) -> &str {
self.sql.as_str()
}
}