rbatis-core 3.1.11

Core of rbatis, the rust SQL toolkit. Not intended to be used directly.
Documentation
use std::str::FromStr;
use rbson::Bson;
use rbson::spec::BinarySubtype;
use sqlx_core::query::Query;
use crate::error::Error;
use crate::types::{DateNative, DateTimeUtc, DateUtc, Decimal, TimeNative, TimestampZ, TimeUtc};
use std::time::SystemTime;
use bigdecimal_::BigDecimal;
use sqlx_core::encode::{Encode, IsNull};
use sqlx_core::postgres::{Postgres, PgArguments, PgArgumentBuffer, PgHasArrayType, PgTypeInfo};
use sqlx_core::types::Type;
use crate::types::DateTimeNative;
use crate::Uuid;

pub struct PgNull {}

impl Type<Postgres> for PgNull {
    fn type_info() -> PgTypeInfo {
        PgTypeInfo::with_name("UNKNOWN")
    }
}

impl PgHasArrayType for PgNull {
    fn array_type_info() -> PgTypeInfo {
        PgTypeInfo::with_name("UNKNOWN")
    }
}


impl Encode<'_, Postgres> for PgNull {
    fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
        IsNull::Yes
    }
}

#[inline]
pub fn bind(t: Bson, mut q: Query<Postgres, PgArguments>) -> crate::Result<Query<Postgres, PgArguments>> {
    match t {
        Bson::String(s) => {
            if s.starts_with("TimestampZ(") {
                let data: TimestampZ = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            if s.starts_with("DateTimeUtc(") {
                let data: DateTimeUtc = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            if s.starts_with("DateTimeNative(") {
                let data: DateTimeNative = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            if s.starts_with("DateNative(") {
                let data: DateNative = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            if s.starts_with("DateUtc(") {
                let data: DateUtc = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            if s.starts_with("TimeUtc(") {
                let data: TimeUtc = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            if s.starts_with("TimeNative(") {
                let data: TimeNative = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            if s.starts_with("Decimal(") {
                let data: Decimal = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner.to_string());
                return Ok(q);
            }
            if s.starts_with("Uuid(") {
                let data: Uuid = rbson::from_bson(Bson::String(s))?;
                q = q.bind(data.inner);
                return Ok(q);
            }
            q = q.bind(Some(s));
        }
        Bson::Null => {
            q = q.bind(PgNull {});
        }
        Bson::Int32(n) => {
            q = q.bind(n);
        }
        Bson::Int64(n) => {
            q = q.bind(n);
        }
        Bson::UInt32(n) => {
            q = q.bind(n);
        }
        Bson::UInt64(n) => {
            q = q.bind(n as i64);
        }
        Bson::Double(n) => {
            q = q.bind(n);
        }
        Bson::Boolean(b) => {
            q = q.bind(b);
        }
        Bson::Decimal128(d) => {
            q = q.bind(BigDecimal::from_str(&d.to_string()).unwrap_or_default());
        }
        Bson::Binary(d) => {
            match d.subtype {
                BinarySubtype::Generic => {
                    q = q.bind(d.bytes);
                }
                BinarySubtype::Uuid => {
                    q = q.bind(crate::types::Uuid::from(d).inner);
                }
                BinarySubtype::UserDefined(type_id) => {
                    match type_id {
                        crate::types::BINARY_SUBTYPE_JSON => {
                            q = q.bind(serde_json::from_slice::<serde_json::Value>(&d.bytes).unwrap_or_default());
                        }
                        _ => {
                            return Err(Error::from("un supported bind type!"));
                        }
                    }
                }
                _ => {
                    return Err(Error::from("un supported bind type!"));
                }
            }
        }
        Bson::DateTime(d) => {
            q = q.bind(DateTimeNative::from(d).inner);
        }
        Bson::Timestamp(d) => {
            let timestamp = {
                let upper = (d.time.to_le() as u64) << 32;
                let lower = d.increment.to_le() as u64;
                (upper | lower) as i64
            };
            let sec = timestamp / 1000;
            let ns = (timestamp % 1000 * 1000000) as u32;
            let primitive_date_time = chrono::NaiveDateTime::from_timestamp(sec, ns);
            q = q.bind(primitive_date_time);
        }
        Bson::Array(arr) => {
            let mut arr_null = vec![];
            let mut arr_str = vec![];
            let mut arr_i32 = vec![];
            let mut arr_i64 = vec![];
            let mut arr_double = vec![];
            let mut arr_bool = vec![];
            let mut arr_decimal = vec![];
            let mut arr_bytes = vec![];
            let mut arr_uuid = vec![];
            let mut arr_json = vec![];
            let mut arr_timestampz = vec![];
            let mut arr_datetime_utc = vec![];
            let mut arr_datetime_native = vec![];
            let mut arr_datenative = vec![];
            let mut arr_dateutc = vec![];
            let mut arr_timeutc = vec![];
            let mut arr_timenative = vec![];
            for x in arr {
                match x {
                    Bson::String(s) => {
                        if s.starts_with("TimestampZ(") {
                            let data: TimestampZ = rbson::from_bson(Bson::String(s))?;
                            arr_timestampz.push(data.inner);
                            continue;
                        }
                        if s.starts_with("DateTimeUtc(") {
                            let data: DateTimeUtc = rbson::from_bson(Bson::String(s))?;
                            arr_datetime_utc.push(data.inner);
                            continue;
                        }
                        if s.starts_with("DateTimeNative(") {
                            let data: DateTimeNative = rbson::from_bson(Bson::String(s))?;
                            arr_datetime_native.push(data.inner);
                            continue;
                        }
                        if s.starts_with("DateNative(") {
                            let data: DateNative = rbson::from_bson(Bson::String(s))?;
                            arr_datenative.push(data.inner);
                            continue;
                        }
                        if s.starts_with("DateUtc(") {
                            let data: DateUtc = rbson::from_bson(Bson::String(s))?;
                            arr_dateutc.push(data.inner);
                            continue;
                        }
                        if s.starts_with("TimeUtc(") {
                            let data: TimeUtc = rbson::from_bson(Bson::String(s))?;
                            arr_timeutc.push(data.inner);
                            continue;
                        }
                        if s.starts_with("TimeNative(") {
                            let data: TimeNative = rbson::from_bson(Bson::String(s))?;
                            arr_timenative.push(data.inner);
                            continue;
                        }
                        if s.starts_with("Decimal(") {
                            let data: Decimal = rbson::from_bson(Bson::String(s))?;
                            arr_decimal.push(data.inner);
                            continue;
                        }
                        if s.starts_with("Uuid(") {
                            let data: Uuid = rbson::from_bson(Bson::String(s))?;
                            arr_uuid.push(data.inner);
                            continue;
                        }
                        arr_str.push(s);
                    }
                    Bson::Null => {
                        arr_null.push(PgNull {});
                    }
                    Bson::Int32(n) => {
                        arr_i32.push(n);
                    }
                    Bson::Int64(n) => {
                        arr_i64.push(n);
                    }
                    Bson::Double(n) => {
                        arr_double.push(n);
                    }
                    Bson::Boolean(b) => {
                        arr_bool.push(b);
                    }
                    Bson::Decimal128(d) => {
                        arr_decimal.push(BigDecimal::from_str(&d.to_string()).unwrap_or_default());
                    }
                    Bson::Binary(d) => {
                        match d.subtype {
                            BinarySubtype::Generic => {
                                arr_bytes.push(d.bytes);
                            }
                            BinarySubtype::Uuid => {
                                arr_uuid.push(crate::types::Uuid::from(d).inner);
                            }
                            BinarySubtype::UserDefined(type_id) => {
                                match type_id {
                                    crate::types::BINARY_SUBTYPE_JSON => {
                                        arr_json.push(serde_json::from_slice::<serde_json::Value>(&d.bytes).unwrap_or_default());
                                    }
                                    _ => {
                                        return Err(Error::from("un supported bind type!"));
                                    }
                                }
                            }
                            _ => {
                                return Err(Error::from("un supported bind type!"));
                            }
                        }
                    }
                    Bson::DateTime(d) => {
                        q = q.bind(DateTimeNative::from(d).inner);
                    }
                    Bson::Timestamp(d) => {
                        let timestamp = {
                            let upper = (d.time.to_le() as u64) << 32;
                            let lower = d.increment.to_le() as u64;
                            (upper | lower) as i64
                        };
                        let sec = timestamp / 1000;
                        let ns = (timestamp % 1000 * 1000000) as u32;
                        let primitive_date_time = chrono::NaiveDateTime::from_timestamp(sec, ns);
                        q = q.bind(primitive_date_time);
                    }
                    _ => {
                        return crate::Result::Err(crate::Error::from("unsupported type!"));
                    }
                }
            }
            if !arr_null.is_empty() {
                q = q.bind(arr_null);
            }
            if !arr_str.is_empty() {
                q = q.bind(arr_str);
            }
            if !arr_i32.is_empty() {
                q = q.bind(arr_i32);
            }
            if !arr_i64.is_empty() {
                q = q.bind(arr_i64);
            }
            if !arr_double.is_empty() {
                q = q.bind(arr_double);
            }
            if !arr_decimal.is_empty() {
                q = q.bind(arr_decimal);
            }
            if !arr_bytes.is_empty() {
                q = q.bind(arr_bytes);
            }
            if !arr_uuid.is_empty() {
                q = q.bind(arr_uuid);
            }
            if !arr_json.is_empty() {
                q = q.bind(arr_json);
            }
            if !arr_timestampz.is_empty() {
                q = q.bind(arr_timestampz);
            }
            if !arr_datetime_utc.is_empty() {
                q = q.bind(arr_datetime_utc);
            }
            if !arr_datetime_native.is_empty() {
                q = q.bind(arr_datetime_native);
            }
            if !arr_datenative.is_empty() {
                q = q.bind(arr_datenative);
            }
            if !arr_dateutc.is_empty() {
                q = q.bind(arr_dateutc);
            }
            if !arr_timeutc.is_empty() {
                q = q.bind(arr_timeutc);
            }
            if !arr_timenative.is_empty() {
                q = q.bind(arr_timenative);
            }
        }
        _ => {
            return crate::Result::Err(crate::Error::from("unsupported type!"));
        }
    }
    return Ok(q);
}