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
use std::collections::HashMap; use std::ffi::CStr; use std::slice; use super::ffi; pub struct StatementMetadata { result: &'static mut ffi::MYSQL_RES, column_indices: HashMap<&'static str, usize>, } impl StatementMetadata { pub fn new(result: &'static mut ffi::MYSQL_RES) -> Self { let mut res = StatementMetadata { column_indices: HashMap::new(), result, }; res.populate_column_indices(); res } pub fn fields(&self) -> &[ffi::MYSQL_FIELD] { unsafe { let ptr = self.result as *const _ as *mut _; let num_fields = ffi::mysql_num_fields(ptr); let field_ptr = ffi::mysql_fetch_fields(ptr); slice::from_raw_parts(field_ptr, num_fields as usize) } } pub fn column_indices(&self) -> &HashMap<&str, usize> { &self.column_indices } fn populate_column_indices(&mut self) { self.column_indices = self .fields() .iter() .enumerate() .map(|(i, field)| { let c_name = unsafe { CStr::from_ptr(field.name) }; (c_name.to_str().unwrap_or_default(), i) }) .collect() } } impl Drop for StatementMetadata { fn drop(&mut self) { unsafe { ffi::mysql_free_result(self.result) }; } }