use crate::dql::QueryResult;
use_prelude!();
impl Store {
pub async fn transaction<T, E>(
&self,
scope: impl AsyncFnOnce(&Transaction) -> Result<T, E>,
) -> Result<T, E>
where
T: core::any::Any,
E: From<DittoError>,
{
let options = CreateTransactionOptions::default();
self.transaction_with_options(options, scope).await
}
pub async fn transaction_with_options<T, E>(
&self,
options: CreateTransactionOptions<'_>,
scope: impl AsyncFnOnce(&Transaction) -> Result<T, E>,
) -> Result<T, E>
where
T: core::any::Any,
E: From<DittoError>,
{
let hint = options.hint.map(char_p::new);
let options = ffi_sdk::BeginTransactionOptions {
hint: hint.as_ref().map(|s| s.as_ref()),
is_read_only: options.is_read_only,
};
self._transaction_with_options(options, scope).await
}
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub struct CreateTransactionOptions<'hint> {
pub hint: Option<&'hint str>,
pub is_read_only: bool,
}
#[allow(
clippy::derivable_impls,
reason = "writing it out makes it clearer what the defaults are"
)]
impl Default for CreateTransactionOptions<'_> {
fn default() -> Self {
Self {
hint: None,
is_read_only: false,
}
}
}
impl CreateTransactionOptions<'_> {
pub fn new() -> Self {
Self::default()
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub struct TransactionInfo {
pub id: String,
pub hint: Option<String>,
pub is_read_only: bool,
}
#[derive(Debug, Clone, PartialEq)]
#[must_use = "Code should handle whether a transaction succeeded"]
pub enum TransactionCompletionAction {
Commit,
Rollback,
}
pub struct Transaction {
pub(crate) ptr: repr_c::Box<ffi_sdk::FfiTransaction>,
}
impl Transaction {
pub fn info(&self) -> TransactionInfo {
self._info()
}
pub async fn execute<Q>(&self, query: Q) -> Result<QueryResult, DittoError>
where
Q: IntoQuery,
Q::Args: serde::Serialize,
{
self._execute(query).await
}
}