@@ -10,7 +10,7 @@ use crate::{
1010 value_converter:: { convert_parameters, PythonDTO } ,
1111} ;
1212
13- use super :: transaction_options:: IsolationLevel ;
13+ use super :: { cursor :: Cursor , transaction_options:: IsolationLevel } ;
1414
1515/// Transaction for internal use only.
1616///
@@ -22,6 +22,7 @@ pub struct RustTransaction {
2222 pub rollback_savepoint : Arc < tokio:: sync:: RwLock < HashSet < String > > > ,
2323
2424 pub isolation_level : Option < IsolationLevel > ,
25+ pub cursor_num : usize ,
2526}
2627
2728impl RustTransaction {
@@ -393,6 +394,34 @@ impl RustTransaction {
393394
394395 Ok ( ( ) )
395396 }
397+
398+ pub async fn inner_cursor < ' a > (
399+ & ' a mut self ,
400+ querystring : String ,
401+ parameters : Vec < PythonDTO > ,
402+ fetch_number : usize ,
403+ ) -> RustPSQLDriverPyResult < Cursor > {
404+ let db_client_arc = self . db_client . clone ( ) ;
405+ let db_client_arc2 = self . db_client . clone ( ) ;
406+ let db_client_guard = db_client_arc. read ( ) . await ;
407+
408+ let mut vec_parameters: Vec < & ( dyn ToSql + Sync ) > = Vec :: with_capacity ( parameters. len ( ) ) ;
409+ for param in parameters. iter ( ) {
410+ vec_parameters. push ( param) ;
411+ }
412+
413+ let cursor_name = format ! ( "cur{}" , self . cursor_num) ;
414+ db_client_guard
415+ . execute (
416+ & format ! ( "DECLARE {} CURSOR FOR {querystring}" , cursor_name) ,
417+ & vec_parameters. into_boxed_slice ( ) ,
418+ )
419+ . await ?;
420+
421+ self . cursor_num = self . cursor_num + 1 ;
422+
423+ Ok ( Cursor :: new ( db_client_arc2, cursor_name, fetch_number) )
424+ }
396425}
397426
398427#[ pyclass( ) ]
@@ -619,4 +648,25 @@ impl Transaction {
619648 Ok ( ( ) )
620649 } )
621650 }
651+
652+ pub fn cursor < ' a > (
653+ & ' a self ,
654+ py : Python < ' a > ,
655+ querystring : String ,
656+ parameters : Option < & ' a PyAny > ,
657+ fetch_number : Option < usize > ,
658+ ) -> RustPSQLDriverPyResult < & PyAny > {
659+ let transaction_arc = self . transaction . clone ( ) ;
660+ let mut params: Vec < PythonDTO > = vec ! [ ] ;
661+ if let Some ( parameters) = parameters {
662+ params = convert_parameters ( parameters) ?
663+ }
664+
665+ rustengine_future ( py, async move {
666+ let mut transaction_guard = transaction_arc. write ( ) . await ;
667+ Ok ( transaction_guard
668+ . inner_cursor ( querystring, params, fetch_number. unwrap_or ( 10 ) )
669+ . await ?)
670+ } )
671+ }
622672}
0 commit comments