@@ -9,7 +9,15 @@ use tokio_postgres::{Error, Row, SimpleQueryMessage};
9
9
/// in the transaction. Transactions can be nested, with inner transactions implemented via savepoints.
10
10
pub struct Transaction < ' a > {
11
11
connection : ConnectionRef < ' a > ,
12
- transaction : tokio_postgres:: Transaction < ' a > ,
12
+ transaction : Option < tokio_postgres:: Transaction < ' a > > ,
13
+ }
14
+
15
+ impl < ' a > Drop for Transaction < ' a > {
16
+ fn drop ( & mut self ) {
17
+ if let Some ( transaction) = self . transaction . take ( ) {
18
+ let _ = self . connection . block_on ( transaction. rollback ( ) ) ;
19
+ }
20
+ }
13
21
}
14
22
15
23
impl < ' a > Transaction < ' a > {
@@ -19,31 +27,38 @@ impl<'a> Transaction<'a> {
19
27
) -> Transaction < ' a > {
20
28
Transaction {
21
29
connection,
22
- transaction,
30
+ transaction : Some ( transaction ) ,
23
31
}
24
32
}
25
33
26
34
/// Consumes the transaction, committing all changes made within it.
27
35
pub fn commit ( mut self ) -> Result < ( ) , Error > {
28
- self . connection . block_on ( self . transaction . commit ( ) )
36
+ self . connection
37
+ . block_on ( self . transaction . take ( ) . unwrap ( ) . commit ( ) )
29
38
}
30
39
31
40
/// Rolls the transaction back, discarding all changes made within it.
32
41
///
33
42
/// This is equivalent to `Transaction`'s `Drop` implementation, but provides any error encountered to the caller.
34
43
pub fn rollback ( mut self ) -> Result < ( ) , Error > {
35
- self . connection . block_on ( self . transaction . rollback ( ) )
44
+ self . connection
45
+ . block_on ( self . transaction . take ( ) . unwrap ( ) . rollback ( ) )
36
46
}
37
47
38
48
/// Like `Client::prepare`.
39
49
pub fn prepare ( & mut self , query : & str ) -> Result < Statement , Error > {
40
- self . connection . block_on ( self . transaction . prepare ( query) )
50
+ self . connection
51
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . prepare ( query) )
41
52
}
42
53
43
54
/// Like `Client::prepare_typed`.
44
55
pub fn prepare_typed ( & mut self , query : & str , types : & [ Type ] ) -> Result < Statement , Error > {
45
- self . connection
46
- . block_on ( self . transaction . prepare_typed ( query, types) )
56
+ self . connection . block_on (
57
+ self . transaction
58
+ . as_ref ( )
59
+ . unwrap ( )
60
+ . prepare_typed ( query, types) ,
61
+ )
47
62
}
48
63
49
64
/// Like `Client::execute`.
@@ -52,7 +67,7 @@ impl<'a> Transaction<'a> {
52
67
T : ?Sized + ToStatement ,
53
68
{
54
69
self . connection
55
- . block_on ( self . transaction . execute ( query, params) )
70
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . execute ( query, params) )
56
71
}
57
72
58
73
/// Like `Client::query`.
@@ -61,7 +76,7 @@ impl<'a> Transaction<'a> {
61
76
T : ?Sized + ToStatement ,
62
77
{
63
78
self . connection
64
- . block_on ( self . transaction . query ( query, params) )
79
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . query ( query, params) )
65
80
}
66
81
67
82
/// Like `Client::query_one`.
@@ -70,7 +85,7 @@ impl<'a> Transaction<'a> {
70
85
T : ?Sized + ToStatement ,
71
86
{
72
87
self . connection
73
- . block_on ( self . transaction . query_one ( query, params) )
88
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . query_one ( query, params) )
74
89
}
75
90
76
91
/// Like `Client::query_opt`.
@@ -83,7 +98,7 @@ impl<'a> Transaction<'a> {
83
98
T : ?Sized + ToStatement ,
84
99
{
85
100
self . connection
86
- . block_on ( self . transaction . query_opt ( query, params) )
101
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . query_opt ( query, params) )
87
102
}
88
103
89
104
/// Like `Client::query_raw`.
@@ -95,7 +110,7 @@ impl<'a> Transaction<'a> {
95
110
{
96
111
let stream = self
97
112
. connection
98
- . block_on ( self . transaction . query_raw ( query, params) ) ?;
113
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . query_raw ( query, params) ) ?;
99
114
Ok ( RowIter :: new ( self . connection . as_ref ( ) , stream) )
100
115
}
101
116
@@ -114,16 +129,20 @@ impl<'a> Transaction<'a> {
114
129
T : ?Sized + ToStatement ,
115
130
{
116
131
self . connection
117
- . block_on ( self . transaction . bind ( query, params) )
132
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . bind ( query, params) )
118
133
}
119
134
120
135
/// Continues execution of a portal, returning the next set of rows.
121
136
///
122
137
/// Unlike `query`, portals can be incrementally evaluated by limiting the number of rows returned in each call to
123
138
/// `query_portal`. If the requested number is negative or 0, all remaining rows will be returned.
124
139
pub fn query_portal ( & mut self , portal : & Portal , max_rows : i32 ) -> Result < Vec < Row > , Error > {
125
- self . connection
126
- . block_on ( self . transaction . query_portal ( portal, max_rows) )
140
+ self . connection . block_on (
141
+ self . transaction
142
+ . as_ref ( )
143
+ . unwrap ( )
144
+ . query_portal ( portal, max_rows) ,
145
+ )
127
146
}
128
147
129
148
/// The maximally flexible version of `query_portal`.
@@ -132,9 +151,12 @@ impl<'a> Transaction<'a> {
132
151
portal : & Portal ,
133
152
max_rows : i32 ,
134
153
) -> Result < RowIter < ' _ > , Error > {
135
- let stream = self
136
- . connection
137
- . block_on ( self . transaction . query_portal_raw ( portal, max_rows) ) ?;
154
+ let stream = self . connection . block_on (
155
+ self . transaction
156
+ . as_ref ( )
157
+ . unwrap ( )
158
+ . query_portal_raw ( portal, max_rows) ,
159
+ ) ?;
138
160
Ok ( RowIter :: new ( self . connection . as_ref ( ) , stream) )
139
161
}
140
162
@@ -143,7 +165,9 @@ impl<'a> Transaction<'a> {
143
165
where
144
166
T : ?Sized + ToStatement ,
145
167
{
146
- let sink = self . connection . block_on ( self . transaction . copy_in ( query) ) ?;
168
+ let sink = self
169
+ . connection
170
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . copy_in ( query) ) ?;
147
171
Ok ( CopyInWriter :: new ( self . connection . as_ref ( ) , sink) )
148
172
}
149
173
@@ -152,44 +176,45 @@ impl<'a> Transaction<'a> {
152
176
where
153
177
T : ?Sized + ToStatement ,
154
178
{
155
- let stream = self . connection . block_on ( self . transaction . copy_out ( query) ) ?;
179
+ let stream = self
180
+ . connection
181
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . copy_out ( query) ) ?;
156
182
Ok ( CopyOutReader :: new ( self . connection . as_ref ( ) , stream) )
157
183
}
158
184
159
185
/// Like `Client::simple_query`.
160
186
pub fn simple_query ( & mut self , query : & str ) -> Result < Vec < SimpleQueryMessage > , Error > {
161
187
self . connection
162
- . block_on ( self . transaction . simple_query ( query) )
188
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . simple_query ( query) )
163
189
}
164
190
165
191
/// Like `Client::batch_execute`.
166
192
pub fn batch_execute ( & mut self , query : & str ) -> Result < ( ) , Error > {
167
193
self . connection
168
- . block_on ( self . transaction . batch_execute ( query) )
194
+ . block_on ( self . transaction . as_ref ( ) . unwrap ( ) . batch_execute ( query) )
169
195
}
170
196
171
197
/// Like `Client::cancel_token`.
172
198
pub fn cancel_token ( & self ) -> CancelToken {
173
- CancelToken :: new ( self . transaction . cancel_token ( ) )
199
+ CancelToken :: new ( self . transaction . as_ref ( ) . unwrap ( ) . cancel_token ( ) )
174
200
}
175
201
176
202
/// Like `Client::transaction`, but creates a nested transaction via a savepoint.
177
203
pub fn transaction ( & mut self ) -> Result < Transaction < ' _ > , Error > {
178
- let transaction = self . connection . block_on ( self . transaction . transaction ( ) ) ?;
179
- Ok ( Transaction {
180
- connection : self . connection . as_ref ( ) ,
181
- transaction,
182
- } )
204
+ let transaction = self
205
+ . connection
206
+ . block_on ( self . transaction . as_mut ( ) . unwrap ( ) . transaction ( ) ) ?;
207
+ Ok ( Transaction :: new ( self . connection . as_ref ( ) , transaction) )
183
208
}
209
+
184
210
/// Like `Client::transaction`, but creates a nested transaction via a savepoint with the specified name.
185
211
pub fn savepoint < I > ( & mut self , name : I ) -> Result < Transaction < ' _ > , Error >
186
212
where
187
213
I : Into < String > ,
188
214
{
189
- let transaction = self . connection . block_on ( self . transaction . savepoint ( name) ) ?;
190
- Ok ( Transaction {
191
- connection : self . connection . as_ref ( ) ,
192
- transaction,
193
- } )
215
+ let transaction = self
216
+ . connection
217
+ . block_on ( self . transaction . as_mut ( ) . unwrap ( ) . savepoint ( name) ) ?;
218
+ Ok ( Transaction :: new ( self . connection . as_ref ( ) , transaction) )
194
219
}
195
220
}
0 commit comments