typed_sql/query/mod.rs
1use crate::table::{Table, TableQueryable};
2use crate::types::bind::{Binder, Binding};
3use crate::ToSql;
4
5pub mod delete;
6use delete::Delete;
7
8pub mod filter;
9use filter::Filter;
10pub use filter::Filterable;
11
12pub mod insert;
13pub use insert::Insertable;
14use insert::{InsertSelect, InsertStatement, Values};
15
16pub mod predicate;
17pub use predicate::Predicate;
18use predicate::{And, Or};
19
20pub mod prepare;
21use prepare::Prepare;
22
23pub mod select;
24use select::queryable::{Count, WildCard, WriteQueryable};
25use select::{GroupBy, GroupOrder, Limit, Order, OrderBy, SelectStatement, Selectable};
26pub use select::{Join, Joined, Queryable, Select};
27
28pub mod update;
29use update::{Update, UpdateSet};
30
31pub trait Query: Sized {
32 /// # Examples
33 /// ```
34 /// use typed_sql::{Binding, Query, Table, ToSql};
35 ///
36 /// #[derive(Table)]
37 /// struct Post {
38 /// id: i64,
39 /// content: String
40 /// }
41 ///
42 /// #[derive(Binding)]
43 /// struct PostBinding {
44 /// id: i64
45 /// }
46 ///
47 /// let stmt = PostBinding::prepare("postplan", |binds| {
48 /// Post::table()
49 /// .select()
50 /// .filter(|post| post.id.eq(binds.id))
51 /// });
52 ///
53 /// assert_eq!(
54 /// stmt.to_sql(),
55 /// "PREPARE postplan AS SELECT * FROM posts WHERE posts.id = $1;"
56 /// );
57 /// ```
58 fn prepare<F, S>(name: &str, f: F) -> Prepare<Self, S>
59 where
60 Self: Binding,
61 F: FnOnce(Self::Bindings) -> S,
62 S: ToSql,
63 {
64 let bindings = Self::bindings(&mut Binder::default());
65 Prepare::new(name, f(bindings))
66 }
67
68 /// # Examples
69 /// ```
70 /// use typed_sql::{Query, Table, ToSql};
71 ///
72 /// #[derive(Table)]
73 /// struct Post {
74 /// content: String
75 /// }
76 ///
77 /// let stmt = Post::table().select().filter(|p| p.content.eq("foo"));
78 ///
79 /// assert_eq!(
80 /// stmt.to_sql_unchecked(),
81 /// "SELECT * FROM posts WHERE posts.content = 'foo';"
82 /// );
83 /// ```
84 fn select(self) -> SelectStatement<Self, WildCard>
85 where
86 Self: Selectable,
87 {
88 self.query(WildCard)
89 }
90
91 /// # Examples
92 /// ```
93 /// use typed_sql::{Query, Queryable, Table, ToSql};
94 ///
95 /// #[derive(Table)]
96 /// struct Post {
97 /// id: i64,
98 /// content: String
99 /// }
100 ///
101 /// #[derive(Queryable)]
102 /// struct PostQuery {
103 /// content: String
104 /// }
105 ///
106 /// let stmt = Post::table().query(PostQuery::queryable());
107 ///
108 /// assert_eq!(
109 /// stmt.to_sql_unchecked(),
110 /// "SELECT content FROM posts;"
111 /// );
112 /// ```
113 fn query<Q>(self, query: Q) -> SelectStatement<Self, Q>
114 where
115 Self: Selectable,
116 Q: WriteQueryable,
117 {
118 SelectStatement::new(self, query)
119 }
120
121 /// # Examples
122 /// ```
123 /// use typed_sql::{Query, Table, ToSql};
124 ///
125 /// #[derive(Table)]
126 /// struct Post {
127 /// content: Option<String>
128 /// }
129 ///
130 /// let stmt = Post::table().count(|post| post.content);
131 ///
132 /// assert_eq!(stmt.to_sql(), "SELECT COUNT(posts.content) FROM posts;");
133 /// ```
134 /// ## Wildcard
135 /// ```
136 /// use typed_sql::{Query, Table, ToSql};
137 ///
138 /// #[derive(Table)]
139 /// struct Post {}
140 ///
141 /// let stmt = Post::table().count(|_| {});
142 ///
143 /// assert_eq!(stmt.to_sql(), "SELECT COUNT(*) FROM posts;");
144 /// ```
145 fn count<F, T>(self, f: F) -> SelectStatement<Self, Count<T>>
146 where
147 Self: Selectable,
148 F: FnOnce(Self::Fields) -> T,
149 Count<T>: WriteQueryable,
150 {
151 self.query(Count::new(f(Default::default())))
152 }
153
154 /// ```
155 /// use typed_sql::{Insertable, Query, Table, ToSql};
156 ///
157 /// #[derive(Table)]
158 /// struct User {
159 /// id: i64,
160 /// name: String
161 /// }
162 ///
163 /// #[derive(Insertable)]
164 /// struct UserInsert {
165 /// name: &'static str
166 /// }
167 ///
168 /// let stmt = User::table().insert(UserInsert { name: "Matt" });
169 ///
170 /// assert_eq!(
171 /// stmt.to_sql_unchecked(),
172 /// "INSERT INTO users(name) VALUES ('Matt');"
173 /// );
174 /// ```
175 fn insert<I>(self, value: I) -> InsertStatement<Self::Table, I>
176 where
177 Self: TableQueryable,
178 I: Insertable,
179 {
180 InsertStatement::new(value)
181 }
182
183 fn insert_values<I>(self, values: I) -> InsertStatement<Self::Table, Values<I>>
184 where
185 Self: TableQueryable,
186 I: IntoIterator + Clone,
187 I::Item: Insertable,
188 {
189 InsertStatement::new(Values::new(values))
190 }
191
192 fn insert_select<S, I>(self, select: S) -> InsertStatement<Self::Table, InsertSelect<S, I>>
193 where
194 Self: TableQueryable,
195 S: Select,
196 I: Insertable,
197 {
198 InsertStatement::new(InsertSelect::new(select))
199 }
200
201 /// ```
202 /// use typed_sql::{Query, Table, ToSql};
203 ///
204 /// #[derive(Table)]
205 /// struct Post {
206 /// id: i64,
207 /// name: String
208 /// }
209 ///
210 /// let stmt = Post::table()
211 /// .update(|p| p.id.eq(2).and(p.name.eq("foo")))
212 /// .filter(|p| p.id.eq(1));
213 ///
214 /// assert_eq!(
215 /// stmt.to_sql_unchecked(),
216 /// "UPDATE posts \
217 /// SET posts.id = 2,posts.name = 'foo' \
218 /// WHERE posts.id = 1;"
219 /// );
220 /// ```
221 fn update<F, S>(self, f: F) -> Update<Self::Table, S>
222 where
223 Self: TableQueryable,
224 F: FnOnce(<Self::Table as Table>::Fields) -> S,
225 S: UpdateSet,
226 {
227 Update::new(f(Default::default()))
228 }
229
230 /// ```
231 /// use typed_sql::{Query, Table, ToSql};
232 ///
233 /// #[derive(Table)]
234 /// struct Post {
235 /// id: i64
236 /// }
237 ///
238 /// let stmt = Post::table().delete().filter(|p| p.id.eq(2));
239 ///
240 /// assert_eq!(stmt.to_sql_unchecked(), "DELETE FROM posts WHERE posts.id = 2;");
241 /// ```
242 fn delete(self) -> Delete<Self::Table>
243 where
244 Self: TableQueryable,
245 {
246 Delete::new()
247 }
248
249 fn filter<F, P>(self, f: F) -> Filter<Self, P>
250 where
251 Self: Filterable,
252 F: FnOnce(Self::Fields) -> P,
253 {
254 Filter::new(self, f(Default::default()))
255 }
256
257 /// ```
258 /// use typed_sql::{Query, Table, ToSql};
259 ///
260 /// #[derive(Table)]
261 /// struct User {
262 /// id: i64
263 /// }
264 ///
265 /// let stmt = User::table().select().filter(|user| user.id.neq(2).and(user.id.lt(5)));
266 ///
267 /// assert_eq!(
268 /// stmt.to_sql_unchecked(),
269 /// "SELECT * FROM users WHERE users.id != 2 AND users.id < 5;"
270 /// );
271 /// ```
272 fn and<P>(self, predicate: P) -> And<Self, P>
273 where
274 Self: Predicate,
275 P: Predicate,
276 {
277 And {
278 head: self,
279 tail: predicate,
280 }
281 }
282
283 /// ```
284 /// use typed_sql::{Query, Table, ToSql};
285 ///
286 /// #[derive(Table)]
287 /// struct User {
288 /// id: i64
289 /// }
290 ///
291 /// let stmt = User::table()
292 /// .select()
293 /// .filter(|user| user.id.eq(1).or(user.id.eq(3)));
294 ///
295 /// assert_eq!(
296 /// stmt.to_sql_unchecked(),
297 /// "SELECT * FROM users WHERE users.id = 1 OR users.id = 3;"
298 /// );
299 fn or<P>(self, predicate: P) -> Or<Self, P>
300 where
301 Self: Predicate,
302 P: Predicate,
303 {
304 Or {
305 head: self,
306 tail: predicate,
307 }
308 }
309
310 /// # Examples
311 /// ```
312 /// use typed_sql::{Table, ToSql, Query};
313 ///
314 /// #[derive(Table)]
315 /// struct User {
316 /// id: i64
317 /// }
318 ///
319 /// let stmt = User::table().select().group_by(|user| user.id);
320 ///
321 /// assert_eq!(stmt.to_sql(), "SELECT * FROM users GROUP BY users.id;");
322 /// ```
323 /// ## Multiple columns
324 /// ```
325 /// use typed_sql::{Query, Table, ToSql};
326 ///
327 /// #[derive(Table)]
328 /// struct User {
329 /// id: i64,
330 /// name: String
331 /// }
332 ///
333 /// let stmt = User::table().select().group_by(|user| user.id.then(user.name));
334 ///
335 /// assert_eq!(stmt.to_sql(), "SELECT * FROM users GROUP BY users.id,users.name;");
336 /// ```
337 fn group_by<F, O>(self, f: F) -> GroupBy<Self, O>
338 where
339 Self: Select,
340 F: FnOnce(<Self::Selectable as Selectable>::Fields) -> O,
341 O: GroupOrder,
342 {
343 GroupBy::new(self, f(Default::default()))
344 }
345
346 /// # Examples
347 /// ```
348 /// use typed_sql::{Query, Table, ToSql};
349 ///
350 /// #[derive(Table)]
351 /// struct User {
352 /// id: i64,
353 /// name: String
354 /// }
355 ///
356 /// let stmt = User::table().select().order_by(|user| user.id);
357 ///
358 /// assert_eq!(stmt.to_sql(), "SELECT * FROM users ORDER BY users.id;");
359 /// ```
360 /// ## Direction
361 /// ```
362 /// use typed_sql::{Query, Table, ToSql};
363 ///
364 /// #[derive(Table)]
365 /// struct User {
366 /// id: i64
367 /// }
368 ///
369 /// let stmt = User::table().select().order_by(|user| user.id.ascending());
370 ///
371 /// assert_eq!(stmt.to_sql(), "SELECT * FROM users ORDER BY users.id ASC;");
372 /// ```
373 /// ## Multiple columns
374 /// ```
375 /// use typed_sql::{Query, Table, ToSql};
376 ///
377 /// #[derive(Table)]
378 /// struct User {
379 /// id: i64,
380 /// name: String
381 /// }
382 ///
383 /// let stmt = User::table().select()
384 /// .order_by(|user| user.id.ascending().then(user.name.descending()));
385 ///
386 /// assert_eq!(stmt.to_sql(), "SELECT * FROM users ORDER BY users.id ASC,users.name DESC;");
387 /// ```
388 fn order_by<F, O>(self, f: F) -> OrderBy<Self, O>
389 where
390 Self: Select,
391 F: FnOnce(<Self::Selectable as Selectable>::Fields) -> O,
392 O: Order,
393 {
394 OrderBy::new(self, f(Default::default()))
395 }
396
397 fn limit(self, limit: usize) -> Limit<Self>
398 where
399 Self: Select,
400 {
401 Limit::new(self, limit)
402 }
403}
404
405impl<T> Query for T {}