@@ -151,6 +151,7 @@ impl Config {
151
151
pub struct Transaction < ' conn > {
152
152
conn : & ' conn Connection ,
153
153
depth : u32 ,
154
+ savepoint_name : Option < & ' conn str > ,
154
155
commit : Cell < bool > ,
155
156
finished : bool ,
156
157
}
@@ -177,6 +178,7 @@ impl<'conn> TransactionInternals<'conn> for Transaction<'conn> {
177
178
Transaction {
178
179
conn : conn,
179
180
depth : depth,
181
+ savepoint_name : None ,
180
182
commit : Cell :: new ( false ) ,
181
183
finished : false ,
182
184
}
@@ -195,14 +197,13 @@ impl<'conn> Transaction<'conn> {
195
197
fn finish_inner ( & mut self ) -> Result < ( ) > {
196
198
let mut conn = self . conn . conn . borrow_mut ( ) ;
197
199
debug_assert ! ( self . depth == conn. trans_depth) ;
198
- let query = match ( self . commit . get ( ) , self . depth != 1 ) {
199
- ( false , true ) => "ROLLBACK TO sp" ,
200
- ( false , false ) => "ROLLBACK" ,
201
- ( true , true ) => "RELEASE sp" ,
202
- ( true , false ) => "COMMIT" ,
203
- } ;
204
200
conn. trans_depth -= 1 ;
205
- conn. quick_query ( query) . map ( |_| ( ) )
201
+ match ( self . commit . get ( ) , self . savepoint_name ) {
202
+ ( false , Some ( savepoint_name) ) => conn. quick_query ( & format ! ( "ROLLBACK TO {}" , savepoint_name) ) ,
203
+ ( false , None ) => conn. quick_query ( "ROLLBACK" ) ,
204
+ ( true , Some ( savepoint_name) ) => conn. quick_query ( & format ! ( "RELEASE {}" , savepoint_name) ) ,
205
+ ( true , None ) => conn. quick_query ( "COMMIT" ) ,
206
+ } . map ( |_| ( ) )
206
207
}
207
208
208
209
/// Like `Connection::prepare`.
@@ -233,22 +234,33 @@ impl<'conn> Transaction<'conn> {
233
234
self . conn . batch_execute ( query)
234
235
}
235
236
236
- /// Like `Connection::transaction`.
237
+ /// Like `Connection::transaction`, but creates a nested transaction .
237
238
///
238
239
/// # Panics
239
240
///
240
241
/// Panics if there is an active nested transaction.
241
242
pub fn transaction < ' a > ( & ' a self ) -> Result < Transaction < ' a > > {
243
+ self . savepoint ( "sp" )
244
+ }
245
+
246
+ /// Like `Connection::transaction`, but creates a nested transaction
247
+ /// with the provided name.
248
+ ///
249
+ /// # Panics
250
+ ///
251
+ /// Panics if there is an active nested transaction.
252
+ pub fn savepoint < ' a > ( & ' a self , name : & ' a str ) -> Result < Transaction < ' a > > {
242
253
let mut conn = self . conn . conn . borrow_mut ( ) ;
243
254
check_desync ! ( conn) ;
244
255
assert ! ( conn. trans_depth == self . depth,
245
- "`transaction ` may only be called on the active transaction" ) ;
246
- try!( conn. quick_query ( "SAVEPOINT sp" ) ) ;
256
+ "`savepoint ` may only be called on the active transaction" ) ;
257
+ try!( conn. quick_query ( & format ! ( "SAVEPOINT {}" , name ) ) ) ;
247
258
conn. trans_depth += 1 ;
248
259
Ok ( Transaction {
249
260
conn : self . conn ,
250
- commit : Cell :: new ( false ) ,
251
261
depth : self . depth + 1 ,
262
+ savepoint_name : Some ( name) ,
263
+ commit : Cell :: new ( false ) ,
252
264
finished : false ,
253
265
} )
254
266
}
0 commit comments