1use crate::expr::{Expr, TableRef};
2use crate::join::Join;
3use crate::order::OrderBy;
4use crate::pagination::Pagination;
5use crate::predicate::Predicate;
6use sql_orm_core::{Entity, EntityColumn};
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct SelectProjection {
10 pub expr: Expr,
11 pub alias: Option<&'static str>,
12}
13
14impl SelectProjection {
15 pub fn column<E: Entity>(column: EntityColumn<E>) -> Self {
16 let alias = column.column_name();
17 Self {
18 expr: Expr::from(column),
19 alias: Some(alias),
20 }
21 }
22
23 pub fn expr(expr: Expr) -> Self {
24 let alias = match &expr {
25 Expr::Column(column) => Some(column.column_name),
26 _ => None,
27 };
28
29 Self { expr, alias }
30 }
31
32 pub fn expr_as(expr: Expr, alias: &'static str) -> Self {
33 Self {
34 expr,
35 alias: Some(alias),
36 }
37 }
38}
39
40impl<E: Entity> From<EntityColumn<E>> for SelectProjection {
41 fn from(value: EntityColumn<E>) -> Self {
42 Self::column(value)
43 }
44}
45
46impl From<Expr> for SelectProjection {
47 fn from(value: Expr) -> Self {
48 Self::expr(value)
49 }
50}
51
52#[derive(Debug, Clone, PartialEq)]
53pub struct SelectQuery {
54 pub from: TableRef,
55 pub joins: Vec<Join>,
56 pub projection: Vec<SelectProjection>,
57 pub predicate: Option<Predicate>,
58 pub order_by: Vec<OrderBy>,
59 pub pagination: Option<Pagination>,
60}
61
62impl SelectQuery {
63 pub fn from_entity<E: Entity>() -> Self {
64 Self {
65 from: TableRef::for_entity::<E>(),
66 joins: Vec::new(),
67 projection: Vec::new(),
68 predicate: None,
69 order_by: Vec::new(),
70 pagination: None,
71 }
72 }
73
74 pub fn from_entity_as<E: Entity>(alias: &'static str) -> Self {
75 Self {
76 from: TableRef::for_entity_as::<E>(alias),
77 joins: Vec::new(),
78 projection: Vec::new(),
79 predicate: None,
80 order_by: Vec::new(),
81 pagination: None,
82 }
83 }
84
85 pub fn select<P, I>(mut self, projection: I) -> Self
86 where
87 P: Into<SelectProjection>,
88 I: IntoIterator<Item = P>,
89 {
90 self.projection = projection.into_iter().map(Into::into).collect();
91 self
92 }
93
94 pub fn filter(mut self, predicate: Predicate) -> Self {
95 self.predicate = Some(match self.predicate.take() {
96 Some(existing) => Predicate::and(vec![existing, predicate]),
97 None => predicate,
98 });
99 self
100 }
101
102 pub fn join(mut self, join: Join) -> Self {
103 self.joins.push(join);
104 self
105 }
106
107 pub fn inner_join<E: Entity>(self, on: Predicate) -> Self {
108 self.join(Join::inner_entity::<E>(on))
109 }
110
111 pub fn left_join<E: Entity>(self, on: Predicate) -> Self {
112 self.join(Join::left_entity::<E>(on))
113 }
114
115 pub fn inner_join_as<E: Entity>(self, alias: &'static str, on: Predicate) -> Self {
116 self.join(Join::inner_entity_as::<E>(alias, on))
117 }
118
119 pub fn left_join_as<E: Entity>(self, alias: &'static str, on: Predicate) -> Self {
120 self.join(Join::left_entity_as::<E>(alias, on))
121 }
122
123 pub fn order_by(mut self, order: OrderBy) -> Self {
124 self.order_by.push(order);
125 self
126 }
127
128 pub fn paginate(mut self, pagination: Pagination) -> Self {
129 self.pagination = Some(pagination);
130 self
131 }
132}
133
134#[derive(Debug, Clone, PartialEq)]
135pub struct CountQuery {
136 pub from: TableRef,
137 pub predicate: Option<Predicate>,
138}
139
140impl CountQuery {
141 pub fn from_entity<E: Entity>() -> Self {
142 Self {
143 from: TableRef::for_entity::<E>(),
144 predicate: None,
145 }
146 }
147
148 pub fn from_entity_as<E: Entity>(alias: &'static str) -> Self {
149 Self {
150 from: TableRef::for_entity_as::<E>(alias),
151 predicate: None,
152 }
153 }
154
155 pub fn filter(mut self, predicate: Predicate) -> Self {
156 self.predicate = Some(match self.predicate.take() {
157 Some(existing) => Predicate::and(vec![existing, predicate]),
158 None => predicate,
159 });
160 self
161 }
162}
163
164#[derive(Debug, Clone, PartialEq)]
165pub struct ExistsQuery {
166 pub from: TableRef,
167 pub joins: Vec<Join>,
168 pub predicate: Option<Predicate>,
169}
170
171impl ExistsQuery {
172 pub fn from_entity<E: Entity>() -> Self {
173 Self {
174 from: TableRef::for_entity::<E>(),
175 joins: Vec::new(),
176 predicate: None,
177 }
178 }
179
180 pub fn from_entity_as<E: Entity>(alias: &'static str) -> Self {
181 Self {
182 from: TableRef::for_entity_as::<E>(alias),
183 joins: Vec::new(),
184 predicate: None,
185 }
186 }
187
188 pub fn filter(mut self, predicate: Predicate) -> Self {
189 self.predicate = Some(match self.predicate.take() {
190 Some(existing) => Predicate::and(vec![existing, predicate]),
191 None => predicate,
192 });
193 self
194 }
195
196 pub fn join(mut self, join: Join) -> Self {
197 self.joins.push(join);
198 self
199 }
200
201 pub fn inner_join<E: Entity>(self, on: Predicate) -> Self {
202 self.join(Join::inner_entity::<E>(on))
203 }
204
205 pub fn left_join<E: Entity>(self, on: Predicate) -> Self {
206 self.join(Join::left_entity::<E>(on))
207 }
208
209 pub fn inner_join_as<E: Entity>(self, alias: &'static str, on: Predicate) -> Self {
210 self.join(Join::inner_entity_as::<E>(alias, on))
211 }
212
213 pub fn left_join_as<E: Entity>(self, alias: &'static str, on: Predicate) -> Self {
214 self.join(Join::left_entity_as::<E>(alias, on))
215 }
216}