use super::backend::{
AnswerConsumer, BoundedAnswerLimits, BoundedAnswerStats, GivenRowsSpec, QueryResult,
TransactionOps, TxType,
};
use crate::error::{OrmError, Result};
use type_bridge_core_lib::ast::{
TypedFetchRows, TypedHydrateThings, TypedPageRematch, TypedRootScan,
};
pub struct Transaction {
inner: Option<Box<dyn TransactionOps>>,
tx_type: TxType,
}
impl Transaction {
pub(crate) fn new(inner: Box<dyn TransactionOps>, tx_type: TxType) -> Self {
Self {
inner: Some(inner),
tx_type,
}
}
pub async fn query(&mut self, typeql: &str) -> Result<QueryResult> {
let tx = self
.inner
.as_mut()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.query(typeql).await
}
pub async fn query_with_rows(
&mut self,
typeql: &str,
rows: GivenRowsSpec,
) -> Result<QueryResult> {
let tx = self
.inner
.as_mut()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.query_with_rows(typeql, rows).await
}
pub(crate) async fn query_typed_bounded(
&mut self,
query: &TypedFetchRows,
limits: BoundedAnswerLimits,
consumer: &mut dyn AnswerConsumer,
) -> Result<BoundedAnswerStats> {
let tx = self
.inner
.as_mut()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.query_typed_bounded(query, limits, consumer).await
}
pub(crate) async fn hydrate_typed_bounded(
&mut self,
query: &TypedHydrateThings,
limits: BoundedAnswerLimits,
consumer: &mut dyn AnswerConsumer,
) -> Result<BoundedAnswerStats> {
let tx = self
.inner
.as_mut()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.hydrate_typed_bounded(query, limits, consumer).await
}
pub(crate) async fn query_root_typed_bounded(
&mut self,
query: &TypedRootScan,
limits: BoundedAnswerLimits,
consumer: &mut dyn AnswerConsumer,
) -> Result<BoundedAnswerStats> {
let tx = self
.inner
.as_mut()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.query_root_typed_bounded(query, limits, consumer).await
}
pub(crate) async fn rematch_page_typed_bounded(
&mut self,
query: &TypedPageRematch,
limits: BoundedAnswerLimits,
consumer: &mut dyn AnswerConsumer,
) -> Result<BoundedAnswerStats> {
let tx = self
.inner
.as_mut()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.rematch_page_typed_bounded(query, limits, consumer).await
}
pub async fn commit(&mut self) -> Result<()> {
let mut tx = self
.inner
.take()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.commit().await
}
pub async fn rollback(&mut self) -> Result<()> {
let mut tx = self
.inner
.take()
.ok_or_else(|| OrmError::Transaction("Transaction already consumed".into()))?;
tx.rollback().await
}
pub async fn close(&mut self) -> Result<()> {
let Some(mut tx) = self.inner.take() else {
return Ok(());
};
tx.close().await
}
pub fn tx_type(&self) -> TxType {
self.tx_type
}
}