@@ -151,6 +151,7 @@ impl Config {
151151pub struct Transaction < ' conn > {
152152 conn : & ' conn Connection ,
153153 depth : u32 ,
154+ savepoint_name : Option < String > ,
154155 commit : Cell < bool > ,
155156 finished : bool ,
156157}
@@ -177,6 +178,7 @@ impl<'conn> TransactionInternals<'conn> for Transaction<'conn> {
177178 Transaction {
178179 conn : conn,
179180 depth : depth,
181+ savepoint_name : None ,
180182 commit : Cell :: new ( false ) ,
181183 finished : false ,
182184 }
@@ -195,14 +197,13 @@ impl<'conn> Transaction<'conn> {
195197 fn finish_inner ( & mut self ) -> Result < ( ) > {
196198 let mut conn = self . conn . conn . borrow_mut ( ) ;
197199 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- } ;
204200 conn. trans_depth -= 1 ;
205- conn. quick_query ( query) . map ( |_| ( ) )
201+ match ( self . commit . get ( ) , & self . savepoint_name ) {
202+ ( false , & Some ( ref savepoint_name) ) => conn. quick_query ( & format ! ( "ROLLBACK TO {}" , savepoint_name) ) ,
203+ ( false , & None ) => conn. quick_query ( "ROLLBACK" ) ,
204+ ( true , & Some ( ref savepoint_name) ) => conn. quick_query ( & format ! ( "RELEASE {}" , savepoint_name) ) ,
205+ ( true , & None ) => conn. quick_query ( "COMMIT" ) ,
206+ } . map ( |_| ( ) )
206207 }
207208
208209 /// Like `Connection::prepare`.
@@ -233,22 +234,33 @@ impl<'conn> Transaction<'conn> {
233234 self . conn . batch_execute ( query)
234235 }
235236
236- /// Like `Connection::transaction`.
237+ /// Like `Connection::transaction`, but creates a nested transaction .
237238 ///
238239 /// # Panics
239240 ///
240241 /// Panics if there is an active nested transaction.
241242 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 : & str ) -> Result < Transaction < ' a > > {
242253 let mut conn = self . conn . conn . borrow_mut ( ) ;
243254 check_desync ! ( conn) ;
244255 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 ) ) ) ;
247258 conn. trans_depth += 1 ;
248259 Ok ( Transaction {
249260 conn : self . conn ,
250- commit : Cell :: new ( false ) ,
251261 depth : self . depth + 1 ,
262+ savepoint_name : Some ( name. to_owned ( ) ) ,
263+ commit : Cell :: new ( false ) ,
252264 finished : false ,
253265 } )
254266 }
0 commit comments