use crate::{Dialect, RelError, Row, Value};
use std::future::Future;
use std::pin::Pin;
use std::time::Duration;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Isolation {
#[default]
ReadCommitted,
RepeatableRead,
Serializable,
}
pub trait RelationalBackend: Send + Sync {
type Tx<'a>: RelationalTx + 'a
where
Self: 'a;
fn backend(&self) -> &str;
fn version(&self) -> &str;
fn dialect(&self) -> Dialect;
fn execute(
&self,
sql: &str,
params: &[Value],
) -> impl Future<Output = Result<u64, RelError>> + Send;
fn query(
&self,
sql: &str,
params: &[Value],
) -> impl Future<Output = Result<Vec<Row>, RelError>> + Send;
fn begin(
&self,
isolation: Isolation,
) -> impl Future<Output = Result<Self::Tx<'_>, RelError>> + Send;
fn call_bound(&self) -> Option<Duration> {
None
}
fn with_lock_held<'a>(
&'a self,
lock_sql: &'a str,
at_most: Duration,
during: Pin<Box<dyn Future<Output = ()> + Send + 'a>>,
) -> impl Future<Output = Result<(), RelError>> + Send {
let _ = (lock_sql, at_most, during);
async { Err(RelError::Unsupported("with_lock_held".to_string())) }
}
}
pub trait RelationalTx: Send {
fn execute(
&mut self,
sql: &str,
params: &[Value],
) -> impl Future<Output = Result<u64, RelError>> + Send;
fn query(
&mut self,
sql: &str,
params: &[Value],
) -> impl Future<Output = Result<Vec<Row>, RelError>> + Send;
fn commit(self) -> impl Future<Output = Result<(), RelError>> + Send;
fn rollback(self) -> impl Future<Output = Result<(), RelError>> + Send;
}