@@ -19,6 +19,7 @@ use std::mem;
19
19
use std:: ptr;
20
20
use std:: sync:: Arc ;
21
21
use std:: sync:: Mutex ;
22
+ use std:: time:: Duration ;
22
23
23
24
use crate :: binding:: * ;
24
25
use crate :: chkerr;
@@ -30,6 +31,7 @@ use crate::sql_type::ToSql;
30
31
use crate :: to_odpi_str;
31
32
use crate :: to_rust_slice;
32
33
use crate :: to_rust_str;
34
+ use crate :: util:: duration_to_msecs;
33
35
use crate :: AssertSend ;
34
36
use crate :: AssertSync ;
35
37
use crate :: Context ;
@@ -986,6 +988,73 @@ impl Connection {
986
988
Ok ( ( ) )
987
989
}
988
990
991
+ /// Gets the current call timeout used for round-trips to
992
+ /// the database made with this connection. `None` means that no timeouts
993
+ /// will take place.
994
+ pub fn call_timeout ( & self ) -> Result < Option < Duration > > {
995
+ let mut value = 0 ;
996
+ chkerr ! (
997
+ self . ctxt,
998
+ dpiConn_getCallTimeout( self . handle. raw( ) , & mut value)
999
+ ) ;
1000
+ if value != 0 {
1001
+ Ok ( Some ( Duration :: from_millis ( value. into ( ) ) ) )
1002
+ } else {
1003
+ Ok ( None )
1004
+ }
1005
+ }
1006
+
1007
+ /// Sets the call timeout to be used for round-trips to the
1008
+ /// database made with this connection. None means that no timeouts
1009
+ /// will take place.
1010
+ ///
1011
+ /// The call timeout value applies to each database round-trip
1012
+ /// individually, not to the sum of all round-trips. Time spent
1013
+ /// processing in rust-oracle before or after the completion of each
1014
+ /// round-trip is not counted.
1015
+ ///
1016
+ /// - If the time from the start of any one round-trip to the
1017
+ /// completion of that same round-trip exceeds call timeout,
1018
+ /// then the operation is halted and an exception occurs.
1019
+ ///
1020
+ /// - In the case where an rust-oracle operation requires more than one
1021
+ /// round-trip and each round-trip takes less than call timeout,
1022
+ /// then no timeout will occur, even if the sum of all round-trip
1023
+ /// calls exceeds call timeout.
1024
+ ///
1025
+ /// - If no round-trip is required, the operation will never be
1026
+ /// interrupted.
1027
+ ///
1028
+ /// After a timeout is triggered, rust-oracle attempts to clean up the
1029
+ /// internal connection state. The cleanup is allowed to take another
1030
+ /// `duration`.
1031
+ ///
1032
+ /// If the cleanup was successful, an exception DPI-1067 will be
1033
+ /// raised but the application can continue to use the connection.
1034
+ ///
1035
+ /// For small values of call timeout, the connection cleanup may not
1036
+ /// complete successfully within the additional call timeout
1037
+ /// period. In this case an exception ORA-3114 is raised and the
1038
+ /// connection will no longer be usable. It should be closed.
1039
+ pub fn set_call_timeout ( & self , dur : Option < Duration > ) -> Result < ( ) > {
1040
+ if let Some ( dur) = dur {
1041
+ let msecs = duration_to_msecs ( dur) . ok_or ( Error :: OutOfRange ( format ! (
1042
+ "Too large duration {:?}. It must be less than 49.7 days" ,
1043
+ dur
1044
+ ) ) ) ?;
1045
+ if msecs == 0 {
1046
+ return Err ( Error :: OutOfRange ( format ! (
1047
+ "Too short duration {:?}. It must not be submilliseconds" ,
1048
+ dur
1049
+ ) ) ) ;
1050
+ }
1051
+ chkerr ! ( self . ctxt, dpiConn_setCallTimeout( self . handle. raw( ) , msecs) ) ;
1052
+ } else {
1053
+ chkerr ! ( self . ctxt, dpiConn_setCallTimeout( self . handle. raw( ) , 0 ) ) ;
1054
+ }
1055
+ Ok ( ( ) )
1056
+ }
1057
+
989
1058
/// Gets current schema associated with the connection
990
1059
pub fn current_schema ( & self ) -> Result < String > {
991
1060
let mut s = new_odpi_str ( ) ;
0 commit comments