1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use either::Either;
use pollster::FutureExt;

use super::*;

/// ReadTransaction is a read-only transaction.
///
/// It is created by calling [`TransactionDB::read`].
pub struct ReadTransaction<D: AsyncDatabase, S: AsyncSpawner, H> {
  pub(super) db: TransactionDB<D, S, H>,
  pub(super) read_ts: u64,
}

impl<D, S, H> ReadTransaction<D, S, H>
where
  D: AsyncDatabase,
  S: AsyncSpawner,
{
  /// Looks for key and returns corresponding Item.
  pub async fn get<'a: 'b, 'b>(
    &'a self,
    key: &'b D::Key,
  ) -> Result<Option<Either<D::ItemRef<'a>, D::Item>>, D::Error> {
    self.db.inner.db.get(key, self.read_ts).await
  }

  /// Returns an iterator.
  pub async fn iter(&self, opts: IteratorOptions) -> D::Iterator<'_> {
    self
      .db
      .inner
      .db
      .iter(core::iter::empty(), self.read_ts, opts)
      .await
  }

  /// Returns an iterator over keys.
  pub async fn keys(&self, opts: KeysOptions) -> D::Keys<'_> {
    self
      .db
      .inner
      .db
      .keys(core::iter::empty(), self.read_ts, opts)
      .await
  }
}

impl<D, S, H> Drop for ReadTransaction<D, S, H>
where
  D: AsyncDatabase,
  S: AsyncSpawner,
{
  fn drop(&mut self) {
    self.db.inner.orc.done_read(self.read_ts).block_on();
  }
}