vantage_sql/primitives/select/
window.rs1use std::fmt::{Debug, Display};
2
3use vantage_expressions::{Expression, Expressive, ExpressiveEnum};
4
5#[derive(Debug, Clone)]
21pub struct Window<T: Debug + Display + Clone> {
22 partition_by: Vec<Expression<T>>,
23 order_by: Vec<(Expression<T>, vantage_expressions::Order)>,
24 frame: Option<String>,
25 named_ref: Option<String>,
26}
27
28impl<T: Debug + Display + Clone> Default for Window<T> {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl<T: Debug + Display + Clone> Window<T> {
35 pub fn new() -> Self {
36 Self {
37 partition_by: Vec::new(),
38 order_by: Vec::new(),
39 frame: None,
40 named_ref: None,
41 }
42 }
43
44 pub fn named(name: impl Into<String>) -> Self {
46 Self {
47 partition_by: Vec::new(),
48 order_by: Vec::new(),
49 frame: None,
50 named_ref: Some(name.into()),
51 }
52 }
53
54 pub fn partition_by(mut self, expr: impl Expressive<T>) -> Self {
55 self.partition_by.push(expr.expr());
56 self
57 }
58
59 pub fn order_by(mut self, expr: impl Expressive<T>, order: vantage_expressions::Order) -> Self {
60 self.order_by.push((expr.expr(), order));
61 self
62 }
63
64 pub fn rows(mut self, from: &str, to: &str) -> Self {
65 self.frame = Some(format!("ROWS BETWEEN {} AND {}", from, to));
66 self
67 }
68
69 pub fn range(mut self, from: &str, to: &str) -> Self {
70 self.frame = Some(format!("RANGE BETWEEN {} AND {}", from, to));
71 self
72 }
73
74 pub fn apply(&self, func: impl Expressive<T>) -> Expression<T> {
76 Expression::new(
77 "{} OVER {}",
78 vec![
79 ExpressiveEnum::Nested(func.expr()),
80 ExpressiveEnum::Nested(self.spec_expr()),
81 ],
82 )
83 }
84
85 fn spec_expr(&self) -> Expression<T> {
86 if let Some(name) = &self.named_ref {
87 return Expression::new(name.clone(), vec![]);
88 }
89
90 let mut parts: Vec<Expression<T>> = Vec::new();
91
92 if !self.partition_by.is_empty() {
93 parts.push(Expression::new(
94 "PARTITION BY {}",
95 vec![ExpressiveEnum::Nested(Expression::from_vec(
96 self.partition_by.clone(),
97 ", ",
98 ))],
99 ));
100 }
101
102 if !self.order_by.is_empty() {
103 let order_parts: Vec<Expression<T>> = self
104 .order_by
105 .iter()
106 .map(|(expr, order)| {
107 Expression::new(
108 format!("{{}}{}", order.suffix()),
109 vec![ExpressiveEnum::Nested(expr.clone())],
110 )
111 })
112 .collect();
113 parts.push(Expression::new(
114 "ORDER BY {}",
115 vec![ExpressiveEnum::Nested(Expression::from_vec(
116 order_parts,
117 ", ",
118 ))],
119 ));
120 }
121
122 if let Some(frame) = &self.frame {
123 parts.push(Expression::new(frame.clone(), vec![]));
124 }
125
126 let inner = Expression::from_vec(parts, " ");
127 Expression::new("({})", vec![ExpressiveEnum::Nested(inner)])
128 }
129
130 pub fn definition(&self) -> Expression<T> {
132 self.spec_expr()
133 }
134}