1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2pub enum AggregationType {
3 Sum,
4 Count,
5}
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum AggregationFrequency {
9 Daily,
10 Weekly,
11 Monthly,
12 Yearly,
13}
14
15#[derive(Debug, Clone)]
16pub struct AggregationGroup {
17 source: String,
18 destination: String,
19 source_derived_from: Option<String>,
20}
21
22impl AggregationGroup {
23 pub fn new<S: Into<String>>(source: S, destination: S, source_derived_from: Option<S>) -> Self {
24 Self {
25 source: source.into(),
26 destination: destination.into(),
27 source_derived_from: source_derived_from.map(|s| s.into()),
28 }
29 }
30
31 pub fn source(&self) -> &str {
32 &self.source
33 }
34
35 pub fn destination(&self) -> &str {
36 &self.destination
37 }
38
39 pub fn source_derived_from(&self) -> Option<&str> {
40 self.source_derived_from.as_deref()
41 }
42}
43
44#[derive(Debug, Clone)]
45pub struct AggregationColumn {
46 aggregation_type: AggregationType,
47 source_column: String,
48 destination_column: String,
49}
50
51impl AggregationColumn {
52 pub fn new<S: Into<String>>(
53 aggregation_type: AggregationType,
54 source_column: S,
55 destination_column: S,
56 ) -> Self {
57 Self {
58 aggregation_type,
59 source_column: source_column.into(),
60 destination_column: destination_column.into(),
61 }
62 }
63
64 pub fn aggregation_type(&self) -> AggregationType {
65 self.aggregation_type
66 }
67 pub fn source_column(&self) -> &str {
68 &self.source_column
69 }
70 pub fn destination_column(&self) -> &str {
71 &self.destination_column
72 }
73}
74
75#[derive(Debug, Clone)]
76pub struct Aggregation {
77 destination_table: String,
78 date_column: String,
79 criteria: Option<String>,
80 time_stamp_column: String,
81 aggregation_frequency: AggregationFrequency,
82 aggregation_columns: Vec<AggregationColumn>,
83 aggregation_groups: Vec<AggregationGroup>,
84}
85
86impl Aggregation {
87 #[allow(clippy::too_many_arguments)]
88 pub fn new<S: Into<String>>(
89 destination_table: S,
90 date_column: S,
91 criteria: Option<S>,
92 time_stamp_column: S,
93 aggregation_frequency: AggregationFrequency,
94 aggregation_columns: Vec<AggregationColumn>,
95 aggregation_groups: Vec<AggregationGroup>,
96 ) -> Self {
97 Self {
98 destination_table: destination_table.into(),
99 date_column: date_column.into(),
100 criteria: criteria.map(|s| s.into()),
101 time_stamp_column: time_stamp_column.into(),
102 aggregation_frequency,
103 aggregation_columns,
104 aggregation_groups,
105 }
106 }
107
108 pub fn destination_table(&self) -> &str {
109 &self.destination_table
110 }
111
112 pub fn date_column(&self) -> &str {
113 &self.date_column
114 }
115
116 pub fn criteria(&self) -> Option<&str> {
117 self.criteria.as_deref()
118 }
119
120 pub fn time_stamp_column(&self) -> &str {
121 &self.time_stamp_column
122 }
123
124 pub fn aggregation_frequency(&self) -> AggregationFrequency {
125 self.aggregation_frequency
126 }
127
128 pub fn aggregation_groups(&self) -> &Vec<AggregationGroup> {
129 &self.aggregation_groups
130 }
131
132 pub fn aggregation_columns(&self) -> &Vec<AggregationColumn> {
133 &self.aggregation_columns
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn aggregation_group_new_and_getters() {
143 let g = AggregationGroup::new("src", "dest", Some("derived"));
144 assert_eq!(g.source(), "src");
145 assert_eq!(g.destination(), "dest");
146 assert_eq!(g.source_derived_from().unwrap(), "derived");
147 }
148
149 #[test]
150 fn aggregation_column_new_and_getters() {
151 let c = AggregationColumn::new(AggregationType::Sum, "s_col", "d_col");
152 assert_eq!(c.aggregation_type(), AggregationType::Sum);
153 assert_eq!(c.source_column(), "s_col");
154 assert_eq!(c.destination_column(), "d_col");
155 }
156
157 #[test]
158 fn aggregation_new_and_getters() {
159 let cols = vec![
160 AggregationColumn::new(AggregationType::Sum, "a", "a_sum"),
161 AggregationColumn::new(AggregationType::Count, "b", "b_cnt"),
162 ];
163 let groups = vec![
164 AggregationGroup::new("src1", "dst1", Some("from1")),
165 AggregationGroup::new("src2", "dst2", Some("from2")),
166 ];
167 let aggr = Aggregation::new(
168 "dest_table",
169 "date_col",
170 Some("criteria"),
171 "ts_col",
172 AggregationFrequency::Monthly,
173 cols.clone(),
174 groups.clone(),
175 );
176
177 assert_eq!(aggr.destination_table(), "dest_table");
178 assert_eq!(aggr.date_column(), "date_col");
179 assert_eq!(aggr.criteria().unwrap(), "criteria");
180 assert_eq!(aggr.time_stamp_column(), "ts_col");
181 assert_eq!(aggr.aggregation_frequency(), AggregationFrequency::Monthly);
182 assert_eq!(aggr.aggregation_columns().len(), 2);
183 assert_eq!(aggr.aggregation_groups().len(), 2);
184
185 assert_eq!(aggr.aggregation_columns()[0].source_column(), "a");
187 assert_eq!(
188 aggr.aggregation_columns()[1].aggregation_type(),
189 AggregationType::Count
190 );
191 assert_eq!(aggr.aggregation_groups()[0].destination(), "dst1");
192 assert_eq!(aggr.aggregation_groups()[1].source_derived_from().unwrap(), "from2");
193
194 assert_eq!(aggr.aggregation_columns().len(), cols.len());
196 assert_eq!(aggr.aggregation_groups().len(), groups.len());
197 }
198}