idb_sys/transaction/
mod.rs1mod transaction_mode;
2
3pub use self::transaction_mode::TransactionMode;
4
5use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
6use web_sys::{DomException, Event, EventTarget, IdbTransaction};
7
8use crate::{utils::dom_string_list_to_vec, Database, Error, ObjectStore};
9
10#[derive(Debug)]
13pub struct Transaction {
14 inner: IdbTransaction,
15 abort_callback: Option<Closure<dyn FnMut(Event)>>,
16 complete_callback: Option<Closure<dyn FnMut(Event)>>,
17 error_callback: Option<Closure<dyn FnMut(Event)>>,
18}
19
20impl Transaction {
21 pub fn store_names(&self) -> Vec<String> {
24 dom_string_list_to_vec(&self.inner.object_store_names())
25 }
26
27 pub fn mode(&self) -> Result<TransactionMode, Error> {
30 self.inner
31 .mode()
32 .map_err(Error::TransactionModeNotFound)?
33 .try_into()
34 }
35
36 pub fn database(&self) -> Database {
38 self.inner.db().into()
39 }
40
41 pub fn error(&self) -> Option<DomException> {
43 self.inner.error()
44 }
45
46 pub fn object_store(&self, name: &str) -> Result<ObjectStore, Error> {
48 self.inner
49 .object_store(name)
50 .map(Into::into)
51 .map_err(Error::ObjectStoreNotFound)
52 }
53
54 pub fn commit(&self) -> Result<(), Error> {
58 self.inner.commit().map_err(Error::TransactionCommitError)
59 }
60
61 pub fn abort(&self) -> Result<(), Error> {
63 self.inner.abort().map_err(Error::TransactionAbortError)
64 }
65
66 pub fn on_abort<F>(&mut self, callback: F)
68 where
69 F: FnOnce(Event) + 'static,
70 {
71 let closure = Closure::once(callback);
72 self.inner
73 .set_onabort(Some(closure.as_ref().unchecked_ref()));
74 self.abort_callback = Some(closure);
75 }
76
77 pub fn on_complete<F>(&mut self, callback: F)
79 where
80 F: FnOnce(Event) + 'static,
81 {
82 let closure = Closure::once(callback);
83 self.inner
84 .set_oncomplete(Some(closure.as_ref().unchecked_ref()));
85 self.complete_callback = Some(closure);
86 }
87
88 pub fn on_error<F>(&mut self, callback: F)
90 where
91 F: FnOnce(Event) + 'static,
92 {
93 let closure = Closure::once(callback);
94 self.inner
95 .set_onerror(Some(closure.as_ref().unchecked_ref()));
96 self.error_callback = Some(closure);
97 }
98}
99
100impl TryFrom<EventTarget> for Transaction {
101 type Error = Error;
102
103 fn try_from(target: EventTarget) -> Result<Self, Self::Error> {
104 let target: JsValue = target.into();
105 target
106 .dyn_into::<IdbTransaction>()
107 .map(Into::into)
108 .map_err(|value| Error::UnexpectedJsType("IdbTransaction", value))
109 }
110}
111
112impl From<IdbTransaction> for Transaction {
113 fn from(inner: IdbTransaction) -> Self {
114 Self {
115 inner,
116 abort_callback: None,
117 complete_callback: None,
118 error_callback: None,
119 }
120 }
121}
122
123impl From<Transaction> for IdbTransaction {
124 fn from(transaction: Transaction) -> Self {
125 transaction.inner
126 }
127}
128
129impl TryFrom<JsValue> for Transaction {
130 type Error = Error;
131
132 fn try_from(value: JsValue) -> Result<Self, Self::Error> {
133 value
134 .dyn_into::<IdbTransaction>()
135 .map(Into::into)
136 .map_err(|value| Error::UnexpectedJsType("IdbTransaction", value))
137 }
138}
139
140impl From<Transaction> for JsValue {
141 fn from(value: Transaction) -> Self {
142 value.inner.into()
143 }
144}