odbc-api-helper 0.1.6

odbc-api helper
Documentation
use crate::Convert;
use odbc_api::buffers::{AnyColumnView, BufferDescription, BufferKind};
use odbc_api::sys::{Date, Time, Timestamp};
use odbc_api::DataType;
use std::char::decode_utf16;

#[derive(Debug, Clone)]
pub struct Column {
    pub name: String,
    pub data_type: DataType,
    pub nullable: bool,
}

impl Column {
    pub fn new(name: String, data_type: DataType, nullable: bool) -> Self {
        Self {
            name,
            data_type,
            nullable,
        }
    }
}

impl TryFrom<&Column> for BufferDescription {
    type Error = String;

    fn try_from(c: &Column) -> Result<Self, Self::Error> {
        let description = BufferDescription {
            nullable: c.nullable,
            kind: BufferKind::from_data_type(c.data_type)
                .ok_or_else(|| format!("covert DataType:{:?} to BufferKind error", c.data_type))?,
        };
        Ok(description)
    }
}

#[derive(Debug)]
pub enum ColumnItem {
    Text(Option<String>),
    WText(Option<String>),
    Binary(Option<Vec<u8>>),
    Date(Option<Date>),
    Time(Option<Time>),
    Timestamp(Option<Timestamp>),
    F64(Option<f64>),
    F32(Option<f32>),
    I8(Option<i8>),
    I16(Option<i16>),
    I32(Option<i32>),
    I64(Option<i64>),
    U8(Option<u8>),
    Bit(Option<bool>),
}

impl ToString for ColumnItem {
    fn to_string(&self) -> String {
        format!("{:?}", self)
    }
}

impl Convert<Vec<ColumnItem>> for AnyColumnView<'_> {
    fn convert(self) -> Vec<ColumnItem> {
        match self {
            AnyColumnView::Text(view) => {
                let mut buffer = Vec::with_capacity(view.len());
                for v in view.iter() {
                    if let Some(x) = v {
                        let cow = String::from_utf8_lossy(x);
                        buffer.push(ColumnItem::Text(Some(cow.to_string())));
                    } else {
                        buffer.push(ColumnItem::Text(None))
                    }
                }
                return buffer;
            }
            AnyColumnView::WText(view) => {
                let mut buffer = Vec::with_capacity(view.len());
                for value in view.iter() {
                    if let Some(utf16) = value {
                        let mut buf_utf8 = String::new();
                        for c in decode_utf16(utf16.as_slice().iter().cloned()) {
                            buf_utf8.push(c.unwrap());
                        }
                        buffer.push(ColumnItem::WText(Some(buf_utf8)));
                    } else {
                        buffer.push(ColumnItem::WText(None))
                    }
                }
                return buffer;
            }
            AnyColumnView::Binary(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    if let Some(bytes) = value {
                        buffer.push(ColumnItem::Binary(Some(bytes.to_vec())))
                    } else {
                        buffer.push(ColumnItem::Binary(None))
                    }
                }
                return buffer;
            }
            AnyColumnView::Date(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::Date(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::Timestamp(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::Timestamp(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::Time(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::Time(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::I32(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::I32(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::Bit(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::Bit(Some(value.as_bool())))
                }
                return buffer;
            }

            AnyColumnView::F64(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::F64(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::F32(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::F32(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::I8(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::I8(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::I16(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::I16(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::I64(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::I64(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::U8(view) => {
                let mut buffer = vec![];
                for value in view.iter() {
                    buffer.push(ColumnItem::U8(Some(*value)))
                }
                return buffer;
            }
            AnyColumnView::NullableDate(_) => {
                warn!("lost NullableDate type");
            }
            AnyColumnView::NullableTime(_) => {
                warn!("lost NullableTime type");
            }
            AnyColumnView::NullableTimestamp(_) => {
                warn!("lost NullableTimestamp type");
            }
            AnyColumnView::NullableF64(_) => {
                warn!("lost NullableF64 type");
            }
            AnyColumnView::NullableF32(_) => {
                warn!("lost NullableF32 type");
            }
            AnyColumnView::NullableI8(_) => {
                warn!("lost NullableI8 type");
            }
            AnyColumnView::NullableI16(_) => {
                warn!("lost NullableI16 type");
            }
            AnyColumnView::NullableI32(_) => {
                warn!("lost NullableI32 type");
            }
            AnyColumnView::NullableI64(_) => {
                warn!("lost NullableI64 type");
            }
            AnyColumnView::NullableU8(_) => {
                warn!("lost NullableU8 type");
            }
            AnyColumnView::NullableBit(_) => {
                warn!("lost NullableBit type");
            }
        };
        vec![ColumnItem::Bit(None)]
    }
}