sift-query-sqlx 0.1.0

PostgreSQL renderer and sqlx executor for SiftQuery
Documentation
use sift_query_core::{AggregateFn, ValueType};

pub(super) fn bind_type(value_type: ValueType) -> Result<&'static str, crate::RenderError> {
    Ok(match value_type {
        ValueType::Bool => "boolean",
        ValueType::I32 => "integer",
        ValueType::I64 => "bigint",
        ValueType::F32 => "real",
        ValueType::F64 => "double precision",
        ValueType::Text => "text",
        ValueType::Bytes => "bytea",
        #[cfg(feature = "decimal")]
        ValueType::Decimal => "numeric",
        #[cfg(feature = "chrono")]
        ValueType::Date => "date",
        #[cfg(feature = "chrono")]
        ValueType::Time => "time",
        #[cfg(feature = "chrono")]
        ValueType::DateTime => "timestamp",
        #[cfg(feature = "chrono")]
        ValueType::Timestamp => "timestamptz",
        #[cfg(feature = "uuid")]
        ValueType::Uuid => "uuid",
        #[cfg(feature = "json")]
        ValueType::Json => "jsonb",
        #[cfg(feature = "postgres-types")]
        ValueType::ArrayI64 => "bigint[]",
        #[cfg(feature = "postgres-types")]
        ValueType::ArrayText => "text[]",
        #[cfg(feature = "postgres-types")]
        ValueType::Int8Range => "int8range",
        #[cfg(feature = "postgres-types")]
        ValueType::Network => "inet",
        _ => {
            return Err(crate::RenderError::UnsupportedBindType(format!(
                "{value_type:?}"
            )));
        }
    })
}

pub(super) fn supports_array(value_type: ValueType) -> bool {
    match value_type {
        ValueType::Bool
        | ValueType::I32
        | ValueType::I64
        | ValueType::F32
        | ValueType::F64
        | ValueType::Text => true,
        #[cfg(feature = "decimal")]
        ValueType::Decimal => true,
        #[cfg(feature = "chrono")]
        ValueType::Date | ValueType::Time | ValueType::DateTime | ValueType::Timestamp => true,
        #[cfg(feature = "uuid")]
        ValueType::Uuid => true,
        _ => false,
    }
}

pub(super) fn supports_aggregate(function: AggregateFn, value_type: ValueType) -> bool {
    match function {
        AggregateFn::Sum => match value_type {
            ValueType::I32 | ValueType::F32 | ValueType::F64 => true,
            #[cfg(feature = "decimal")]
            ValueType::I64 | ValueType::Decimal => true,
            _ => false,
        },
        AggregateFn::Avg => match value_type {
            ValueType::F32 | ValueType::F64 => true,
            #[cfg(feature = "decimal")]
            ValueType::I32 | ValueType::I64 | ValueType::Decimal => true,
            _ => false,
        },
        AggregateFn::Min | AggregateFn::Max => match value_type {
            ValueType::I32 | ValueType::I64 | ValueType::F32 | ValueType::F64 | ValueType::Text => {
                true
            }
            #[cfg(feature = "decimal")]
            ValueType::Decimal => true,
            #[cfg(feature = "chrono")]
            ValueType::Date | ValueType::Time | ValueType::DateTime | ValueType::Timestamp => true,
            #[cfg(feature = "uuid")]
            ValueType::Uuid => true,
            _ => false,
        },
        AggregateFn::Custom(_) => true,
    }
}

pub(super) fn render_aggregate(function: AggregateFn, field: &str) -> String {
    match function {
        AggregateFn::Sum => format!("sum({field})"),
        AggregateFn::Avg => format!("avg({field})"),
        AggregateFn::Min => format!("min({field})"),
        AggregateFn::Max => format!("max({field})"),
        AggregateFn::Custom(aggregate) => aggregate.template().replace("{field}", field),
    }
}
#[cfg(test)]
mod tests;