use std::fmt::Debug;
use super::expressive::Expressive;
use crate::{Expression, ExpressiveEnum};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Order {
pub ascending: bool,
pub nulls: Option<Nulls>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Nulls {
First,
Last,
}
#[allow(non_upper_case_globals)]
impl Order {
pub const Asc: Order = Order {
ascending: true,
nulls: None,
};
pub const Desc: Order = Order {
ascending: false,
nulls: None,
};
pub fn nulls_last(self) -> Self {
Self {
nulls: Some(Nulls::Last),
..self
}
}
pub fn nulls_first(self) -> Self {
Self {
nulls: Some(Nulls::First),
..self
}
}
pub fn suffix(&self) -> &'static str {
match (self.ascending, self.nulls) {
(true, None) => "",
(false, None) => " DESC",
(true, Some(Nulls::Last)) => " NULLS LAST",
(true, Some(Nulls::First)) => " NULLS FIRST",
(false, Some(Nulls::Last)) => " DESC NULLS LAST",
(false, Some(Nulls::First)) => " DESC NULLS FIRST",
}
}
}
pub trait Selectable<T, C = Expression<T>>: Send + Sync + Debug + Clone {
fn add_source(&mut self, source: impl Into<SourceRef<T>>, alias: Option<String>);
fn add_field(&mut self, field: impl Into<String>);
fn add_expression(&mut self, expression: impl Expressive<T>);
fn add_where_condition(&mut self, condition: impl Into<C>);
fn set_distinct(&mut self, distinct: bool);
fn add_order_by(&mut self, order: impl Into<C>, direction: Order);
fn add_group_by(&mut self, expression: impl Expressive<T>);
fn set_limit(&mut self, limit: Option<i64>, skip: Option<i64>);
fn clear_fields(&mut self);
fn clear_where_conditions(&mut self);
fn clear_order_by(&mut self);
fn clear_group_by(&mut self);
fn has_fields(&self) -> bool;
fn has_where_conditions(&self) -> bool;
fn has_order_by(&self) -> bool;
fn has_group_by(&self) -> bool;
fn is_distinct(&self) -> bool;
fn get_limit(&self) -> Option<i64>;
fn get_skip(&self) -> Option<i64>;
fn as_count(&self) -> Expression<T>;
fn as_sum(&self, column: impl Expressive<T>) -> Expression<T>;
fn as_max(&self, column: impl Expressive<T>) -> Expression<T>;
fn as_min(&self, column: impl Expressive<T>) -> Expression<T>;
fn with_source(mut self, source: impl Into<SourceRef<T>>) -> Self
where
Self: Sized,
{
Self::add_source(&mut self, source, None);
self
}
fn with_source_as(mut self, source: impl Into<SourceRef<T>>, alias: impl Into<String>) -> Self
where
Self: Sized,
{
Self::add_source(&mut self, source, Some(alias.into()));
self
}
fn with_condition(mut self, condition: impl Into<C>) -> Self
where
Self: Sized,
{
Self::add_where_condition(&mut self, condition);
self
}
fn with_order(mut self, order: impl Into<C>, direction: Order) -> Self
where
Self: Sized,
{
Self::add_order_by(&mut self, order, direction);
self
}
fn with_field(mut self, field: impl Into<String>) -> Self
where
Self: Sized,
{
Self::add_field(&mut self, field);
self
}
fn with_expression(mut self, expression: impl Expressive<T>) -> Self
where
Self: Sized,
{
Self::add_expression(&mut self, expression);
self
}
fn with_group_by(mut self, expression: impl Expressive<T>) -> Self
where
Self: Sized,
{
Self::add_group_by(&mut self, expression);
self
}
fn with_distinct(mut self, distinct: bool) -> Self
where
Self: Sized,
{
Self::set_distinct(&mut self, distinct);
self
}
fn with_limit(mut self, limit: Option<i64>, skip: Option<i64>) -> Self
where
Self: Sized,
{
Self::set_limit(&mut self, limit, skip);
self
}
}
pub struct SourceRef<T>(ExpressiveEnum<T>);
impl<T> SourceRef<T> {
pub fn into_expressive_enum(self) -> ExpressiveEnum<T> {
self.0
}
}
impl<T> From<&str> for SourceRef<T>
where
T: From<String>,
{
fn from(value: &str) -> Self {
SourceRef(ExpressiveEnum::Scalar(T::from(value.to_string())))
}
}
impl<T> From<String> for SourceRef<T>
where
T: From<String>,
{
fn from(value: String) -> Self {
SourceRef(ExpressiveEnum::Scalar(T::from(value)))
}
}
impl<T> From<Expression<T>> for SourceRef<T> {
fn from(value: Expression<T>) -> Self {
SourceRef(ExpressiveEnum::Nested(value))
}
}