1use std::borrow::Cow;
2
3use crate::{expr::*, query::*, types::*};
4use inherent::inherent;
5
6pub trait OverStatement {
7 #[doc(hidden)]
8 fn add_partition_by(&mut self, partition: Expr) -> &mut Self;
10
11 fn partition_by<T>(&mut self, col: T) -> &mut Self
13 where
14 T: IntoColumnRef,
15 {
16 self.add_partition_by(Expr::Column(col.into_column_ref()))
17 }
18
19 fn partition_by_customs<I, T>(&mut self, cols: I) -> &mut Self
21 where
22 T: Into<Cow<'static, str>>,
23 I: IntoIterator<Item = T>,
24 {
25 cols.into_iter().for_each(|c| {
26 self.add_partition_by(Expr::Custom(c.into()));
27 });
28 self
29 }
30
31 fn partition_by_columns<I, T>(&mut self, cols: I) -> &mut Self
33 where
34 T: IntoColumnRef,
35 I: IntoIterator<Item = T>,
36 {
37 cols.into_iter().for_each(|c| {
38 self.add_partition_by(Expr::Column(c.into_column_ref()));
39 });
40 self
41 }
42}
43
44#[derive(Debug, Clone, PartialEq)]
46pub enum Frame {
47 UnboundedPreceding,
48 Preceding(u32),
49 CurrentRow,
50 Following(u32),
51 UnboundedFollowing,
52}
53
54#[derive(Debug, Clone, PartialEq)]
56pub enum FrameType {
57 Range,
58 Rows,
59}
60
61#[derive(Debug, Clone, PartialEq)]
63pub struct FrameClause {
64 pub(crate) r#type: FrameType,
65 pub(crate) start: Frame,
66 pub(crate) end: Option<Frame>,
67}
68
69#[derive(Default, Debug, Clone, PartialEq)]
77pub struct WindowStatement {
78 pub(crate) partition_by: Vec<Expr>,
79 pub(crate) order_by: Vec<OrderExpr>,
80 pub(crate) frame: Option<FrameClause>,
81}
82
83impl WindowStatement {
84 pub fn new() -> Self {
86 Self::default()
87 }
88
89 pub fn take(&mut self) -> Self {
90 Self {
91 partition_by: std::mem::take(&mut self.partition_by),
92 order_by: std::mem::take(&mut self.order_by),
93 frame: self.frame.take(),
94 }
95 }
96
97 pub fn partition_by<T>(col: T) -> Self
99 where
100 T: IntoColumnRef,
101 {
102 let mut window = Self::new();
103 window.add_partition_by(Expr::Column(col.into_column_ref()));
104 window
105 }
106
107 pub fn partition_by_custom<T>(col: T) -> Self
109 where
110 T: Into<Cow<'static, str>>,
111 {
112 let mut window = Self::new();
113 window.add_partition_by(Expr::cust(col));
114 window
115 }
116
117 pub fn frame_start(&mut self, r#type: FrameType, start: Frame) -> &mut Self {
147 self.frame(r#type, start, None)
148 }
149
150 pub fn frame_between(&mut self, r#type: FrameType, start: Frame, end: Frame) -> &mut Self {
181 self.frame(r#type, start, Some(end))
182 }
183
184 pub fn frame(&mut self, r#type: FrameType, start: Frame, end: Option<Frame>) -> &mut Self {
186 let frame_clause = FrameClause { r#type, start, end };
187 self.frame = Some(frame_clause);
188 self
189 }
190}
191
192impl OverStatement for WindowStatement {
193 fn add_partition_by(&mut self, partition: Expr) -> &mut Self {
194 self.partition_by.push(partition);
195 self
196 }
197}
198
199#[inherent]
200impl OrderedStatement for WindowStatement {
201 pub fn add_order_by(&mut self, order: OrderExpr) -> &mut Self {
202 self.order_by.push(order);
203 self
204 }
205
206 pub fn clear_order_by(&mut self) -> &mut Self {
207 self.order_by = Vec::new();
208 self
209 }
210
211 pub fn order_by<T>(&mut self, col: T, order: Order) -> &mut Self
212 where
213 T: IntoColumnRef;
214
215 pub fn order_by_expr(&mut self, expr: Expr, order: Order) -> &mut Self;
216 pub fn order_by_customs<I, T>(&mut self, cols: I) -> &mut Self
217 where
218 T: Into<Cow<'static, str>>,
219 I: IntoIterator<Item = (T, Order)>;
220 pub fn order_by_columns<I, T>(&mut self, cols: I) -> &mut Self
221 where
222 T: IntoColumnRef,
223 I: IntoIterator<Item = (T, Order)>;
224 pub fn order_by_with_nulls<T>(
225 &mut self,
226 col: T,
227 order: Order,
228 nulls: NullOrdering,
229 ) -> &mut Self
230 where
231 T: IntoColumnRef;
232 pub fn order_by_expr_with_nulls(
233 &mut self,
234 expr: Expr,
235 order: Order,
236 nulls: NullOrdering,
237 ) -> &mut Self;
238 pub fn order_by_customs_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
239 where
240 T: Into<Cow<'static, str>>,
241 I: IntoIterator<Item = (T, Order, NullOrdering)>;
242 pub fn order_by_columns_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
243 where
244 T: IntoColumnRef,
245 I: IntoIterator<Item = (T, Order, NullOrdering)>;
246}