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> {
87 if let Some(name) = &self.named_ref {
88 return Expression::new(name.clone(), vec![]);
89 }
90
91 let mut parts: Vec<Expression<T>> = Vec::new();
92
93 if !self.partition_by.is_empty() {
94 parts.push(Expression::new(
95 "PARTITION BY {}",
96 vec![ExpressiveEnum::Nested(Expression::from_vec(
97 self.partition_by.clone(),
98 ", ",
99 ))],
100 ));
101 }
102
103 if !self.order_by.is_empty() {
104 let order_parts: Vec<Expression<T>> = self
105 .order_by
106 .iter()
107 .map(|(expr, order)| {
108 Expression::new(
109 format!("{{}}{}", order.suffix()),
110 vec![ExpressiveEnum::Nested(expr.clone())],
111 )
112 })
113 .collect();
114 parts.push(Expression::new(
115 "ORDER BY {}",
116 vec![ExpressiveEnum::Nested(Expression::from_vec(
117 order_parts,
118 ", ",
119 ))],
120 ));
121 }
122
123 if let Some(frame) = &self.frame {
124 parts.push(Expression::new(frame.clone(), vec![]));
125 }
126
127 let inner = Expression::from_vec(parts, " ");
128 Expression::new("({})", vec![ExpressiveEnum::Nested(inner)])
129 }
130
131 pub fn definition(&self) -> Expression<T> {
133 self.spec_expr()
134 }
135}