1use drizzle_core::Token;
2pub use drizzle_core::builder::{BuilderInit, ExecutableState, OrderByClause};
4pub use drizzle_core::{
5 OrderBy, SQL, ToSQL,
6 traits::{SQLSchema, SQLTable},
7};
8
9use crate::{common::PostgresSchemaType, traits::PostgresTable, values::PostgresValue};
11use std::{fmt::Debug, marker::PhantomData};
12
13pub mod cte;
15pub mod delete;
16pub mod insert;
17pub mod prepared;
18pub mod select;
19pub mod update;
20
21pub use cte::{CTEDefinition, CTEView};
23
24pub use delete::{DeleteInitial, DeleteReturningSet, DeleteWhereSet};
26pub use insert::{
27 Conflict, InsertInitial, InsertOnConflictSet, InsertReturningSet, InsertValuesSet,
28};
29pub use select::{
30 SelectFromSet, SelectGroupSet, SelectInitial, SelectJoinSet, SelectLimitSet, SelectOffsetSet,
31 SelectOrderSet, SelectWhereSet,
32};
33pub use update::{
34 UpdateFromSet, UpdateInitial, UpdateReturningSet, UpdateSetClauseSet, UpdateWhereSet,
35};
36
37#[derive(Debug, Clone)]
38pub struct CTEInit;
39
40impl ExecutableState for CTEInit {}
41
42#[derive(Debug, Clone, Default)]
47pub struct QueryBuilder<'a, Schema = (), State = (), Table = ()> {
48 pub sql: SQL<'a, PostgresValue<'a>>,
49 schema: PhantomData<Schema>,
50 state: PhantomData<State>,
51 table: PhantomData<Table>,
52}
53
54impl<'a, Schema, State, Table> ToSQL<'a, PostgresValue<'a>>
59 for QueryBuilder<'a, Schema, State, Table>
60{
61 fn to_sql(&self) -> SQL<'a, PostgresValue<'a>> {
62 self.sql.clone()
63 }
64}
65
66impl<'a> QueryBuilder<'a> {
67 pub const fn new<S>() -> QueryBuilder<'a, S, BuilderInit> {
69 QueryBuilder {
70 sql: SQL::empty(),
71 schema: PhantomData,
72 state: PhantomData,
73 table: PhantomData,
74 }
75 }
76}
77
78impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
79 pub fn select<T>(&self, columns: T) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
80 where
81 T: ToSQL<'a, PostgresValue<'a>>,
82 {
83 let sql = crate::helpers::select(columns);
84 select::SelectBuilder {
85 sql,
86 schema: PhantomData,
87 state: PhantomData,
88 table: PhantomData,
89 }
90 }
91
92 pub fn select_distinct<T>(
96 &self,
97 columns: T,
98 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
99 where
100 T: ToSQL<'a, PostgresValue<'a>>,
101 {
102 let sql = crate::helpers::select_distinct(columns);
103 select::SelectBuilder {
104 sql,
105 schema: PhantomData,
106 state: PhantomData,
107 table: PhantomData,
108 }
109 }
110
111 pub fn select_distinct_on<On, Columns>(
113 &self,
114 on: On,
115 columns: Columns,
116 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
117 where
118 On: ToSQL<'a, PostgresValue<'a>>,
119 Columns: ToSQL<'a, PostgresValue<'a>>,
120 {
121 let sql = crate::helpers::select_distinct_on(on, columns);
122 select::SelectBuilder {
123 sql,
124 schema: PhantomData,
125 state: PhantomData,
126 table: PhantomData,
127 }
128 }
129}
130
131impl<'a, Schema> QueryBuilder<'a, Schema, CTEInit> {
132 pub fn select<T>(&self, columns: T) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
133 where
134 T: ToSQL<'a, PostgresValue<'a>>,
135 {
136 let sql = self.sql.clone().append(crate::helpers::select(columns));
137 select::SelectBuilder {
138 sql,
139 schema: PhantomData,
140 state: PhantomData,
141 table: PhantomData,
142 }
143 }
144
145 pub fn select_distinct<T>(
147 &self,
148 columns: T,
149 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
150 where
151 T: ToSQL<'a, PostgresValue<'a>>,
152 {
153 let sql = self
154 .sql
155 .clone()
156 .append(crate::helpers::select_distinct(columns));
157 select::SelectBuilder {
158 sql,
159 schema: PhantomData,
160 state: PhantomData,
161 table: PhantomData,
162 }
163 }
164
165 pub fn select_distinct_on<On, Columns>(
167 &self,
168 on: On,
169 columns: Columns,
170 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
171 where
172 On: ToSQL<'a, PostgresValue<'a>>,
173 Columns: ToSQL<'a, PostgresValue<'a>>,
174 {
175 let sql = self
176 .sql
177 .clone()
178 .append(crate::helpers::select_distinct_on(on, columns));
179 select::SelectBuilder {
180 sql,
181 schema: PhantomData,
182 state: PhantomData,
183 table: PhantomData,
184 }
185 }
186
187 pub fn insert<Table>(
189 &self,
190 table: Table,
191 ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
192 where
193 Table: PostgresTable<'a>,
194 {
195 let sql = self.sql.clone().append(crate::helpers::insert(table));
196
197 insert::InsertBuilder {
198 sql,
199 schema: PhantomData,
200 state: PhantomData,
201 table: PhantomData,
202 }
203 }
204
205 pub fn update<Table>(
207 &self,
208 table: Table,
209 ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
210 where
211 Table: PostgresTable<'a>,
212 {
213 let sql = self.sql.clone().append(crate::helpers::update::<
214 'a,
215 Table,
216 PostgresSchemaType,
217 PostgresValue<'a>,
218 >(table));
219
220 update::UpdateBuilder {
221 sql,
222 schema: PhantomData,
223 state: PhantomData,
224 table: PhantomData,
225 }
226 }
227
228 pub fn delete<Table>(
230 &self,
231 table: Table,
232 ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
233 where
234 Table: PostgresTable<'a>,
235 {
236 let sql = self.sql.clone().append(crate::helpers::delete::<
237 'a,
238 Table,
239 PostgresSchemaType,
240 PostgresValue<'a>,
241 >(table));
242
243 delete::DeleteBuilder {
244 sql,
245 schema: PhantomData,
246 state: PhantomData,
247 table: PhantomData,
248 }
249 }
250
251 pub fn with<C>(&self, cte: C) -> QueryBuilder<'a, Schema, CTEInit>
252 where
253 C: CTEDefinition<'a>,
254 {
255 let sql = self
256 .sql
257 .clone()
258 .push(Token::COMMA)
259 .append(cte.cte_definition());
260 QueryBuilder {
261 sql,
262 schema: PhantomData,
263 state: PhantomData,
264 table: PhantomData,
265 }
266 }
267}
268
269impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
270 pub fn insert<Table>(
271 &self,
272 table: Table,
273 ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
274 where
275 Table: PostgresTable<'a>,
276 {
277 let sql = crate::helpers::insert(table);
278
279 insert::InsertBuilder {
280 sql,
281 schema: PhantomData,
282 state: PhantomData,
283 table: PhantomData,
284 }
285 }
286
287 pub fn update<Table>(
288 &self,
289 table: Table,
290 ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
291 where
292 Table: PostgresTable<'a>,
293 {
294 let sql = crate::helpers::update::<'a, Table, PostgresSchemaType, PostgresValue<'a>>(table);
295
296 update::UpdateBuilder {
297 sql,
298 schema: PhantomData,
299 state: PhantomData,
300 table: PhantomData,
301 }
302 }
303
304 pub fn delete<Table>(
305 &self,
306 table: Table,
307 ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
308 where
309 Table: PostgresTable<'a>,
310 {
311 let sql = crate::helpers::delete::<'a, Table, PostgresSchemaType, PostgresValue<'a>>(table);
312
313 delete::DeleteBuilder {
314 sql,
315 schema: PhantomData,
316 state: PhantomData,
317 table: PhantomData,
318 }
319 }
320
321 pub fn with<C>(&self, cte: C) -> QueryBuilder<'a, Schema, CTEInit>
322 where
323 C: CTEDefinition<'a>,
324 {
325 let sql = SQL::from(Token::WITH).append(cte.cte_definition());
326 QueryBuilder {
327 sql,
328 schema: PhantomData,
329 state: PhantomData,
330 table: PhantomData,
331 }
332 }
333}
334
335#[cfg(test)]
337mod tests {
338 use super::*;
339
340 #[test]
341 fn test_query_builder_new() {
342 let qb = QueryBuilder::new::<()>();
343 let sql = qb.to_sql();
344 assert_eq!(sql.sql(), "");
345 assert_eq!(sql.params().count(), 0);
346 }
347
348 #[test]
349 fn test_builder_init_type() {
350 let _state = BuilderInit;
351 }
352}