nimiq_database/mdbx/transaction/
wrapper.rs1use std::ops::Deref;
2
3use libmdbx::{NoWriteMap, RO, RW};
4use nimiq_database_value::IntoDatabaseValue;
5
6use super::MdbxTransaction;
7use crate::{
8 mdbx::{CursorProxy, MdbxCursor},
9 traits::{DupTable, ReadTransaction, RegularTable, Table, WriteTransaction},
10};
11
12pub enum MdbxReadTransaction<'db> {
15 Read(MdbxTransaction<'db, RO>),
16 Write(MdbxTransaction<'db, RW>),
17}
18
19impl<'db> AsRef<MdbxReadTransaction<'db>> for MdbxReadTransaction<'db> {
20 fn as_ref(&self) -> &MdbxReadTransaction<'db> {
21 self
22 }
23}
24
25impl<'db> MdbxReadTransaction<'db> {
26 pub(crate) fn new_read(txn: libmdbx::Transaction<'db, RO, NoWriteMap>) -> Self {
27 MdbxReadTransaction::Read(MdbxTransaction::new(txn))
28 }
29}
30
31impl<'db> ReadTransaction<'db> for MdbxReadTransaction<'db> {
32 type Cursor<'txn, T: Table>
33 = CursorProxy<'txn, T>
34 where
35 Self: 'txn;
36
37 type DupCursor<'txn, T: DupTable>
38 = CursorProxy<'txn, T>
39 where
40 Self: 'txn;
41
42 fn get<T: Table>(&self, table: &T, key: &T::Key) -> Option<T::Value> {
43 match self {
44 MdbxReadTransaction::Read(txn) => txn.get(table, key),
45 MdbxReadTransaction::Write(txn) => txn.get(table, key),
46 }
47 }
48
49 fn cursor<'txn, T: RegularTable>(&'txn self, table: &T) -> Self::Cursor<'txn, T> {
50 match self {
51 MdbxReadTransaction::Read(txn) => CursorProxy::Read(txn.cursor(table)),
52 MdbxReadTransaction::Write(txn) => {
53 CursorProxy::Write(ReadTransaction::cursor(txn, table))
54 }
55 }
56 }
57
58 fn dup_cursor<'txn, T: DupTable>(&'txn self, table: &T) -> Self::DupCursor<'txn, T> {
59 match self {
60 MdbxReadTransaction::Read(txn) => CursorProxy::Read(txn.dup_cursor(table)),
61 MdbxReadTransaction::Write(txn) => {
62 CursorProxy::Write(ReadTransaction::dup_cursor(txn, table))
63 }
64 }
65 }
66}
67
68pub struct MdbxWriteTransaction<'db> {
69 txn: MdbxReadTransaction<'db>,
70}
71
72impl<'db> MdbxWriteTransaction<'db> {
73 pub(crate) fn new(txn: libmdbx::Transaction<'db, RW, NoWriteMap>) -> Self {
74 Self {
75 txn: MdbxReadTransaction::Write(MdbxTransaction::new(txn)),
76 }
77 }
78}
79
80impl<'db> ReadTransaction<'db> for MdbxWriteTransaction<'db> {
81 type Cursor<'txn, T: Table>
82 = CursorProxy<'txn, T>
83 where
84 Self: 'txn;
85
86 type DupCursor<'txn, T: DupTable>
87 = CursorProxy<'txn, T>
88 where
89 Self: 'txn;
90
91 fn get<T: Table>(&self, table: &T, key: &T::Key) -> Option<T::Value> {
92 self.txn.get(table, key)
93 }
94
95 fn cursor<'txn, T: RegularTable>(&'txn self, table: &T) -> Self::Cursor<'txn, T> {
96 self.txn.cursor(table)
97 }
98
99 fn dup_cursor<'txn, T: DupTable>(&'txn self, table: &T) -> Self::DupCursor<'txn, T> {
100 self.txn.dup_cursor(table)
101 }
102}
103
104impl<'db> WriteTransaction<'db> for MdbxWriteTransaction<'db> {
105 type WriteCursor<'txn, T: Table>
106 = MdbxCursor<'txn, RW, T>
107 where
108 Self: 'txn;
109
110 type DupWriteCursor<'txn, T: DupTable>
111 = MdbxCursor<'txn, RW, T>
112 where
113 Self: 'txn;
114
115 fn put_reserve<T: RegularTable>(&mut self, table: &T, key: &T::Key, value: &T::Value)
116 where
117 T::Value: IntoDatabaseValue,
118 {
119 match self.txn {
120 MdbxReadTransaction::Write(ref mut txn) => txn.put_reserve(table, key, value),
121 _ => unreachable!(),
122 }
123 }
124
125 fn put<T: Table>(&mut self, table: &T, key: &T::Key, value: &T::Value) {
126 match self.txn {
127 MdbxReadTransaction::Write(ref mut txn) => txn.put(table, key, value),
128 _ => unreachable!(),
129 }
130 }
131
132 fn append<T: Table>(&mut self, table: &T, key: &T::Key, value: &T::Value) {
133 match self.txn {
134 MdbxReadTransaction::Write(ref mut txn) => txn.append(table, key, value),
135 _ => unreachable!(),
136 }
137 }
138
139 fn remove<T: Table>(&mut self, table: &T, key: &T::Key) {
140 match self.txn {
141 MdbxReadTransaction::Write(ref mut txn) => txn.remove(table, key),
142 _ => unreachable!(),
143 }
144 }
145
146 fn remove_item<T: Table>(&mut self, table: &T, key: &T::Key, value: &T::Value) {
147 match self.txn {
148 MdbxReadTransaction::Write(ref mut txn) => txn.remove_item(table, key, value),
149 _ => unreachable!(),
150 }
151 }
152
153 fn commit(self) {
154 match self.txn {
155 MdbxReadTransaction::Write(txn) => txn.commit(),
156 _ => unreachable!(),
157 }
158 }
159
160 fn cursor<'txn, T: RegularTable>(&'txn self, table: &T) -> Self::WriteCursor<'txn, T> {
161 match self.txn {
162 MdbxReadTransaction::Write(ref txn) => WriteTransaction::cursor(txn, table),
163 _ => unreachable!(),
164 }
165 }
166
167 fn dup_cursor<'txn, T: DupTable>(&'txn self, table: &T) -> Self::DupWriteCursor<'txn, T> {
168 match self.txn {
169 MdbxReadTransaction::Write(ref txn) => WriteTransaction::dup_cursor(txn, table),
170 _ => unreachable!(),
171 }
172 }
173
174 fn clear_table<T: Table>(&mut self, table: &T) {
175 match self.txn {
176 MdbxReadTransaction::Write(ref mut txn) => txn.clear_table(table),
177 _ => unreachable!(),
178 }
179 }
180}
181
182impl<'db> Deref for MdbxWriteTransaction<'db> {
183 type Target = MdbxReadTransaction<'db>;
184
185 fn deref(&self) -> &Self::Target {
186 &self.txn
187 }
188}
189
190impl<'db> AsRef<MdbxReadTransaction<'db>> for MdbxWriteTransaction<'db> {
191 fn as_ref(&self) -> &MdbxReadTransaction<'db> {
192 &self.txn
193 }
194}