diesel/mysql_like/connection/stmt/
metadata.rs1#![allow(unsafe_code)] use core::ffi::CStr;
3use core::ptr::NonNull;
4use core::slice;
5
6use super::ffi;
7use crate::mysql_like::connection::bind::Flags;
8
9pub(in crate::mysql_like::connection) struct StatementMetadata {
10 fields: Vec<MysqlFieldMetadata>,
11}
12
13impl StatementMetadata {
14 pub(in crate::mysql_like::connection) fn new(mut result: NonNull<ffi::MYSQL_RES>) -> Self {
15 let fields: &[ffi::MYSQL_FIELD] = unsafe {
16 let num_fields = ffi::mysql_num_fields(result.as_ptr());
17 let field_ptr = ffi::mysql_fetch_fields(result.as_ptr());
18 if field_ptr.is_null() {
19 &[]
20 } else {
21 slice::from_raw_parts(field_ptr, num_fields as usize)
22 }
23 };
24 let fields = fields
25 .iter()
26 .map(|f| {
27 let field_name = if f.name.is_null() {
28 None
29 } else {
30 unsafe {
31 Some(CStr::from_ptr(f.name).to_str().expect(
32 "Expect mysql field names to be UTF-8, because we \
33 requested UTF-8 encoding on connection setup",
34 ))
35 }
36 };
37 MysqlFieldMetadata {
38 field_name: field_name.map(Into::into),
39 field_type: f.type_,
40 flags: f.flags,
41 }
42 })
43 .collect::<Vec<_>>();
44 unsafe {
45 ffi::mysql_free_result(result.as_mut());
46 }
47 StatementMetadata { fields }
48 }
49
50 pub(in crate::mysql_like::connection) fn fields(&'_ self) -> &'_ [MysqlFieldMetadata] {
51 &self.fields
52 }
53}
54
55pub(in crate::mysql_like::connection) struct MysqlFieldMetadata {
56 field_name: Option<Box<str>>,
57 field_type: ffi::enum_field_types,
58 flags: core::ffi::c_uint,
59}
60
61impl MysqlFieldMetadata {
62 pub(in crate::mysql_like::connection) fn field_name(&self) -> Option<&str> {
63 self.field_name.as_deref()
64 }
65
66 pub(in crate::mysql_like::connection) fn field_type(&self) -> ffi::enum_field_types {
67 self.field_type
68 }
69
70 pub(in crate::mysql_like::connection) fn flags(
71 &self,
72 ) -> Result<Flags, Box<dyn core::error::Error + Send + Sync>> {
73 Flags::try_from(self.flags)
74 }
75}