use state::{SqlMethodTypes, aggregates_singleton, methods_singleton};
use types::Type;
pub fn add_method<'a, T: Into<Option<&'a str>>>(object_type: &Type, return_type: Type, argument_types: Vec<Type>,
method: &str, template: T)
{
let methods = methods_singleton();
methods.insert(method.to_string(), SqlMethodTypes {
argument_types,
object_type: object_type.clone(),
return_type,
template: template.into().map(ToString::to_string),
});
}
pub fn add_aggregate(rust_function: &str, sql_function: &str) {
let aggregates = aggregates_singleton();
aggregates.insert(rust_function.to_string(), sql_function.to_string());
}
pub fn add_initial_aggregates() {
add_aggregate("avg", "AVG");
}
pub fn add_initial_methods() {
let date_types = [Type::LocalDateTime, Type::NaiveDate, Type::NaiveDateTime, Type::UtcDateTime];
for date_type in &date_types {
#[cfg(feature = "postgres")]
add_method(date_type, Type::I32, vec![], "year", "EXTRACT(YEAR FROM $0)");
#[cfg(feature = "rusqlite")]
add_method(date_type, Type::I32, vec![], "year", "CAST(STRFTIME('%Y', $0) AS INT)");
#[cfg(feature = "postgres")]
add_method(date_type, Type::I32, vec![], "month", "EXTRACT(MONTH FROM $0)"); #[cfg(feature = "rusqlite")]
add_method(date_type, Type::I32, vec![], "month", "CAST(STRFTIME('%m', $0) AS INT)");
#[cfg(feature = "postgres")]
add_method(date_type, Type::I32, vec![], "day", "EXTRACT(DAY FROM $0)");
#[cfg(feature = "rusqlite")]
add_method(date_type, Type::I32, vec![], "day", "CAST(STRFTIME('%d', $0) AS INT)");
}
let time_types = [Type::LocalDateTime, Type::NaiveDateTime, Type::NaiveTime, Type::UtcDateTime];
for time_type in &time_types {
#[cfg(feature = "postgres")]
add_method(time_type, Type::I32, vec![], "hour", "EXTRACT(HOUR FROM $0)");
#[cfg(feature = "rusqlite")]
add_method(time_type, Type::I32, vec![], "hour", "CAST(STRFTIME('%H', $0) AS INT)");
#[cfg(feature = "postgres")]
add_method(time_type, Type::I32, vec![], "minute", "EXTRACT(MINUTE FROM $0)");
#[cfg(feature = "rusqlite")]
add_method(time_type, Type::I32, vec![], "minute", "CAST(STRFTIME('%M', $0) AS INT)");
#[cfg(feature = "postgres")]
add_method(time_type, Type::I32, vec![], "second", "EXTRACT(SECOND FROM $0)");
#[cfg(feature = "rusqlite")]
add_method(time_type, Type::I32, vec![], "second", "CAST(STRFTIME('%S', $0) AS INT)");
}
add_method(&Type::String, Type::Bool, vec![Type::String], "contains", "$0 LIKE '%' || $1 || '%'");
add_method(&Type::String, Type::Bool, vec![Type::String], "ends_with", "$0 LIKE '%' || $1");
add_method(&Type::String, Type::Bool, vec![Type::String], "starts_with", "$0 LIKE $1 || '%'");
add_method(&Type::String, Type::I32, vec![], "len", "LENGTH($0)");
#[cfg(feature = "postgres")]
add_method(&Type::String, Type::Bool, vec![Type::String], "regex", "$0 LIKE $1");
#[cfg(feature = "rusqlite")]
add_method(&Type::String, Type::Bool, vec![Type::String], "regex", None);
#[cfg(feature = "postgres")]
add_method(&Type::String, Type::Bool, vec![Type::String], "iregex", "$0 ILIKE $1");
#[cfg(feature = "rusqlite")]
add_method(&Type::String, Type::Bool, vec![Type::String], "iregex", "$0 LIKE $1");
add_method(&Type::Nullable(Box::new(Type::Generic)), Type::Bool, vec![], "is_some", "$0 IS NOT NULL");
add_method(&Type::Nullable(Box::new(Type::Generic)), Type::Bool, vec![], "is_none", "$0 IS NULL");
}