1use crate::db::cf_handle;
3use crate::{Result, internal_error};
4use ckb_db_schema::Col;
5use rocksdb::ops::{DeleteCF, GetPinnedCF, PutCF};
6pub use rocksdb::{DBPinnableSlice, DBVector};
7use rocksdb::{
8 OptimisticTransaction, OptimisticTransactionDB, OptimisticTransactionSnapshot, ReadOptions,
9};
10use std::sync::Arc;
11
12pub struct RocksDBTransaction {
14 pub(crate) db: Arc<OptimisticTransactionDB>,
15 pub(crate) inner: OptimisticTransaction,
16}
17
18impl RocksDBTransaction {
19 pub fn get_pinned(&self, col: Col, key: &[u8]) -> Result<Option<DBPinnableSlice>> {
21 let cf = cf_handle(&self.db, col)?;
22 self.inner.get_pinned_cf(cf, key).map_err(internal_error)
23 }
24
25 pub fn put(&self, col: Col, key: &[u8], value: &[u8]) -> Result<()> {
27 let cf = cf_handle(&self.db, col)?;
28 self.inner.put_cf(cf, key, value).map_err(internal_error)
29 }
30
31 pub fn delete(&self, col: Col, key: &[u8]) -> Result<()> {
33 let cf = cf_handle(&self.db, col)?;
34 self.inner.delete_cf(cf, key).map_err(internal_error)
35 }
36
37 pub fn get_for_update(
39 &self,
40 col: Col,
41 key: &[u8],
42 snapshot: &RocksDBTransactionSnapshot<'_>,
43 ) -> Result<Option<DBVector>> {
44 let cf = cf_handle(&self.db, col)?;
45 let mut opts = ReadOptions::default();
46 opts.set_snapshot(&snapshot.inner);
47 self.inner
48 .get_for_update_cf_opt(cf, key, &opts, true)
49 .map_err(internal_error)
50 }
51
52 pub fn commit(&self) -> Result<()> {
54 self.inner.commit().map_err(internal_error)
55 }
56
57 pub fn rollback(&self) -> Result<()> {
59 self.inner.rollback().map_err(internal_error)
60 }
61
62 pub fn get_snapshot(&self) -> RocksDBTransactionSnapshot<'_> {
64 RocksDBTransactionSnapshot {
65 db: Arc::clone(&self.db),
66 inner: self.inner.snapshot(),
67 }
68 }
69
70 pub fn set_savepoint(&self) {
72 self.inner.set_savepoint()
73 }
74
75 pub fn rollback_to_savepoint(&self) -> Result<()> {
77 self.inner.rollback_to_savepoint().map_err(internal_error)
78 }
79}
80
81pub struct RocksDBTransactionSnapshot<'a> {
83 pub(crate) db: Arc<OptimisticTransactionDB>,
84 pub(crate) inner: OptimisticTransactionSnapshot<'a>,
85}
86
87impl<'a> RocksDBTransactionSnapshot<'a> {
88 pub fn get_pinned(&self, col: Col, key: &[u8]) -> Result<Option<DBPinnableSlice>> {
90 let cf = cf_handle(&self.db, col)?;
91 self.inner.get_pinned_cf(cf, key).map_err(internal_error)
92 }
93}