vantage_table/table/impls/
selectable.rs1use vantage_core::Result;
2use vantage_expressions::traits::selectable::Selectable;
3use vantage_expressions::{Expression, Expressive, SelectableDataSource, expr_any};
4use vantage_types::Entity;
5
6use crate::{
7 column::core::ColumnType, table::Table, traits::column_like::ColumnLike,
8 traits::table_source::TableSource,
9};
10
11impl<T, E> Table<T, E>
12where
13 T: SelectableDataSource<T::Value, T::Condition> + TableSource,
14 T::Value: From<String>, E: Entity<T::Value>,
16{
17 pub fn select(&self) -> T::Select {
19 let mut select = self.data_source.select();
20
21 select.add_source(self.table_name(), None);
23
24 for column in self.columns.values() {
26 if let Some(expr_fn) = self.expressions.get(column.name()) {
27 let expr = expr_fn(self);
28 self.data_source.add_select_column(
29 &mut select,
30 expr_any!("({})", (expr)),
31 Some(column.name()),
32 );
33 } else if let Some(alias) = column.alias() {
34 let expr = self.data_source.expr(column.name(), vec![]);
35 self.data_source
36 .add_select_column(&mut select, expr, Some(alias));
37 } else {
38 select.add_field(column.name());
39 }
40 }
41
42 for (name, expr_fn) in &self.expressions {
44 if !self.columns.contains_key(name) {
45 let expr = expr_fn(self);
46 self.data_source.add_select_column(
47 &mut select,
48 expr_any!("({})", (expr)),
49 Some(name),
50 );
51 }
52 }
53
54 for condition in self.conditions.values() {
56 select.add_where_condition(condition.clone());
57 }
58
59 for (expr, direction) in self.order_by.values() {
61 let order = match direction {
62 crate::sorting::SortDirection::Ascending => vantage_expressions::Order::Asc,
63 crate::sorting::SortDirection::Descending => vantage_expressions::Order::Desc,
64 };
65 select.add_order_by(expr.clone(), order);
66 }
67
68 if let Some(pagination) = &self.pagination {
70 select.set_limit(Some(pagination.limit()), Some(pagination.skip()));
71 }
72
73 select
74 }
75 pub async fn get_count(&self) -> Result<i64> {
77 self.data_source.get_table_count(self).await
78 }
79
80 pub async fn get_sum(&self, column: &T::Column<T::AnyType>) -> Result<T::Value> {
82 self.data_source.get_table_sum(self, column).await
83 }
84
85 pub async fn get_max(&self, column: &T::Column<T::AnyType>) -> Result<T::Value> {
87 self.data_source.get_table_max(self, column).await
88 }
89
90 pub async fn get_min(&self, column: &T::Column<T::AnyType>) -> Result<T::Value> {
92 self.data_source.get_table_min(self, column).await
93 }
94
95 pub fn get_count_query(&self) -> Expression<T::Value> {
97 self.select().as_count()
98 }
99
100 pub fn get_sum_query<Type>(&self, column: &T::Column<Type>) -> Expression<T::Value>
102 where
103 Type: ColumnType,
104 T::Column<Type>: Expressive<T::Value>,
105 {
106 self.select().as_sum(column.expr())
107 }
108}
109
110impl<T, E> Table<T, E>
112where
113 T: SelectableDataSource<serde_json::Value, T::Condition>
114 + TableSource<Value = serde_json::Value>
115 + vantage_expressions::traits::datasource::ExprDataSource<serde_json::Value>,
116 T::Value: From<String>,
117 E: Entity<serde_json::Value>,
118{
119 pub async fn get_count_via_query(&self) -> Result<i64> {
121 let count_query = self.get_count_query();
122 let result = self.data_source.execute(&count_query).await?;
123
124 if let Some(count) = result.get("count").and_then(|v| v.as_i64()) {
126 Ok(count)
127 } else if let Some(count) = result.as_i64() {
128 Ok(count)
129 } else {
130 Ok(0)
131 }
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138 use crate::mocks::mock_table_source::MockTableSource;
139 use serde_json::json;
140 use vantage_expressions::mocks::datasource::MockSelectableDataSource;
141 use vantage_expressions::traits::datasource::ExprDataSource;
142
143 #[tokio::test]
144 async fn test_selectable_functionality() {
145 let mock_select_source = MockSelectableDataSource::new(json!([
146 {"id": "1", "name": "Alice", "age": 30},
147 {"id": "2", "name": "Bob", "age": 25}
148 ]));
149
150 let mock_query_source = vantage_expressions::mocks::mock_builder::new()
151 .on_exact_select("SELECT COUNT(*) FROM \"users\"", json!(42));
152
153 let table = MockTableSource::new()
154 .with_data(
155 "users",
156 vec![
157 json!({"id": "1", "name": "Alice", "age": 30}),
158 json!({"id": "2", "name": "Bob", "age": 25}),
159 ],
160 )
161 .await
162 .with_select_source(mock_select_source)
163 .with_query_source(mock_query_source);
164 let table = Table::<_, vantage_types::EmptyEntity>::new("users", table);
165
166 let select = table.select();
168 assert_eq!(select.source(), Some("users"));
169
170 let query_expr: vantage_expressions::Expression<serde_json::Value> = select.into();
172 assert_eq!(query_expr.preview(), "SELECT * FROM users");
173
174 let count_query = table.get_count_query();
176 assert_eq!(count_query.preview(), "SELECT COUNT(*) FROM \"users\"");
177
178 let count = table.get_count_via_query().await.unwrap();
186 assert_eq!(count, 42);
187 }
188
189 #[tokio::test]
190 #[should_panic(expected = "MockTableSource select source not set")]
191 async fn test_panics_without_select_source() {
192 let table = Table::<_, vantage_types::EmptyEntity>::new("users", MockTableSource::new());
193 let _select = table.select();
194 }
195
196 #[tokio::test]
197 #[should_panic(expected = "MockTableSource query source not set")]
198 async fn test_panics_without_query_source() {
199 let table = Table::<_, vantage_types::EmptyEntity>::new("users", MockTableSource::new());
200 let query = table.data_source().expr("SELECT COUNT(*)", vec![]);
201 let _result = table.data_source().execute(&query).await;
202 }
203}