use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
use queryweave::Value;
use sqlx::query_builder::Separated;
use sqlx::{Database, Encode, QueryBuilder, Type};
pub trait BindValues: Database {
fn push_bind_value(query_builder: &mut QueryBuilder<'_, Self>, value: Value);
fn push_bind_value_unseparated<Sep: std::fmt::Display>(
separated: &mut Separated<'_, '_, Self, Sep>,
value: Value,
);
}
macro_rules! bind_value {
($target:expr, $bind:ident, $value:expr) => {
match $value {
Value::Bool(value) => $target.$bind(value),
Value::I16(value) => $target.$bind(value),
Value::I32(value) => $target.$bind(value),
Value::I64(value) => $target.$bind(value),
Value::F32(value) => $target.$bind(value),
Value::F64(value) => $target.$bind(value),
Value::Text(value) => $target.$bind(value),
Value::DateTimeUtc(value) => $target.$bind(value),
Value::NaiveDateTime(value) => $target.$bind(value),
Value::NaiveDate(value) => $target.$bind(value),
Value::NaiveTime(value) => $target.$bind(value),
}
};
}
impl<DB> BindValues for DB
where
DB: Database,
for<'q> Option<bool>: Encode<'q, DB> + Type<DB>,
for<'q> Option<i16>: Encode<'q, DB> + Type<DB>,
for<'q> Option<i32>: Encode<'q, DB> + Type<DB>,
for<'q> Option<i64>: Encode<'q, DB> + Type<DB>,
for<'q> Option<f32>: Encode<'q, DB> + Type<DB>,
for<'q> Option<f64>: Encode<'q, DB> + Type<DB>,
for<'q> Option<String>: Encode<'q, DB> + Type<DB>,
for<'q> Option<DateTime<Utc>>: Encode<'q, DB> + Type<DB>,
for<'q> Option<NaiveDateTime>: Encode<'q, DB> + Type<DB>,
for<'q> Option<NaiveDate>: Encode<'q, DB> + Type<DB>,
for<'q> Option<NaiveTime>: Encode<'q, DB> + Type<DB>,
{
fn push_bind_value(query_builder: &mut QueryBuilder<'_, Self>, value: Value) {
bind_value!(query_builder, push_bind, value);
}
fn push_bind_value_unseparated<Sep: std::fmt::Display>(
separated: &mut Separated<'_, '_, Self, Sep>,
value: Value,
) {
bind_value!(separated, push_bind_unseparated, value);
}
}