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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
mod coop_transaction;
use crate::api::places_api::ConnectionType;
use crate::error::*;
use coop_transaction::ChunkedCoopTransaction;
use rusqlite::Connection;
use sql_support::{ConnExt, UncheckedTransaction};
macro_rules! debug_complaint {
($($fmt_args:tt)*) => {
log::error!($($fmt_args)*);
if cfg!(debug_assertions) {
panic!($($fmt_args)*);
}
};
}
pub struct PlacesTransaction<'conn>(PlacesTransactionRepr<'conn>);
enum PlacesTransactionRepr<'conn> {
ChunkedWrite(ChunkedCoopTransaction<'conn>),
UnchunkedWrite(UncheckedTransaction<'conn>),
ReadOnly(UncheckedTransaction<'conn>),
}
impl<'conn> PlacesTransaction<'conn> {
#[inline]
pub fn should_commit(&self) -> bool {
match &self.0 {
PlacesTransactionRepr::ChunkedWrite(tx) => tx.should_commit(),
_ => true,
}
}
#[inline]
pub fn maybe_commit(&mut self) -> Result<()> {
if let PlacesTransactionRepr::ChunkedWrite(tx) = &mut self.0 {
tx.maybe_commit()?;
} else {
debug_complaint!("maybe_commit called on a non-chunked transaction");
}
Ok(())
}
pub fn commit(self) -> Result<()> {
match self.0 {
PlacesTransactionRepr::ChunkedWrite(t) => t.commit()?,
PlacesTransactionRepr::UnchunkedWrite(t) => t.commit()?,
PlacesTransactionRepr::ReadOnly(t) => t.commit()?,
};
Ok(())
}
pub fn rollback(self) -> Result<()> {
match self.0 {
PlacesTransactionRepr::ChunkedWrite(t) => t.rollback()?,
PlacesTransactionRepr::UnchunkedWrite(t) => t.rollback()?,
PlacesTransactionRepr::ReadOnly(t) => t.rollback()?,
};
Ok(())
}
}
impl super::PlacesDb {
pub fn begin_transaction(&self) -> Result<PlacesTransaction<'_>> {
Ok(PlacesTransaction(match self.conn_type() {
ConnectionType::Sync => {
PlacesTransactionRepr::ChunkedWrite(self.chunked_coop_trransaction()?)
}
ConnectionType::ReadWrite => {
PlacesTransactionRepr::UnchunkedWrite(self.coop_transaction()?)
}
ConnectionType::ReadOnly => {
PlacesTransactionRepr::ReadOnly(self.unchecked_transaction()?)
}
}))
}
}
impl<'conn> std::ops::Deref for PlacesTransaction<'conn> {
type Target = Connection;
fn deref(&self) -> &Connection {
match &self.0 {
PlacesTransactionRepr::ChunkedWrite(t) => &t,
PlacesTransactionRepr::UnchunkedWrite(t) => &t,
PlacesTransactionRepr::ReadOnly(t) => &t,
}
}
}
impl<'conn> ConnExt for PlacesTransaction<'conn> {
#[inline]
fn conn(&self) -> &Connection {
&*self
}
}