use rusqlite::types::Value;
use crate::number::AsInteger;
use crate::rusqlite::RusqliteQuery;
use crate::rusqlite::ToRusqliteSingleField;
use crate::sql::Field;
use crate::sql::Prefix;
use crate::NumberCriterium;
impl<N, F: Field> ToRusqliteSingleField<F> for NumberCriterium<N>
where
N: AsInteger,
{
fn get_sql_where(&self, field_name: &str) -> String {
self.get_number_criterium_sql_where(field_name)
}
fn get_inverted_sql_where(&self, field_name: &str) -> Option<String> {
self.get_number_criterium_inverted_sql_where(field_name)
}
fn get_where_values(&self, _is_inverted: bool) -> Vec<Value> {
self.get_number_criterium_where_values()
}
}
impl<N> NumberCriterium<N> {
fn get_number_criterium_sql_where(&self, field_name: &str) -> String {
match self {
Self::Equals(_) => format!("{field_name} = ?"),
Self::LessThan(_) => format!("{field_name} < ?"),
Self::LessThanOrEqual(_) => format!("{field_name} <= ?"),
Self::GreaterThan(_) => format!("{field_name} > ?"),
Self::GreaterThanOrEqual(_) => format!("{field_name} >= ?"),
Self::InList(l) => {
if !l.is_empty() {
format!("{} IN (?{})", field_name, ",?".repeat(l.len() - 1))
} else {
"0".to_string()
}
}
Self::IsNone => format!("{field_name} is NULL"),
}
}
fn get_number_criterium_inverted_sql_where(&self, field_name: &str) -> Option<String> {
Some(match self {
Self::Equals(_) => format!("{field_name} != ?"),
Self::LessThan(_) => format!("{field_name} >= ?"),
Self::LessThanOrEqual(_) => format!("{field_name} > ?"),
Self::GreaterThan(_) => format!("{field_name} <= ?"),
Self::GreaterThanOrEqual(_) => format!("{field_name} < ?"),
Self::InList(l) => {
if !l.is_empty() {
format!("{} NOT IN (?{})", field_name, ",?".repeat(l.len() - 1))
} else {
"1".to_string()
}
}
Self::IsNone => format!("{field_name} is not NULL"),
})
}
}
impl<N> NumberCriterium<N>
where
N: AsInteger,
{
fn get_number_criterium_where_values(&self) -> Vec<Value> {
vec![(match self {
Self::Equals(n) => n,
Self::LessThan(n) => n,
Self::LessThanOrEqual(n) => n,
Self::GreaterThan(n) => n,
Self::GreaterThanOrEqual(n) => n,
Self::InList(l) => {
return l.iter().map(|i| i.as_criterium_i64().into()).collect();
}
Self::IsNone => {
return Vec::new();
}
})
.as_criterium_i64()
.into()]
}
pub fn assemble_rusqlite_query_with_subquery<F: Field>(
&self,
prefix: Prefix,
sql_subquery: &str,
mut where_values: Vec<Value>,
) -> RusqliteQuery<F> {
where_values.append(&mut self.get_number_criterium_where_values());
RusqliteQuery {
used_prefix: prefix.to_string(),
sql_where_clause: self.get_number_criterium_sql_where(sql_subquery),
where_values: where_values,
sql_joins: Vec::new(),
}
}
}
macro_rules! impl_for_number_criterium_with_cast {
($e:ty) => {
impl<F: Field> ToRusqliteSingleField<F> for NumberCriterium<$e> {
fn get_sql_where(&self, field_name: &str) -> String {
self.translate(|n| n as i64)
.get_number_criterium_sql_where(field_name)
}
fn get_inverted_sql_where(&self, field_name: &str) -> Option<String> {
self.translate(|n| n as i64)
.get_number_criterium_inverted_sql_where(field_name)
}
fn get_where_values(&self, _is_inverted: bool) -> Vec<Value> {
self.translate(|n| n as i64)
.get_number_criterium_where_values()
}
}
};
}
impl_for_number_criterium_with_cast!(isize);
impl_for_number_criterium_with_cast!(usize);