@@ -36,13 +36,7 @@ use odbc_api::{
3636use widestring:: Utf16String ;
3737
3838use std:: {
39- ffi:: CString ,
40- io:: { self , Write } ,
41- iter,
42- num:: NonZeroUsize ,
43- ptr:: null_mut,
44- str, thread,
45- time:: { Duration , Instant } ,
39+ ffi:: CString , io:: { self , Write } , iter, num:: NonZeroUsize , ptr:: null_mut, str, sync:: Arc , thread, time:: { Duration , Instant }
4640} ;
4741
4842const MSSQL : & Profile = & Profile {
@@ -571,6 +565,33 @@ fn into_cursor(profile: &Profile) {
571565 assert_eq ! ( expected, actual) ;
572566}
573567
568+ /// We want to be able to create multiple statements with the utilizing the same connection, yet we
569+ /// in some cases it might be hard to keep track of the ownership of the connection separately. So
570+ /// essentially we want our statements to be owning an `Arc` to connection.
571+ #[ test_case( MSSQL ; "Microsoft SQL Server" ) ]
572+ #[ test_case( MARIADB ; "Maria DB" ) ]
573+ #[ test_case( SQLITE_3 ; "SQLite 3" ) ]
574+ #[ test_case( POSTGRES ; "PostgreSQL" ) ]
575+ fn shared_ownership_of_connections_by_statement ( profile : & Profile ) {
576+ // Given
577+ let table_name = table_name ! ( ) ;
578+ let ( conn, table) = Given :: new ( & table_name)
579+ . column_types ( & [ "INT" ] )
580+ . values_by_column ( & [
581+ & [
582+ Some ( "42" )
583+ ] ,
584+ ] )
585+ . build ( profile)
586+ . unwrap ( ) ;
587+
588+ // When
589+ let conn = Arc :: new ( conn) ;
590+ let cursor_1 = conn. clone ( ) . execute_arc ( & table. sql_all_ordered_by_id ( ) , ( ) , None ) . unwrap ( ) . unwrap ( ) ;
591+ let cursor_2 = conn. execute_arc ( & table. sql_all_ordered_by_id ( ) , ( ) , None ) . unwrap ( ) . unwrap ( ) ;
592+ // drop(conn); // This line would not compile without the `Arc` around the connection type
593+ }
594+
574595/// Strong exception safety for `into_cursor`. Our first query will fail, because it will query a
575596/// non-existing table, but our second one using the same connection will succeed. This is one
576597/// scenario in which it is useful not to "swallow" the connection in case of an error.
@@ -1483,20 +1504,20 @@ fn var_char_slice_mut_as_input_output_parameter(profile: &Profile) {
14831504 let conn = profile. connection ( ) . unwrap ( ) ;
14841505 conn. execute (
14851506 r#"
1486- IF EXISTS (SELECT name FROM sysobjects WHERE name = 'TestInOutText')
1487- DROP PROCEDURE TestInOutText
1507+ IF EXISTS (SELECT name FROM sysobjects WHERE name = 'TestInOutText')
1508+ DROP PROCEDURE TestInOutText
14881509 "# ,
14891510 ( ) ,
14901511 None ,
14911512 )
14921513 . unwrap ( ) ;
14931514
14941515 conn. execute (
1495- r#"CREATE PROCEDURE TestInOutText
1496- @OutParm VARCHAR(15) OUTPUT
1516+ r#"CREATE PROCEDURE TestInOutText
1517+ @OutParm VARCHAR(15) OUTPUT
14971518 AS
1498- SELECT @OutParm = 'Hello, World!'
1499- RETURN 99
1519+ SELECT @OutParm = 'Hello, World!'
1520+ RETURN 99
15001521 "# ,
15011522 ( ) ,
15021523 None ,
@@ -2822,20 +2843,20 @@ fn output_parameter(profile: &Profile) {
28222843 let conn = profile. connection ( ) . unwrap ( ) ;
28232844 conn. execute (
28242845 r#"
2825- IF EXISTS (SELECT name FROM sysobjects WHERE name = 'TestOutputParam')
2826- DROP PROCEDURE TestOutputParam
2846+ IF EXISTS (SELECT name FROM sysobjects WHERE name = 'TestOutputParam')
2847+ DROP PROCEDURE TestOutputParam
28272848 "# ,
28282849 ( ) ,
28292850 None ,
28302851 )
28312852 . unwrap ( ) ;
28322853
28332854 conn. execute (
2834- r#"CREATE PROCEDURE TestOutputParam
2835- @OutParm int OUTPUT
2855+ r#"CREATE PROCEDURE TestOutputParam
2856+ @OutParm int OUTPUT
28362857 AS
2837- SELECT @OutParm = @OutParm + 5
2838- RETURN 99
2858+ SELECT @OutParm = @OutParm + 5
2859+ RETURN 99
28392860 "# ,
28402861 ( ) ,
28412862 None ,
0 commit comments