use crate::{expr::*, query::*, types::*};
pub trait OverStatement {
#[doc(hidden)]
fn add_partition_by(&mut self, partition: SimpleExpr) -> &mut Self;
fn partition_by<T>(&mut self, col: T) -> &mut Self
where
T: IntoColumnRef,
{
self.add_partition_by(SimpleExpr::Column(col.into_column_ref()))
}
fn partition_by_customs<T>(&mut self, cols: Vec<T>) -> &mut Self
where
T: ToString,
{
cols.into_iter().for_each(|c| {
self.add_partition_by(SimpleExpr::Custom(c.to_string()));
});
self
}
fn partition_by_columns<T>(&mut self, cols: Vec<T>) -> &mut Self
where
T: IntoColumnRef,
{
cols.into_iter().for_each(|c| {
self.add_partition_by(SimpleExpr::Column(c.into_column_ref()));
});
self
}
}
#[derive(Debug, Clone)]
pub enum Frame {
UnboundedPreceding,
Preceding(u32),
CurrentRow,
Following(u32),
UnboundedFollowing,
}
#[derive(Debug, Clone)]
pub enum FrameType {
Range,
Rows,
}
#[derive(Debug, Clone)]
pub struct FrameClause {
pub(crate) r#type: FrameType,
pub(crate) start: Frame,
pub(crate) end: Option<Frame>,
}
#[derive(Debug, Clone)]
pub struct WindowStatement {
pub(crate) partition_by: Vec<SimpleExpr>,
pub(crate) order_by: Vec<OrderExpr>,
pub(crate) frame: Option<FrameClause>,
}
impl Default for WindowStatement {
fn default() -> Self {
Self::new()
}
}
impl WindowStatement {
pub fn new() -> Self {
Self {
partition_by: Vec::new(),
order_by: Vec::new(),
frame: None,
}
}
pub fn take(&mut self) -> Self {
Self {
partition_by: std::mem::take(&mut self.partition_by),
order_by: std::mem::take(&mut self.order_by),
frame: self.frame.take(),
}
}
pub fn partition_by<T>(col: T) -> Self
where
T: IntoColumnRef,
{
let mut window = Self::new();
window.add_partition_by(SimpleExpr::Column(col.into_column_ref()));
window
}
pub fn partition_by_custom<T>(col: T) -> Self
where
T: ToString,
{
let mut window = Self::new();
window.add_partition_by(SimpleExpr::Custom(col.to_string()));
window
}
pub fn order_by<T>(col: T, order: Order) -> Self
where
T: IntoColumnRef,
{
let mut window = Self::new();
window.order_by_expr(SimpleExpr::Column(col.into_column_ref()), order);
window
}
pub fn order_by_custom<T>(col: T, order: Order) -> Self
where
T: ToString,
{
let mut window = Self::new();
window.order_by_expr(SimpleExpr::Custom(col.to_string()), order);
window
}
pub fn frame_start(&mut self, r#type: FrameType, start: Frame) -> &mut Self {
self.frame(r#type, start, None)
}
pub fn frame_between(&mut self, r#type: FrameType, start: Frame, end: Frame) -> &mut Self {
self.frame(r#type, start, Some(end))
}
pub fn frame(&mut self, r#type: FrameType, start: Frame, end: Option<Frame>) -> &mut Self {
let frame_clause = FrameClause { r#type, start, end };
self.frame = Some(frame_clause);
self
}
}
impl OverStatement for WindowStatement {
fn add_partition_by(&mut self, partition: SimpleExpr) -> &mut Self {
self.partition_by.push(partition);
self
}
}
impl OrderedStatement for WindowStatement {
fn add_order_by(&mut self, order: OrderExpr) -> &mut Self {
self.order_by.push(order);
self
}
}