#[doc(hidden)]
use std::str::FromStr;
pub(crate) const LOB_CHUNK_MAXSIZE_SET: usize = 1048500;
#[derive(Debug, PartialEq)]
pub enum MimerDatatype<'a> {
Null,
BigInt(i64),
Int(i32),
Double(f64),
Real(f32),
String(String),
StringRef(&'a str),
Bool(bool),
BinaryArray(Vec<u8>),
BinaryArrayRef(&'a [u8]),
}
pub trait ToSql {
fn to_sql(&self) -> MimerDatatype;
}
pub trait FromSql: Sized {
fn from_sql(value: MimerDatatype) -> Result<Self, i32>;
}
impl<T> ToSql for Option<T>
where
T: ToSql,
{
fn to_sql(&self) -> MimerDatatype {
match self {
Some(v) => v.to_sql(),
None => MimerDatatype::Null,
}
}
}
impl ToSql for i32 {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::Int(*self)
}
}
impl FromSql for i32 {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::Int(val) => Ok(val),
_ => Err(-26200),
}
}
}
impl ToSql for i64 {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::BigInt(*self)
}
}
impl FromSql for i64 {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::BigInt(val) => Ok(val),
_ => Err(-26200),
}
}
}
impl ToSql for &str {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::StringRef(self)
}
}
impl ToSql for String {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::StringRef(self)
}
}
impl FromSql for String {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::String(val) => Ok(val.to_string()),
_ => Err(-26200),
}
}
}
impl ToSql for f32 {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::Real(*self)
}
}
impl FromSql for f32 {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::Real(val) => Ok(val),
MimerDatatype::BinaryArray(val) => {
if val.len() != 4 {
Err(-26200)
} else {
Ok(f32::from_le_bytes(val[0..4].try_into().unwrap()))
}
}
_ => Err(-26200),
}
}
}
impl ToSql for f64 {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::Double(*self)
}
}
impl FromSql for f64 {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::Double(val) => Ok(val),
_ => Err(-26200),
}
}
}
impl ToSql for bool {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::Bool(*self)
}
}
impl FromSql for bool {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::Bool(val) => Ok(val),
_ => Err(-26200),
}
}
}
impl ToSql for Vec<u8> {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::BinaryArrayRef(self)
}
}
impl<const N: usize> ToSql for [u8; N] {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::BinaryArrayRef(self)
}
}
impl FromSql for Vec<u8> {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::BinaryArray(val) => Ok(val),
_ => Err(-26200),
}
}
}
impl ToSql for uuid::Uuid {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::BinaryArrayRef(self.as_bytes())
}
}
impl FromSql for uuid::Uuid {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::BinaryArray(val) => {
let mut bytes: [u8; 16] = [0; 16];
bytes.copy_from_slice(&val[..16]);
Ok(uuid::Uuid::from_bytes(bytes))
}
_ => Err(-26200),
}
}
}
impl ToSql for chrono::NaiveDate {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::String(self.to_string())
}
}
impl FromSql for chrono::NaiveDate {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::String(str) => match chrono::NaiveDate::from_str(str.as_ref()) {
Ok(date) => Ok(date),
Err(_) => Err(-26200),
},
_ => Err(-26200),
}
}
}
impl ToSql for chrono::NaiveTime {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::String(self.to_string())
}
}
impl FromSql for chrono::NaiveTime {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::String(str) => match chrono::NaiveTime::from_str(str.as_ref()) {
Ok(time) => Ok(time),
Err(_) => Err(-26200),
},
_ => Err(-26200),
}
}
}
impl ToSql for chrono::NaiveDateTime {
fn to_sql(&self) -> MimerDatatype {
MimerDatatype::String(self.to_string())
}
}
impl FromSql for chrono::NaiveDateTime {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::String(str) => {
match chrono::NaiveDateTime::parse_from_str(&str, "%Y-%m-%d %H:%M:%S") {
Ok(date_time) => Ok(date_time),
Err(_) => Err(-26200),
}
}
_ => Err(-26200),
}
}
}
impl ToSql for (f32, f32) {
fn to_sql(&self) -> MimerDatatype {
let mut bytes: [u8; 8] = [0; 8];
bytes[..4].copy_from_slice(&self.0.to_le_bytes());
bytes[4..].copy_from_slice(&self.1.to_le_bytes());
MimerDatatype::BinaryArray(bytes.to_vec())
}
}
impl FromSql for (f32, f32) {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::BinaryArray(v) => {
if v.len() != 8 {
return Err(-26200);
}
Ok((
f32::from_le_bytes(v[0..4].try_into().unwrap()), f32::from_le_bytes(v[4..8].try_into().unwrap()), ))
}
_ => Err(-26200),
}
}
}
impl ToSql for geo::Point<i32> {
fn to_sql(&self) -> MimerDatatype {
let mut bytes: [u8; 8] = [0; 8];
bytes[..4].copy_from_slice(&self.x().to_le_bytes());
bytes[4..].copy_from_slice(&self.y().to_le_bytes());
MimerDatatype::BinaryArray(bytes.to_vec())
}
}
impl FromSql for geo::Point<i32> {
fn from_sql(value: MimerDatatype) -> Result<Self, i32> {
match value {
MimerDatatype::BinaryArray(v) => {
if v.len() != 8 {
return Err(-26200);
}
Ok(geo::Point::new(
i32::from_le_bytes(v[0..4].try_into().unwrap()),
i32::from_le_bytes(v[4..8].try_into().unwrap()),
))
}
_ => Err(-26200),
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_temporal {
() => {
ffi::MIMER_DATE
| ffi::MIMER_TIME
| ffi::MIMER_TIMESTAMP
| ffi::MIMER_INTERVAL_YEAR
| ffi::MIMER_INTERVAL_MONTH
| ffi::MIMER_INTERVAL_DAY
| ffi::MIMER_INTERVAL_HOUR
| ffi::MIMER_INTERVAL_MINUTE
| ffi::MIMER_INTERVAL_SECOND
| ffi::MIMER_INTERVAL_YEAR_TO_MONTH
| ffi::MIMER_INTERVAL_DAY_TO_HOUR
| ffi::MIMER_INTERVAL_DAY_TO_MINUTE
| ffi::MIMER_INTERVAL_DAY_TO_SECOND
| ffi::MIMER_INTERVAL_HOUR_TO_MINUTE
| ffi::MIMER_INTERVAL_HOUR_TO_SECOND
| ffi::MIMER_INTERVAL_MINUTE_TO_SECOND
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_strings {
() => {
ffi::MIMER_CHARACTER_VARYING
| ffi::MIMER_CHARACTER
| ffi::MIMER_NCHAR
| ffi::MIMER_NCHAR_VARYING
| ffi::MIMER_UTF8
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_small_ints {
() => {
ffi::MIMER_T_INTEGER
| ffi::MIMER_NATIVE_SMALLINT_NULLABLE
| ffi::MIMER_NATIVE_INTEGER_NULLABLE
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_big_ints {
() => {
ffi::MIMER_NATIVE_BIGINT_NULLABLE
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_real {
() => {
ffi::MIMER_NATIVE_REAL_NULLABLE
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_doubles {
() => {
ffi::MIMER_T_DOUBLE | ffi::MIMER_NATIVE_DOUBLE_NULLABLE
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_booleans {
() => {
ffi::MIMER_BOOLEAN
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_BINARY {
() => {
ffi::MIMER_BINARY | ffi::MIMER_BINARY_VARYING
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_spatial {
() => {
ffi::MIMER_GIS_LOCATION
| ffi::MIMER_GIS_LATITUDE
| ffi::MIMER_GIS_LONGITUDE
| ffi::MIMER_GIS_COORDINATE
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_BLOB {
() => {
ffi::MIMER_BLOB | ffi::MIMER_NATIVE_BLOB
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! match_mimer_CLOB {
() => {
ffi::MIMER_CLOB | ffi::MIMER_NCLOB | ffi::MIMER_NATIVE_CLOB | ffi::MIMER_NATIVE_NCLOB
};
}