1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use super::*; use sys::*; /// A buffer large enough to hold an `SOLState` for diagnostics and a terminating zero. pub type State = [SQLCHAR; SQL_SQLSTATE_SIZE + 1]; /// Result of `Diagnostics::diagnostics` #[derive(Debug, Clone, Copy)] pub struct DiagResult { /// A five-character SQLSTATE code (and terminating NULL) for the diagnostic record /// `rec_number`. The first two characters indicate the class; the next three indicate the /// subclass. For more information, see [SQLSTATE][1]s. /// [1]: https://docs.microsoft.com/sql/odbc/reference/develop-app/sqlstates pub state: State, /// Native error code specific to the data source. pub native_error: SQLINTEGER, /// The total number of characters (excluding the terminating NULL) available to return in /// `message_text`. pub text_length: SQLSMALLINT, } /// A type implementing this trait is able to provide diagnostic information regarding the last /// method call. pub trait Diagnostics { /// Returns the current values of multiple fields of a diagnostic record that contains error, /// warning, and status information. /// /// # Arguments /// /// * `rec_number` - Indicates the status record from which the application seeks information. /// Status records are numbered from 1. /// * `message_text` - Buffer in which to return the diagnostic message text string. If the /// number of characters to return is greater than the buffer length, the /// diagnostic message is truncated to `max(message_text.len() - 1, 0)`. For /// the format of the string, see [Diagnostic Messages][1] /// /// # Result ///` /// * `Success` - The function successfully returned diagnostic information. /// * `Info` - The `message_text` buffer was too small to hold the requested diagnostic message. /// No diagnostic records were generated. To determine that a truncation occurred, /// the application must compare the buffer length to the actual number of bytes /// available, which is found in `DiagResult::text_length` /// * `Error` - `rec_number` was negative or `0`. /// * `NoData` - `rec_number` was greater than the number of diagnostic records that existed /// for the specified Handle. The function also returns `NoData` for any positive /// `rec_number` if there are no diagnostic records available. /// [1]: https://docs.microsoft.com/sql/odbc/reference/develop-app/diagnostic-messages fn diagnostics( &self, rec_number: SQLSMALLINT, message_text: &mut [SQLCHAR], ) -> ReturnOption<DiagResult>; } impl<H: Handle> Diagnostics for H { fn diagnostics( &self, rec_number: SQLSMALLINT, message_text: &mut [SQLCHAR], ) -> ReturnOption<DiagResult> { unsafe { let mut text_length = 0; let mut state = [0; 6]; let mut native_error = 0; let ret = SQLGetDiagRec( H::HANDLE_TYPE, self.handle(), rec_number, state.as_mut_ptr(), &mut native_error, message_text.as_mut_ptr(), message_text.buf_len(), &mut text_length, ); let result = DiagResult { text_length: text_length, state: state, native_error: native_error, }; match ret { SQL_SUCCESS => ReturnOption::Success(result), SQL_SUCCESS_WITH_INFO => ReturnOption::Info(result), SQL_ERROR => ReturnOption::Error(()), SQL_NO_DATA => ReturnOption::NoData(()), unexpected => panic!("SQLGetDiagRec returned: {:?}", unexpected), } } } } impl<S, E> Diagnostics for Return<S, E> where S: Diagnostics, E: Diagnostics, { fn diagnostics( &self, rec_number: SQLSMALLINT, message_text: &mut [SQLCHAR], ) -> ReturnOption<DiagResult> { match *self { Success(ref s) | Info(ref s) => s.diagnostics(rec_number, message_text), Error(ref e) => e.diagnostics(rec_number, message_text), } } }