use std::fmt;
use std::fmt::Debug;
use std::ops::Range;
use super::api::{
GetMultiResult, KeysResult, ScanCursorKeys, ScanCursorVals, ScanResult, Transactable,
};
use super::batch::Batch;
use super::direction::Direction;
use super::{IntoBytes, Key, Result, Val};
use crate::kvs::timestamp::{BoxTimeStamp, BoxTimeStampImpl};
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum TransactionType {
Read,
Write,
}
#[derive(Copy, Clone)]
pub enum LockType {
Pessimistic,
Optimistic,
}
impl From<bool> for LockType {
fn from(value: bool) -> Self {
match value {
true => LockType::Pessimistic,
false => LockType::Optimistic,
}
}
}
pub struct Transactor {
pub(super) inner: Box<dyn Transactable>,
}
impl fmt::Display for Transactor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.kind())
}
}
impl Drop for Transactor {
fn drop(&mut self) {
if !self.closed() && self.writeable() {
#[cfg(test)]
warn!("A transaction was dropped without being committed or cancelled");
#[cfg(not(test))]
error!("A transaction was dropped without being committed or cancelled");
}
}
}
impl Transactor {
pub(super) fn kind(&self) -> &'static str {
self.inner.kind()
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub fn closed(&self) -> bool {
self.inner.closed()
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub fn writeable(&self) -> bool {
self.inner.writeable()
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn cancel(&self) -> Result<()> {
self.inner.cancel().await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn commit(&self) -> Result<()> {
self.inner.commit().await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn exists<K>(&self, key: K, version: Option<u64>) -> Result<bool>
where
K: IntoBytes + Debug,
{
let key = key.into_vec();
self.inner.exists(key, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn get<K>(&self, key: K, version: Option<u64>) -> Result<Option<Val>>
where
K: IntoBytes + Debug,
{
let key = key.into_vec();
self.inner.get(key, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn getm<K>(&self, keys: Vec<K>, version: Option<u64>) -> Result<GetMultiResult>
where
K: IntoBytes + Debug,
{
let keys = keys.into_iter().map(IntoBytes::into_vec).collect();
self.inner.getm(keys, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn getp<K>(&self, key: K, version: Option<u64>) -> Result<ScanResult>
where
K: IntoBytes + Debug,
{
let key = key.into_vec();
self.inner.getp(key, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn getr<K>(&self, rng: Range<K>, version: Option<u64>) -> Result<ScanResult>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.getr(beg..end, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn set<K, V>(&self, key: K, val: V) -> Result<()>
where
K: IntoBytes + Debug,
V: IntoBytes + Debug,
{
let key = key.into_vec();
let val = val.into_vec();
self.inner.set(key, val).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn replace<K, V>(&self, key: K, val: V) -> Result<()>
where
K: IntoBytes + Debug,
V: IntoBytes + Debug,
{
let key = key.into_vec();
let val = val.into_vec();
self.inner.replace(key, val).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn put<K, V>(&self, key: K, val: V) -> Result<()>
where
K: IntoBytes + Debug,
V: IntoBytes + Debug,
{
let key = key.into_vec();
let val = val.into_vec();
self.inner.put(key, val).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn putc<K, V>(&self, key: K, val: V, chk: Option<V>) -> Result<()>
where
K: IntoBytes + Debug,
V: IntoBytes + Debug,
{
let key = key.into_vec();
let val = val.into_vec();
let chk = chk.map(|v| v.into_vec());
self.inner.putc(key, val, chk).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn del<K>(&self, key: K) -> Result<()>
where
K: IntoBytes + Debug,
{
let key = key.into_vec();
self.inner.del(key).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn delc<K, V>(&self, key: K, chk: Option<V>) -> Result<()>
where
K: IntoBytes + Debug,
V: IntoBytes + Debug,
{
let key = key.into_vec();
let chk = chk.map(|v| v.into_vec());
self.inner.delc(key, chk).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn delp<K>(&self, key: K) -> Result<()>
where
K: IntoBytes + Debug,
{
let key = key.into_vec();
self.inner.delp(key).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn delr<K>(&self, rng: Range<K>) -> Result<()>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.delr(beg..end).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn clr<K>(&self, key: K) -> Result<()>
where
K: IntoBytes + Debug,
{
let key = key.into_vec();
self.inner.clr(key).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn clrc<K, V>(&self, key: K, chk: Option<V>) -> Result<()>
where
K: IntoBytes + Debug,
V: IntoBytes + Debug,
{
let key = key.into_vec();
let chk = chk.map(|v| v.into_vec());
self.inner.clrc(key, chk).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn clrp<K>(&self, key: K) -> Result<()>
where
K: IntoBytes + Debug,
{
let key = key.into_vec();
self.inner.clrp(key).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn clrr<K>(&self, rng: Range<K>) -> Result<()>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.clrr(beg..end).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn keys<K>(
&self,
rng: Range<K>,
limit: u32,
skip: u32,
version: Option<u64>,
) -> Result<KeysResult>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
if beg > end {
return Ok(KeysResult::default());
}
self.inner.keys(beg..end, limit, skip, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn keysr<K>(
&self,
rng: Range<K>,
limit: u32,
skip: u32,
version: Option<u64>,
) -> Result<KeysResult>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
if beg > end {
return Ok(KeysResult::default());
}
self.inner.keysr(beg..end, limit, skip, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn scan<K>(
&self,
rng: Range<K>,
limit: u32,
skip: u32,
version: Option<u64>,
) -> Result<ScanResult>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
if beg > end {
return Ok(ScanResult::default());
}
self.inner.scan(beg..end, limit, skip, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn scanr<K>(
&self,
rng: Range<K>,
limit: u32,
skip: u32,
version: Option<u64>,
) -> Result<ScanResult>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
if beg > end {
return Ok(ScanResult::default());
}
self.inner.scanr(beg..end, limit, skip, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn count<K>(&self, rng: Range<K>, version: Option<u64>) -> Result<usize>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.count(beg..end, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn open_keys_cursor<'a, K>(
&'a self,
rng: Range<K>,
dir: Direction,
skip: u32,
version: Option<u64>,
) -> Result<Box<dyn ScanCursorKeys + 'a>>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.open_keys_cursor(beg..end, dir, skip, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn open_vals_cursor<'a, K>(
&'a self,
rng: Range<K>,
dir: Direction,
skip: u32,
version: Option<u64>,
) -> Result<Box<dyn ScanCursorVals + 'a>>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.open_vals_cursor(beg..end, dir, skip, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn batch_keys<K>(
&self,
rng: Range<K>,
batch: u32,
version: Option<u64>,
) -> Result<Batch<Key>>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.batch_keys(beg..end, batch, version).await
}
#[instrument(level = "trace", target = "surrealdb::core::kvs::tr", skip_all)]
pub async fn batch_keys_vals<K>(
&self,
rng: Range<K>,
batch: u32,
version: Option<u64>,
) -> Result<Batch<(Key, Val)>>
where
K: IntoBytes + Debug,
{
let beg = rng.start.into_vec();
let end = rng.end.into_vec();
self.inner.batch_keys_vals(beg..end, batch, version).await
}
pub async fn new_save_point(&self) -> Result<()> {
self.inner.new_save_point().await
}
pub async fn release_last_save_point(&self) -> Result<()> {
self.inner.release_last_save_point().await
}
pub async fn rollback_to_save_point(&self) -> Result<()> {
self.inner.rollback_to_save_point().await
}
pub async fn timestamp(&self) -> Result<BoxTimeStamp> {
self.inner.timestamp().await
}
pub async fn safe_timestamp(&self) -> Result<BoxTimeStamp> {
self.inner.safe_timestamp().await
}
pub fn timestamp_impl(&self) -> BoxTimeStampImpl {
self.inner.timestamp_impl()
}
}