#![allow(dead_code)]
use super::cellvalue::CellValue;
use super::decfloat;
use super::error::ValueError;
use super::*;
use maplit::hashmap;
use rust_decimal;
pub(crate) struct XSQLVar {
pub sqltype: u32,
pub sqlscale: i32,
pub sqlsubtype: i32,
pub sqllen: i32,
pub null_ok: bool,
pub fieldname: String,
pub relname: String,
pub ownname: String,
pub aliasname: String,
}
impl XSQLVar {
pub fn new() -> XSQLVar {
XSQLVar {
sqltype: 0,
sqlscale: 0,
sqlsubtype: 0,
sqllen: 0,
null_ok: false,
fieldname: "".to_string(),
relname: "".to_string(),
ownname: "".to_string(),
aliasname: "".to_string(),
}
}
pub fn io_length(&self) -> isize {
if self.sqltype == SQL_TYPE_TEXT {
self.sqllen as isize
} else {
let map = hashmap! {
SQL_TYPE_TEXT=> -1,
SQL_TYPE_VARYING=> -1,
SQL_TYPE_SHORT=> 4,
SQL_TYPE_LONG=> 4,
SQL_TYPE_FLOAT=> 4,
SQL_TYPE_TIME=> 4,
SQL_TYPE_DATE=> 4,
SQL_TYPE_DOUBLE=> 8,
SQL_TYPE_TIMESTAMP=> 8,
SQL_TYPE_BLOB=> 8,
SQL_TYPE_ARRAY=> 8,
SQL_TYPE_QUAD=> 8,
SQL_TYPE_INT64=> 8,
SQL_TYPE_INT128=> 16,
SQL_TYPE_TIMESTAMP_TZ=> 12,
SQL_TYPE_TIME_TZ=> 8,
SQL_TYPE_DEC64=> 8,
SQL_TYPE_DEC128=> 16,
SQL_TYPE_DEC_FIXED=> 16,
SQL_TYPE_BOOLEAN=> 1,
};
map[&self.sqltype]
}
}
pub fn name(&self) -> &str {
let map = hashmap! {
SQL_TYPE_TEXT=> "TEXT",
SQL_TYPE_VARYING=> "VARCHR",
SQL_TYPE_SHORT=> "SHORT",
SQL_TYPE_LONG=> "LONG",
SQL_TYPE_FLOAT=> "FLOAT",
SQL_TYPE_TIME=> "TIME",
SQL_TYPE_DATE=> "DATE",
SQL_TYPE_DOUBLE=> "DOUBLE",
SQL_TYPE_TIMESTAMP=> "TIMESTAMP",
SQL_TYPE_BLOB=> "BLOB",
SQL_TYPE_ARRAY=> "ARRAY",
SQL_TYPE_QUAD=> "QUAD",
SQL_TYPE_INT64=> "INT64",
SQL_TYPE_INT128=> "INT128",
SQL_TYPE_TIMESTAMP_TZ=> "TIMESTAMP WITH TIMEZONE",
SQL_TYPE_TIME_TZ=> "TIME WITH TIMEZONE",
SQL_TYPE_DEC64=> "DEC64",
SQL_TYPE_DEC128=> "DEC128",
SQL_TYPE_DEC_FIXED=> "DEC_FIXED",
SQL_TYPE_BOOLEAN=> "BOOLEAN",
};
map[&self.sqltype]
}
pub fn value(&self, raw_value: &[u8]) -> Result<CellValue, ValueError> {
match self.sqltype {
SQL_TYPE_TEXT => Ok(CellValue::Text(utils::bytes_to_rtrim_str(raw_value))),
SQL_TYPE_VARYING => Ok(CellValue::Varying(utils::bytes_to_str(raw_value))),
SQL_TYPE_SHORT => Ok(CellValue::Short(utils::bytes_to_bint32(raw_value) as i16)),
SQL_TYPE_LONG => Ok(CellValue::Long(utils::bytes_to_bint32(raw_value))),
SQL_TYPE_INT64 => Ok(if self.sqlscale < 0 {
CellValue::Decimal(rust_decimal::Decimal::new(
utils::bytes_to_bint64(raw_value),
(self.sqlscale * -1) as u32,
))
} else if self.sqlscale > 0 {
CellValue::Decimal(rust_decimal::Decimal::new(
utils::bytes_to_bint64(raw_value) * (self.sqlscale as i64),
0,
))
} else {
CellValue::Int64(utils::bytes_to_bint64(raw_value))
}),
SQL_TYPE_INT128 => Ok(if self.sqlscale < 0 {
CellValue::Decimal(rust_decimal::Decimal::new(
utils::bytes_to_bint64(raw_value),
(self.sqlscale * -1) as u32,
))
} else if self.sqlscale > 0 {
CellValue::Decimal(rust_decimal::Decimal::new(
(utils::bytes_to_bint128(raw_value) as i64) * (self.sqlscale as i64),
0,
))
} else {
CellValue::Int128(utils::bytes_to_bint128(raw_value))
}),
SQL_TYPE_DATE => Ok(CellValue::Date(utils::bytes_to_naive_date(raw_value))),
SQL_TYPE_TIME => Ok(CellValue::Time(utils::bytes_to_naive_time(raw_value))),
SQL_TYPE_TIMESTAMP => Ok(CellValue::TimeStamp(utils::bytes_to_naive_date_time(
raw_value,
))),
SQL_TYPE_TIME_TZ => Ok(CellValue::TimeTz(utils::bytes_to_time_tz(raw_value))),
SQL_TYPE_TIMESTAMP_TZ => Ok(CellValue::TimeStampTz(utils::bytes_to_date_time_tz(
raw_value,
))),
SQL_TYPE_FLOAT => Ok(CellValue::Float(utils::bytes_to_f32(raw_value))),
SQL_TYPE_DOUBLE => Ok(CellValue::Double(utils::bytes_to_f64(raw_value))),
SQL_TYPE_BOOLEAN => Ok(CellValue::Boolean(raw_value[0] != 0)),
SQL_TYPE_BLOB => Ok(if self.sqlsubtype == 1 {
CellValue::BlobText(raw_value.to_vec())
} else {
CellValue::BlobBinary(raw_value.to_vec())
}),
SQL_TYPE_DEC_FIXED => Ok(CellValue::Decimal(decfloat::decimal_fixed_to_decimal(
raw_value,
self.sqlscale,
)?)),
SQL_TYPE_DEC64 => Ok(CellValue::Decimal(decfloat::decimal64_to_decimal(
raw_value,
)?)),
SQL_TYPE_DEC128 => Ok(CellValue::Decimal(decfloat::decimal128_to_decimal(
raw_value,
)?)),
_ => Err(ValueError::new(&format!(
"can't parse result value:{}",
self.sqltype
))),
}
}
}