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