use crate::async_connection::AsyncConnection;
use crate::async_result::AsyncRowset;
use crate::error::Result;
use crate::result::{Row, RowValue};
#[derive(Debug)]
pub struct AsyncTransaction<'conn> {
connection: &'conn mut AsyncConnection,
completed: bool,
}
impl<'conn> AsyncTransaction<'conn> {
pub(crate) async fn new(connection: &'conn mut AsyncConnection) -> Result<Self> {
connection.begin_transaction().await?;
Ok(Self {
connection,
completed: false,
})
}
pub async fn commit(mut self) -> Result<()> {
self.completed = true;
self.connection.commit().await
}
pub async fn rollback(mut self) -> Result<()> {
self.completed = true;
self.connection.rollback().await
}
#[must_use]
pub fn connection(&self) -> &AsyncConnection {
self.connection
}
pub async fn execute_command(&self, sql: &str) -> Result<u64> {
self.connection.execute_command(sql).await
}
pub async fn execute_query(&self, query: &str) -> Result<AsyncRowset<'_>> {
self.connection.execute_query(query).await
}
pub async fn fetch_one<Q: AsRef<str>>(&self, query: Q) -> Result<Row> {
self.connection.fetch_one(query).await
}
pub async fn fetch_optional<Q: AsRef<str>>(&self, query: Q) -> Result<Option<Row>> {
self.connection.fetch_optional(query).await
}
pub async fn fetch_all<Q: AsRef<str>>(&self, query: Q) -> Result<Vec<Row>> {
self.connection.fetch_all(query).await
}
pub async fn fetch_scalar<T, Q>(&self, query: Q) -> Result<T>
where
T: RowValue,
Q: AsRef<str>,
{
self.connection.fetch_scalar(query).await
}
pub async fn fetch_optional_scalar<T, Q>(&self, query: Q) -> Result<Option<T>>
where
T: RowValue,
Q: AsRef<str>,
{
self.connection.fetch_optional_scalar(query).await
}
pub async fn query_count(&self, query: &str) -> Result<i64> {
self.connection.query_count(query).await
}
pub async fn query_params(
&self,
query: &str,
params: &[&dyn crate::params::ToSqlParam],
) -> Result<AsyncRowset<'_>> {
self.connection.query_params(query, params).await
}
pub async fn command_params(
&self,
query: &str,
params: &[&dyn crate::params::ToSqlParam],
) -> Result<u64> {
self.connection.command_params(query, params).await
}
}
impl Drop for AsyncTransaction<'_> {
fn drop(&mut self) {
if !self.completed {
tracing::warn!(
"AsyncTransaction dropped without explicit commit/rollback — \
transaction state is undefined until the next command on this connection"
);
}
}
}