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 {}