wick_sql/mssql_tiberius/
sql_wrapper.rs

1use chrono::{DateTime, NaiveDate, NaiveTime, TimeZone, Utc};
2use serde_json::{Number, Value};
3use tiberius::{ColumnData, FromSql, IntoSql};
4
5use crate::common::sql_wrapper::ConvertedType;
6
7impl<'a> IntoSql<'a> for ConvertedType {
8  fn into_sql(self) -> ColumnData<'a> {
9    match self {
10      ConvertedType::I8(v) => v.into_sql(),
11      ConvertedType::I16(v) => v.into_sql(),
12      ConvertedType::I32(v) => v.into_sql(),
13      ConvertedType::I64(v) => v.into_sql(),
14      ConvertedType::U8(v) => v.into_sql(),
15      ConvertedType::U16(v) => v.into_sql(),
16      ConvertedType::U32(v) => v.into_sql(),
17      ConvertedType::U64(v) => v.into_sql(),
18      ConvertedType::F32(v) => v.into_sql(),
19      ConvertedType::F64(v) => v.into_sql(),
20      ConvertedType::Bool(v) => v.into_sql(),
21      ConvertedType::String(v) => v.into_sql(),
22      ConvertedType::Datetime(v) => v.into_sql(),
23    }
24  }
25}
26
27pub(crate) struct FromSqlWrapper(pub(crate) Value);
28
29impl<'a> FromSql<'a> for FromSqlWrapper {
30  fn from_sql(col: &'a ColumnData<'static>) -> tiberius::Result<Option<Self>> {
31    let value: Option<Value> = match col {
32      ColumnData::U8(v) => v.map(Into::into),
33      ColumnData::I16(v) => v.map(Into::into),
34      ColumnData::I32(v) => v.map(Into::into),
35      ColumnData::I64(v) => v.map(Into::into),
36      ColumnData::F32(v) => v.map(Into::into),
37      ColumnData::F64(v) => v.map(Into::into),
38      ColumnData::Bit(v) => v.map(Into::into),
39      ColumnData::String(v) => v.clone().map(|v| v.into()),
40      ColumnData::Guid(v) => v.map(|v| Value::from(v.to_string())),
41      ColumnData::Binary(v) => v
42        .clone()
43        .map(|v| Value::Array(v.iter().copied().map(|v| Value::Number(Number::from(v))).collect())),
44      ColumnData::Numeric(v) => v.map(|v| {
45        let v: i64 = v.value().try_into().unwrap();
46        Value::Number(Number::from(v))
47      }),
48      ColumnData::Xml(_) => unimplemented!(),
49      ColumnData::DateTime(_) | ColumnData::SmallDateTime(_) | ColumnData::DateTime2(_) => {
50        tiberius::time::chrono::NaiveDateTime::from_sql(col)?
51          .map(|d| Value::String(Utc.from_utc_datetime(&d).to_rfc3339()))
52      }
53      ColumnData::DateTimeOffset(_) => DateTime::<Utc>::from_sql(col)?.map(|d| Value::String(d.to_rfc3339())),
54      ColumnData::Time(_) => NaiveTime::from_sql(col)?.map(|d| Value::String(d.to_string())),
55      ColumnData::Date(_) => NaiveDate::from_sql(col)?.map(|d| Value::String(d.to_string())),
56    };
57    Ok(value.map(FromSqlWrapper))
58  }
59}