drizzle_postgres/builder.rs
1//! Query builders for `PostgreSQL` statements.
2//!
3//! [`QueryBuilder`] builds `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `WITH` and
4//! `REFRESH MATERIALIZED VIEW` statements as SQL text plus bound parameters,
5//! without a connection. The driver integrations in the `drizzle` crate wrap
6//! it to run the statements. Each statement kind has a submodule with its
7//! builder states.
8
9use drizzle_core::Token;
10// Re-export common enums and traits from core
11pub use drizzle_core::builder::{BuilderInit, ExecutableState};
12pub use drizzle_core::{
13 OrderBy, SQL, ToSQL,
14 traits::{SQLSchema, SQLTable},
15};
16
17// Local imports
18use crate::{common::PostgresSchemaType, traits::PostgresTable, values::PostgresValue};
19use core::{fmt::Debug, marker::PhantomData};
20
21// Import modules - these provide specific builder types
22pub mod cte;
23pub mod delete;
24pub mod insert;
25pub mod prepared;
26pub mod refresh;
27pub mod select;
28pub mod update;
29
30// Re-export CTE types
31pub use cte::{CTEDefinition, CTEView};
32
33// Export state markers for easier use
34pub use delete::{DeleteInitial, DeleteReturningSet, DeleteWhereSet};
35pub use insert::{
36 InsertColumnsSet, InsertDoUpdateSet, InsertInitial, InsertOnConflictSet, InsertReturningSet,
37 InsertValuesSet, OnConflictBuilder,
38};
39pub use refresh::{
40 RefreshConcurrently, RefreshInitial, RefreshMaterializedView, RefreshWithNoData,
41 refresh_materialized_view,
42};
43pub use select::{
44 SelectForSet, SelectFromSet, SelectGroupSet, SelectInitial, SelectJoinSet, SelectLimitSet,
45 SelectOffsetSet, SelectOrderSet, SelectSetOpSet, SelectWhereSet,
46};
47pub use update::{
48 UpdateFromSet, UpdateInitial, UpdateReturningSet, UpdateSetClauseSet, UpdateWhereSet,
49};
50
51// Re-export SQLViewInfo for convenience when using refresh_materialized_view
52pub use drizzle_core::traits::SQLViewInfo;
53
54/// Builder state after `.with(cte)`: the next call starts the main statement.
55#[derive(Debug, Clone)]
56pub struct CTEInit;
57
58impl ExecutableState for CTEInit {
59 type Rows<R: drizzle_core::row::RowCount> = drizzle_core::row::ZeroOrMore;
60}
61
62/// Builds `PostgreSQL` statements as SQL plus bound parameters, without a connection.
63///
64/// Create one with [`QueryBuilder::new`], then start a statement with
65/// [`select`](QueryBuilder::select), [`insert`](QueryBuilder::insert),
66/// [`update`](QueryBuilder::update), [`delete`](QueryBuilder::delete) or
67/// [`with`](QueryBuilder::with). Each call returns a builder whose type
68/// tracks the clauses added so far, so out-of-order clauses (such as
69/// `.where()` before `.from()`) do not compile. Call `.to_sql()` to get the
70/// statement. The driver crates wrap this builder to run the query.
71///
72/// `Schema` is the schema type from `#[derive(PostgresSchema)]`. The other
73/// type parameters are builder state and are inferred.
74///
75/// # Examples
76///
77/// ```rust
78/// # extern crate self as drizzle;
79/// # mod _drizzle {
80/// # pub mod core { pub use drizzle_core::*; }
81/// # pub mod error { pub use drizzle_core::error::*; }
82/// # pub mod types { pub use drizzle_types::*; }
83/// # pub mod migrations { pub use drizzle_migrations::*; }
84/// # pub use drizzle_types::Dialect;
85/// # pub use drizzle_types as ddl;
86/// # pub mod postgres {
87/// # pub mod values { pub use drizzle_postgres::values::*; }
88/// # pub mod traits { pub use drizzle_postgres::traits::*; }
89/// # pub mod common { pub use drizzle_postgres::common::*; }
90/// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
91/// # pub mod builder { pub use drizzle_postgres::builder::*; }
92/// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
93/// # pub mod expr { pub use drizzle_postgres::expr::*; }
94/// # pub mod types { pub use drizzle_postgres::types::*; }
95/// # #[cfg(feature = "aws-data-api")]
96/// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
97/// # pub struct Row;
98/// # impl Row {
99/// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
100/// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
101/// # pub fn len(&self) -> usize { unimplemented!() }
102/// # }
103/// # pub mod prelude {
104/// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
105/// # pub use drizzle_postgres::attrs::*;
106/// # pub use drizzle_postgres::common::PostgresSchemaType;
107/// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
108/// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
109/// # pub use drizzle_core::*;
110/// # }
111/// # }
112/// # }
113/// # pub use _drizzle::*;
114/// # pub use const_format;
115/// # fn main() {
116/// # use drizzle::postgres::prelude::*;
117/// # use drizzle::postgres::builder::QueryBuilder;
118/// # #[PostgresTable(name = "users")]
119/// # struct User {
120/// # #[column(serial, primary)]
121/// # id: i32,
122/// # name: String,
123/// # email: Option<String>,
124/// # }
125/// # #[PostgresTable(name = "posts")]
126/// # struct Post {
127/// # #[column(serial, primary)]
128/// # id: i32,
129/// # #[column(references = User::id)]
130/// # author_id: i32,
131/// # title: String,
132/// # }
133/// # #[derive(PostgresSchema)]
134/// # struct Schema {
135/// # user: User,
136/// # post: Post,
137/// # }
138/// # let db = QueryBuilder::new::<Schema>();
139/// # let Schema { user, post } = Schema::new();
140/// use drizzle::core::expr::eq;
141///
142/// let query = db
143/// .select((user.id, user.name))
144/// .from(user)
145/// .r#where(eq(user.name, "Alice"));
146///
147/// assert_eq!(
148/// query.to_sql().sql(),
149/// r#"SELECT "users"."id", "users"."name" FROM "users" WHERE "users"."name" = $1"#
150/// );
151/// # }
152/// ```
153#[derive(Debug, Clone, Default)]
154pub struct QueryBuilder<
155 'a,
156 Schema = (),
157 State = (),
158 Table = (),
159 Marker = (),
160 Row = (),
161 Grouped = (),
162> {
163 /// The SQL built so far.
164 pub sql: SQL<'a, PostgresValue<'a>>,
165 schema: PhantomData<Schema>,
166 state: PhantomData<State>,
167 table: PhantomData<Table>,
168 marker: PhantomData<Marker>,
169 row: PhantomData<Row>,
170 grouped: PhantomData<Grouped>,
171}
172
173//------------------------------------------------------------------------------
174// QueryBuilder Implementation
175//------------------------------------------------------------------------------
176
177impl<'a, Schema, State, Table, Marker, Row, Grouped> ToSQL<'a, PostgresValue<'a>>
178 for QueryBuilder<'a, Schema, State, Table, Marker, Row, Grouped>
179{
180 fn to_sql(&self) -> SQL<'a, PostgresValue<'a>> {
181 self.sql.clone()
182 }
183}
184
185impl<'a, Schema, State, Table, Marker, Row, Grouped>
186 QueryBuilder<'a, Schema, State, Table, Marker, Row, Grouped>
187where
188 State: ExecutableState,
189{
190 /// Prepends a [sqlcommenter](https://google.github.io/sqlcommenter/) comment
191 /// to the statement.
192 ///
193 /// The text is wrapped in `/* ... */`. Any `/*` or `*/` in the input is
194 /// neutralised so it cannot end the comment early. Empty text adds nothing.
195 ///
196 /// # Examples
197 ///
198 /// ```rust
199 /// # extern crate self as drizzle;
200 /// # mod _drizzle {
201 /// # pub mod core { pub use drizzle_core::*; }
202 /// # pub mod error { pub use drizzle_core::error::*; }
203 /// # pub mod types { pub use drizzle_types::*; }
204 /// # pub mod migrations { pub use drizzle_migrations::*; }
205 /// # pub use drizzle_types::Dialect;
206 /// # pub use drizzle_types as ddl;
207 /// # pub mod postgres {
208 /// # pub mod values { pub use drizzle_postgres::values::*; }
209 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
210 /// # pub mod common { pub use drizzle_postgres::common::*; }
211 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
212 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
213 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
214 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
215 /// # pub mod types { pub use drizzle_postgres::types::*; }
216 /// # #[cfg(feature = "aws-data-api")]
217 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
218 /// # pub struct Row;
219 /// # impl Row {
220 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
221 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
222 /// # pub fn len(&self) -> usize { unimplemented!() }
223 /// # }
224 /// # pub mod prelude {
225 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
226 /// # pub use drizzle_postgres::attrs::*;
227 /// # pub use drizzle_postgres::common::PostgresSchemaType;
228 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
229 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
230 /// # pub use drizzle_core::*;
231 /// # }
232 /// # }
233 /// # }
234 /// # pub use _drizzle::*;
235 /// # pub use const_format;
236 /// # fn main() {
237 /// # use drizzle::postgres::prelude::*;
238 /// # use drizzle::postgres::builder::QueryBuilder;
239 /// # #[PostgresTable(name = "users")]
240 /// # struct User {
241 /// # #[column(serial, primary)]
242 /// # id: i32,
243 /// # name: String,
244 /// # email: Option<String>,
245 /// # }
246 /// # #[PostgresTable(name = "posts")]
247 /// # struct Post {
248 /// # #[column(serial, primary)]
249 /// # id: i32,
250 /// # #[column(references = User::id)]
251 /// # author_id: i32,
252 /// # title: String,
253 /// # }
254 /// # #[derive(PostgresSchema)]
255 /// # struct Schema {
256 /// # user: User,
257 /// # post: Post,
258 /// # }
259 /// # let db = QueryBuilder::new::<Schema>();
260 /// # let Schema { user, post } = Schema::new();
261 /// let query = db.select(user.id).from(user).comment("list-users");
262 /// assert_eq!(query.to_sql().sql(), r#"/*list-users*/ SELECT "users"."id" FROM "users""#);
263 /// # }
264 /// ```
265 #[must_use]
266 pub fn comment(mut self, text: impl AsRef<str>) -> Self {
267 let fragment = drizzle_core::sql::comment::<PostgresValue<'a>>(text);
268 if fragment.chunks.is_empty() {
269 return self;
270 }
271 let existing = core::mem::replace(&mut self.sql, fragment);
272 self.sql.append_mut(existing);
273 self
274 }
275
276 /// Prepends a key-value [sqlcommenter](https://google.github.io/sqlcommenter/)
277 /// comment to the statement.
278 ///
279 /// Each pair renders as `key='value'`, URL-encoded. Pairs are sorted by
280 /// key, joined with `,` and wrapped in `/* ... */`. Pairs with an empty
281 /// value are skipped; if none remain, nothing is added.
282 ///
283 /// # Examples
284 ///
285 /// ```rust
286 /// # extern crate self as drizzle;
287 /// # mod _drizzle {
288 /// # pub mod core { pub use drizzle_core::*; }
289 /// # pub mod error { pub use drizzle_core::error::*; }
290 /// # pub mod types { pub use drizzle_types::*; }
291 /// # pub mod migrations { pub use drizzle_migrations::*; }
292 /// # pub use drizzle_types::Dialect;
293 /// # pub use drizzle_types as ddl;
294 /// # pub mod postgres {
295 /// # pub mod values { pub use drizzle_postgres::values::*; }
296 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
297 /// # pub mod common { pub use drizzle_postgres::common::*; }
298 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
299 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
300 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
301 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
302 /// # pub mod types { pub use drizzle_postgres::types::*; }
303 /// # #[cfg(feature = "aws-data-api")]
304 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
305 /// # pub struct Row;
306 /// # impl Row {
307 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
308 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
309 /// # pub fn len(&self) -> usize { unimplemented!() }
310 /// # }
311 /// # pub mod prelude {
312 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
313 /// # pub use drizzle_postgres::attrs::*;
314 /// # pub use drizzle_postgres::common::PostgresSchemaType;
315 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
316 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
317 /// # pub use drizzle_core::*;
318 /// # }
319 /// # }
320 /// # }
321 /// # pub use _drizzle::*;
322 /// # pub use const_format;
323 /// # fn main() {
324 /// # use drizzle::postgres::prelude::*;
325 /// # use drizzle::postgres::builder::QueryBuilder;
326 /// # #[PostgresTable(name = "users")]
327 /// # struct User {
328 /// # #[column(serial, primary)]
329 /// # id: i32,
330 /// # name: String,
331 /// # email: Option<String>,
332 /// # }
333 /// # #[PostgresTable(name = "posts")]
334 /// # struct Post {
335 /// # #[column(serial, primary)]
336 /// # id: i32,
337 /// # #[column(references = User::id)]
338 /// # author_id: i32,
339 /// # title: String,
340 /// # }
341 /// # #[derive(PostgresSchema)]
342 /// # struct Schema {
343 /// # user: User,
344 /// # post: Post,
345 /// # }
346 /// # let db = QueryBuilder::new::<Schema>();
347 /// # let Schema { user, post } = Schema::new();
348 /// let query = db
349 /// .select(user.id)
350 /// .from(user)
351 /// .comment_tags([("route", "/users"), ("action", "list")]);
352 /// let sql = query.to_sql().sql();
353 /// assert!(sql.starts_with("/*action='list',route='%2Fusers'*/"));
354 /// # }
355 /// ```
356 #[must_use]
357 pub fn comment_tags<I, K, V>(mut self, pairs: I) -> Self
358 where
359 I: IntoIterator<Item = (K, V)>,
360 K: AsRef<str>,
361 V: AsRef<str>,
362 {
363 let fragment = drizzle_core::sql::comment_tags::<PostgresValue<'a>, _, _, _>(pairs);
364 if fragment.chunks.is_empty() {
365 return self;
366 }
367 let existing = core::mem::replace(&mut self.sql, fragment);
368 self.sql.append_mut(existing);
369 self
370 }
371}
372
373impl<'a> QueryBuilder<'a> {
374 /// Creates a query builder for schema `S`.
375 ///
376 /// # Examples
377 ///
378 /// ```rust
379 /// # extern crate self as drizzle;
380 /// # mod _drizzle {
381 /// # pub mod core { pub use drizzle_core::*; }
382 /// # pub mod error { pub use drizzle_core::error::*; }
383 /// # pub mod types { pub use drizzle_types::*; }
384 /// # pub mod migrations { pub use drizzle_migrations::*; }
385 /// # pub use drizzle_types::Dialect;
386 /// # pub use drizzle_types as ddl;
387 /// # pub mod postgres {
388 /// # pub mod values { pub use drizzle_postgres::values::*; }
389 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
390 /// # pub mod common { pub use drizzle_postgres::common::*; }
391 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
392 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
393 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
394 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
395 /// # pub mod types { pub use drizzle_postgres::types::*; }
396 /// # #[cfg(feature = "aws-data-api")]
397 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
398 /// # pub struct Row;
399 /// # impl Row {
400 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
401 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
402 /// # pub fn len(&self) -> usize { unimplemented!() }
403 /// # }
404 /// # pub mod prelude {
405 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
406 /// # pub use drizzle_postgres::attrs::*;
407 /// # pub use drizzle_postgres::common::PostgresSchemaType;
408 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
409 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
410 /// # pub use drizzle_core::*;
411 /// # }
412 /// # }
413 /// # }
414 /// # pub use _drizzle::*;
415 /// # pub use const_format;
416 /// # fn main() {
417 /// # use drizzle::postgres::prelude::*;
418 /// # use drizzle::postgres::builder::QueryBuilder;
419 /// # #[PostgresTable(name = "users")]
420 /// # struct User {
421 /// # #[column(serial, primary)]
422 /// # id: i32,
423 /// # name: String,
424 /// # email: Option<String>,
425 /// # }
426 /// # #[PostgresTable(name = "posts")]
427 /// # struct Post {
428 /// # #[column(serial, primary)]
429 /// # id: i32,
430 /// # #[column(references = User::id)]
431 /// # author_id: i32,
432 /// # title: String,
433 /// # }
434 /// # #[derive(PostgresSchema)]
435 /// # struct Schema {
436 /// # user: User,
437 /// # post: Post,
438 /// # }
439 /// # let Schema { user, post } = Schema::new();
440 /// let db = QueryBuilder::new::<Schema>();
441 /// let query = db.select(()).from(user);
442 /// assert_eq!(
443 /// query.to_sql().sql(),
444 /// r#"SELECT "users"."id", "users"."name", "users"."email" FROM "users""#
445 /// );
446 /// # }
447 /// ```
448 #[must_use]
449 pub const fn new<S>() -> QueryBuilder<'a, S, BuilderInit> {
450 QueryBuilder {
451 sql: SQL::empty(),
452 schema: PhantomData,
453 state: PhantomData,
454 table: PhantomData,
455 marker: PhantomData,
456 row: PhantomData,
457 grouped: PhantomData,
458 }
459 }
460}
461
462impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
463 /// Starts a `SELECT` of the given columns.
464 ///
465 /// Pass one column or expression, a tuple of them, or `()` for every
466 /// column of the `FROM` table. Continue with `.from(table)`.
467 ///
468 /// # Examples
469 ///
470 /// ```rust
471 /// # extern crate self as drizzle;
472 /// # mod _drizzle {
473 /// # pub mod core { pub use drizzle_core::*; }
474 /// # pub mod error { pub use drizzle_core::error::*; }
475 /// # pub mod types { pub use drizzle_types::*; }
476 /// # pub mod migrations { pub use drizzle_migrations::*; }
477 /// # pub use drizzle_types::Dialect;
478 /// # pub use drizzle_types as ddl;
479 /// # pub mod postgres {
480 /// # pub mod values { pub use drizzle_postgres::values::*; }
481 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
482 /// # pub mod common { pub use drizzle_postgres::common::*; }
483 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
484 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
485 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
486 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
487 /// # pub mod types { pub use drizzle_postgres::types::*; }
488 /// # #[cfg(feature = "aws-data-api")]
489 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
490 /// # pub struct Row;
491 /// # impl Row {
492 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
493 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
494 /// # pub fn len(&self) -> usize { unimplemented!() }
495 /// # }
496 /// # pub mod prelude {
497 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
498 /// # pub use drizzle_postgres::attrs::*;
499 /// # pub use drizzle_postgres::common::PostgresSchemaType;
500 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
501 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
502 /// # pub use drizzle_core::*;
503 /// # }
504 /// # }
505 /// # }
506 /// # pub use _drizzle::*;
507 /// # pub use const_format;
508 /// # fn main() {
509 /// # use drizzle::postgres::prelude::*;
510 /// # use drizzle::postgres::builder::QueryBuilder;
511 /// # #[PostgresTable(name = "users")]
512 /// # struct User {
513 /// # #[column(serial, primary)]
514 /// # id: i32,
515 /// # name: String,
516 /// # email: Option<String>,
517 /// # }
518 /// # #[PostgresTable(name = "posts")]
519 /// # struct Post {
520 /// # #[column(serial, primary)]
521 /// # id: i32,
522 /// # #[column(references = User::id)]
523 /// # author_id: i32,
524 /// # title: String,
525 /// # }
526 /// # #[derive(PostgresSchema)]
527 /// # struct Schema {
528 /// # user: User,
529 /// # post: Post,
530 /// # }
531 /// # let db = QueryBuilder::new::<Schema>();
532 /// # let Schema { user, post } = Schema::new();
533 /// use drizzle::core::expr::eq;
534 ///
535 /// let query = db
536 /// .select((user.name, post.title))
537 /// .from(user)
538 /// .join((post, eq(post.author_id, user.id)));
539 /// assert_eq!(
540 /// query.to_sql().sql(),
541 /// r#"SELECT "users"."name", "posts"."title" FROM "users" JOIN "posts" ON "posts"."author_id" = "users"."id""#
542 /// );
543 /// # }
544 /// ```
545 pub fn select<T>(
546 &self,
547 columns: T,
548 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
549 where
550 T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
551 {
552 let sql = crate::helpers::select(columns);
553 select::SelectBuilder {
554 sql,
555 schema: PhantomData,
556 state: PhantomData,
557 table: PhantomData,
558 marker: PhantomData,
559 row: PhantomData,
560 grouped: PhantomData,
561 }
562 }
563
564 /// Starts a `SELECT DISTINCT`, which drops duplicate rows.
565 ///
566 /// # Examples
567 ///
568 /// ```rust
569 /// # extern crate self as drizzle;
570 /// # mod _drizzle {
571 /// # pub mod core { pub use drizzle_core::*; }
572 /// # pub mod error { pub use drizzle_core::error::*; }
573 /// # pub mod types { pub use drizzle_types::*; }
574 /// # pub mod migrations { pub use drizzle_migrations::*; }
575 /// # pub use drizzle_types::Dialect;
576 /// # pub use drizzle_types as ddl;
577 /// # pub mod postgres {
578 /// # pub mod values { pub use drizzle_postgres::values::*; }
579 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
580 /// # pub mod common { pub use drizzle_postgres::common::*; }
581 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
582 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
583 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
584 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
585 /// # pub mod types { pub use drizzle_postgres::types::*; }
586 /// # #[cfg(feature = "aws-data-api")]
587 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
588 /// # pub struct Row;
589 /// # impl Row {
590 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
591 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
592 /// # pub fn len(&self) -> usize { unimplemented!() }
593 /// # }
594 /// # pub mod prelude {
595 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
596 /// # pub use drizzle_postgres::attrs::*;
597 /// # pub use drizzle_postgres::common::PostgresSchemaType;
598 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
599 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
600 /// # pub use drizzle_core::*;
601 /// # }
602 /// # }
603 /// # }
604 /// # pub use _drizzle::*;
605 /// # pub use const_format;
606 /// # fn main() {
607 /// # use drizzle::postgres::prelude::*;
608 /// # use drizzle::postgres::builder::QueryBuilder;
609 /// # #[PostgresTable(name = "users")]
610 /// # struct User {
611 /// # #[column(serial, primary)]
612 /// # id: i32,
613 /// # name: String,
614 /// # email: Option<String>,
615 /// # }
616 /// # #[PostgresTable(name = "posts")]
617 /// # struct Post {
618 /// # #[column(serial, primary)]
619 /// # id: i32,
620 /// # #[column(references = User::id)]
621 /// # author_id: i32,
622 /// # title: String,
623 /// # }
624 /// # #[derive(PostgresSchema)]
625 /// # struct Schema {
626 /// # user: User,
627 /// # post: Post,
628 /// # }
629 /// # let db = QueryBuilder::new::<Schema>();
630 /// # let Schema { user, post } = Schema::new();
631 /// let query = db.select_distinct(user.name).from(user);
632 /// assert_eq!(query.to_sql().sql(), r#"SELECT DISTINCT "users"."name" FROM "users""#);
633 /// # }
634 /// ```
635 pub fn select_distinct<T>(
636 &self,
637 columns: T,
638 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
639 where
640 T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
641 {
642 let sql = crate::helpers::select_distinct(columns);
643 select::SelectBuilder {
644 sql,
645 schema: PhantomData,
646 state: PhantomData,
647 table: PhantomData,
648 marker: PhantomData,
649 row: PhantomData,
650 grouped: PhantomData,
651 }
652 }
653
654 /// Starts a `SELECT DISTINCT ON (...)`, which keeps one row per distinct
655 /// value of `on`.
656 ///
657 /// The first row of each group wins, so add an `order_by` that starts
658 /// with the `on` columns to choose which row is kept.
659 ///
660 /// # Examples
661 ///
662 /// ```rust
663 /// # extern crate self as drizzle;
664 /// # mod _drizzle {
665 /// # pub mod core { pub use drizzle_core::*; }
666 /// # pub mod error { pub use drizzle_core::error::*; }
667 /// # pub mod types { pub use drizzle_types::*; }
668 /// # pub mod migrations { pub use drizzle_migrations::*; }
669 /// # pub use drizzle_types::Dialect;
670 /// # pub use drizzle_types as ddl;
671 /// # pub mod postgres {
672 /// # pub mod values { pub use drizzle_postgres::values::*; }
673 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
674 /// # pub mod common { pub use drizzle_postgres::common::*; }
675 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
676 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
677 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
678 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
679 /// # pub mod types { pub use drizzle_postgres::types::*; }
680 /// # #[cfg(feature = "aws-data-api")]
681 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
682 /// # pub struct Row;
683 /// # impl Row {
684 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
685 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
686 /// # pub fn len(&self) -> usize { unimplemented!() }
687 /// # }
688 /// # pub mod prelude {
689 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
690 /// # pub use drizzle_postgres::attrs::*;
691 /// # pub use drizzle_postgres::common::PostgresSchemaType;
692 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
693 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
694 /// # pub use drizzle_core::*;
695 /// # }
696 /// # }
697 /// # }
698 /// # pub use _drizzle::*;
699 /// # pub use const_format;
700 /// # fn main() {
701 /// # use drizzle::postgres::prelude::*;
702 /// # use drizzle::postgres::builder::QueryBuilder;
703 /// # #[PostgresTable(name = "users")]
704 /// # struct User {
705 /// # #[column(serial, primary)]
706 /// # id: i32,
707 /// # name: String,
708 /// # email: Option<String>,
709 /// # }
710 /// # #[PostgresTable(name = "posts")]
711 /// # struct Post {
712 /// # #[column(serial, primary)]
713 /// # id: i32,
714 /// # #[column(references = User::id)]
715 /// # author_id: i32,
716 /// # title: String,
717 /// # }
718 /// # #[derive(PostgresSchema)]
719 /// # struct Schema {
720 /// # user: User,
721 /// # post: Post,
722 /// # }
723 /// # let db = QueryBuilder::new::<Schema>();
724 /// # let Schema { user, post } = Schema::new();
725 /// let query = db
726 /// .select_distinct_on(user.email, (user.id, user.email))
727 /// .from(user)
728 /// .order_by(user.email);
729 /// assert_eq!(
730 /// query.to_sql().sql(),
731 /// r#"SELECT DISTINCT ON ("users"."email") "users"."id", "users"."email" FROM "users" ORDER BY "users"."email""#
732 /// );
733 /// # }
734 /// ```
735 pub fn select_distinct_on<On, Columns>(
736 &self,
737 on: On,
738 columns: Columns,
739 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), Columns::Marker>
740 where
741 On: ToSQL<'a, PostgresValue<'a>>,
742 Columns: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
743 {
744 let sql = crate::helpers::select_distinct_on(on, columns);
745 select::SelectBuilder {
746 sql,
747 schema: PhantomData,
748 state: PhantomData,
749 table: PhantomData,
750 marker: PhantomData,
751 row: PhantomData,
752 grouped: PhantomData,
753 }
754 }
755}
756
757impl<'a, Schema> QueryBuilder<'a, Schema, CTEInit> {
758 /// Starts the main `SELECT` after `WITH ...`. See [`QueryBuilder::with`].
759 pub fn select<T>(
760 &self,
761 columns: T,
762 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
763 where
764 T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
765 {
766 let sql = self.sql.clone().append(crate::helpers::select(columns));
767 select::SelectBuilder {
768 sql,
769 schema: PhantomData,
770 state: PhantomData,
771 table: PhantomData,
772 marker: PhantomData,
773 row: PhantomData,
774 grouped: PhantomData,
775 }
776 }
777
778 /// Starts the main `SELECT DISTINCT` after `WITH ...`.
779 pub fn select_distinct<T>(
780 &self,
781 columns: T,
782 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
783 where
784 T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
785 {
786 let sql = self
787 .sql
788 .clone()
789 .append(crate::helpers::select_distinct(columns));
790 select::SelectBuilder {
791 sql,
792 schema: PhantomData,
793 state: PhantomData,
794 table: PhantomData,
795 marker: PhantomData,
796 row: PhantomData,
797 grouped: PhantomData,
798 }
799 }
800
801 /// Starts the main `SELECT DISTINCT ON (...)` after `WITH ...`.
802 pub fn select_distinct_on<On, Columns>(
803 &self,
804 on: On,
805 columns: Columns,
806 ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), Columns::Marker>
807 where
808 On: ToSQL<'a, PostgresValue<'a>>,
809 Columns: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
810 {
811 let sql = self
812 .sql
813 .clone()
814 .append(crate::helpers::select_distinct_on(on, columns));
815 select::SelectBuilder {
816 sql,
817 schema: PhantomData,
818 state: PhantomData,
819 table: PhantomData,
820 marker: PhantomData,
821 row: PhantomData,
822 grouped: PhantomData,
823 }
824 }
825
826 /// Starts the main `INSERT` after `WITH ...`.
827 pub fn insert<Table>(
828 &self,
829 table: Table,
830 ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
831 where
832 Table: PostgresTable<'a>,
833 {
834 let sql = self
835 .sql
836 .clone()
837 .append(crate::helpers::insert::<Table>(&table));
838
839 insert::InsertBuilder {
840 sql,
841 schema: PhantomData,
842 state: PhantomData,
843 table: PhantomData,
844 marker: PhantomData,
845 row: PhantomData,
846 grouped: PhantomData,
847 }
848 }
849
850 /// Starts the main `UPDATE` after `WITH ...`.
851 pub fn update<Table>(
852 &self,
853 table: Table,
854 ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
855 where
856 Table: PostgresTable<'a>,
857 {
858 let sql = self.sql.clone().append(crate::helpers::update::<
859 Table,
860 PostgresSchemaType,
861 PostgresValue<'a>,
862 >(&table));
863
864 update::UpdateBuilder {
865 sql,
866 schema: PhantomData,
867 state: PhantomData,
868 table: PhantomData,
869 marker: PhantomData,
870 row: PhantomData,
871 grouped: PhantomData,
872 }
873 }
874
875 /// Starts the main `DELETE` after `WITH ...`.
876 pub fn delete<Table>(
877 &self,
878 table: Table,
879 ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
880 where
881 Table: PostgresTable<'a>,
882 {
883 let sql = self.sql.clone().append(crate::helpers::delete::<
884 Table,
885 PostgresSchemaType,
886 PostgresValue<'a>,
887 >(&table));
888
889 delete::DeleteBuilder {
890 sql,
891 schema: PhantomData,
892 state: PhantomData,
893 table: PhantomData,
894 marker: PhantomData,
895 row: PhantomData,
896 grouped: PhantomData,
897 }
898 }
899
900 /// Adds another common table expression to the `WITH` list.
901 #[must_use]
902 pub fn with<C>(&self, cte: &C) -> Self
903 where
904 C: CTEDefinition<'a>,
905 {
906 let sql = self
907 .sql
908 .clone()
909 .push(Token::COMMA)
910 .append(cte.cte_definition());
911 QueryBuilder {
912 sql,
913 schema: PhantomData,
914 state: PhantomData,
915 table: PhantomData,
916 marker: PhantomData,
917 row: PhantomData,
918 grouped: PhantomData,
919 }
920 }
921}
922
923impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
924 /// Starts an `INSERT INTO table`. Continue with `.values(...)` or `.select(...)`.
925 ///
926 /// # Examples
927 ///
928 /// ```rust
929 /// # extern crate self as drizzle;
930 /// # mod _drizzle {
931 /// # pub mod core { pub use drizzle_core::*; }
932 /// # pub mod error { pub use drizzle_core::error::*; }
933 /// # pub mod types { pub use drizzle_types::*; }
934 /// # pub mod migrations { pub use drizzle_migrations::*; }
935 /// # pub use drizzle_types::Dialect;
936 /// # pub use drizzle_types as ddl;
937 /// # pub mod postgres {
938 /// # pub mod values { pub use drizzle_postgres::values::*; }
939 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
940 /// # pub mod common { pub use drizzle_postgres::common::*; }
941 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
942 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
943 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
944 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
945 /// # pub mod types { pub use drizzle_postgres::types::*; }
946 /// # #[cfg(feature = "aws-data-api")]
947 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
948 /// # pub struct Row;
949 /// # impl Row {
950 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
951 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
952 /// # pub fn len(&self) -> usize { unimplemented!() }
953 /// # }
954 /// # pub mod prelude {
955 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
956 /// # pub use drizzle_postgres::attrs::*;
957 /// # pub use drizzle_postgres::common::PostgresSchemaType;
958 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
959 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
960 /// # pub use drizzle_core::*;
961 /// # }
962 /// # }
963 /// # }
964 /// # pub use _drizzle::*;
965 /// # pub use const_format;
966 /// # fn main() {
967 /// # use drizzle::postgres::prelude::*;
968 /// # use drizzle::postgres::builder::QueryBuilder;
969 /// # #[PostgresTable(name = "users")]
970 /// # struct User {
971 /// # #[column(serial, primary)]
972 /// # id: i32,
973 /// # name: String,
974 /// # email: Option<String>,
975 /// # }
976 /// # #[PostgresTable(name = "posts")]
977 /// # struct Post {
978 /// # #[column(serial, primary)]
979 /// # id: i32,
980 /// # #[column(references = User::id)]
981 /// # author_id: i32,
982 /// # title: String,
983 /// # }
984 /// # #[derive(PostgresSchema)]
985 /// # struct Schema {
986 /// # user: User,
987 /// # post: Post,
988 /// # }
989 /// # let db = QueryBuilder::new::<Schema>();
990 /// # let Schema { user, post } = Schema::new();
991 /// let query = db.insert(user).values([InsertUser::new("Alice")]);
992 /// assert_eq!(query.to_sql().sql(), r#"INSERT INTO "users" ("name") VALUES ($1)"#);
993 /// # }
994 /// ```
995 pub fn insert<Table>(
996 &self,
997 table: Table,
998 ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
999 where
1000 Table: PostgresTable<'a>,
1001 {
1002 let sql = crate::helpers::insert::<Table>(&table);
1003
1004 insert::InsertBuilder {
1005 sql,
1006 schema: PhantomData,
1007 state: PhantomData,
1008 table: PhantomData,
1009 marker: PhantomData,
1010 row: PhantomData,
1011 grouped: PhantomData,
1012 }
1013 }
1014
1015 /// Starts an `UPDATE table`. Continue with `.set(...)`.
1016 ///
1017 /// # Examples
1018 ///
1019 /// ```rust
1020 /// # extern crate self as drizzle;
1021 /// # mod _drizzle {
1022 /// # pub mod core { pub use drizzle_core::*; }
1023 /// # pub mod error { pub use drizzle_core::error::*; }
1024 /// # pub mod types { pub use drizzle_types::*; }
1025 /// # pub mod migrations { pub use drizzle_migrations::*; }
1026 /// # pub use drizzle_types::Dialect;
1027 /// # pub use drizzle_types as ddl;
1028 /// # pub mod postgres {
1029 /// # pub mod values { pub use drizzle_postgres::values::*; }
1030 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
1031 /// # pub mod common { pub use drizzle_postgres::common::*; }
1032 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
1033 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
1034 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
1035 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
1036 /// # pub mod types { pub use drizzle_postgres::types::*; }
1037 /// # #[cfg(feature = "aws-data-api")]
1038 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
1039 /// # pub struct Row;
1040 /// # impl Row {
1041 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
1042 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
1043 /// # pub fn len(&self) -> usize { unimplemented!() }
1044 /// # }
1045 /// # pub mod prelude {
1046 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
1047 /// # pub use drizzle_postgres::attrs::*;
1048 /// # pub use drizzle_postgres::common::PostgresSchemaType;
1049 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
1050 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
1051 /// # pub use drizzle_core::*;
1052 /// # }
1053 /// # }
1054 /// # }
1055 /// # pub use _drizzle::*;
1056 /// # pub use const_format;
1057 /// # fn main() {
1058 /// # use drizzle::postgres::prelude::*;
1059 /// # use drizzle::postgres::builder::QueryBuilder;
1060 /// # #[PostgresTable(name = "users")]
1061 /// # struct User {
1062 /// # #[column(serial, primary)]
1063 /// # id: i32,
1064 /// # name: String,
1065 /// # email: Option<String>,
1066 /// # }
1067 /// # #[PostgresTable(name = "posts")]
1068 /// # struct Post {
1069 /// # #[column(serial, primary)]
1070 /// # id: i32,
1071 /// # #[column(references = User::id)]
1072 /// # author_id: i32,
1073 /// # title: String,
1074 /// # }
1075 /// # #[derive(PostgresSchema)]
1076 /// # struct Schema {
1077 /// # user: User,
1078 /// # post: Post,
1079 /// # }
1080 /// # let db = QueryBuilder::new::<Schema>();
1081 /// # let Schema { user, post } = Schema::new();
1082 /// use drizzle::core::expr::eq;
1083 ///
1084 /// let query = db
1085 /// .update(user)
1086 /// .set(UpdateUser::default().with_name("Bob"))
1087 /// .r#where(eq(user.id, 1));
1088 /// assert_eq!(
1089 /// query.to_sql().sql(),
1090 /// r#"UPDATE "users" SET "name" = $1 WHERE "users"."id" = $2"#
1091 /// );
1092 /// # }
1093 /// ```
1094 pub fn update<Table>(
1095 &self,
1096 table: Table,
1097 ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
1098 where
1099 Table: PostgresTable<'a>,
1100 {
1101 let sql = crate::helpers::update::<Table, PostgresSchemaType, PostgresValue<'a>>(&table);
1102
1103 update::UpdateBuilder {
1104 sql,
1105 schema: PhantomData,
1106 state: PhantomData,
1107 table: PhantomData,
1108 marker: PhantomData,
1109 row: PhantomData,
1110 grouped: PhantomData,
1111 }
1112 }
1113
1114 /// Starts a `DELETE FROM table`.
1115 ///
1116 /// Without `.where(...)` the statement deletes every row.
1117 ///
1118 /// # Examples
1119 ///
1120 /// ```rust
1121 /// # extern crate self as drizzle;
1122 /// # mod _drizzle {
1123 /// # pub mod core { pub use drizzle_core::*; }
1124 /// # pub mod error { pub use drizzle_core::error::*; }
1125 /// # pub mod types { pub use drizzle_types::*; }
1126 /// # pub mod migrations { pub use drizzle_migrations::*; }
1127 /// # pub use drizzle_types::Dialect;
1128 /// # pub use drizzle_types as ddl;
1129 /// # pub mod postgres {
1130 /// # pub mod values { pub use drizzle_postgres::values::*; }
1131 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
1132 /// # pub mod common { pub use drizzle_postgres::common::*; }
1133 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
1134 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
1135 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
1136 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
1137 /// # pub mod types { pub use drizzle_postgres::types::*; }
1138 /// # #[cfg(feature = "aws-data-api")]
1139 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
1140 /// # pub struct Row;
1141 /// # impl Row {
1142 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
1143 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
1144 /// # pub fn len(&self) -> usize { unimplemented!() }
1145 /// # }
1146 /// # pub mod prelude {
1147 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
1148 /// # pub use drizzle_postgres::attrs::*;
1149 /// # pub use drizzle_postgres::common::PostgresSchemaType;
1150 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
1151 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
1152 /// # pub use drizzle_core::*;
1153 /// # }
1154 /// # }
1155 /// # }
1156 /// # pub use _drizzle::*;
1157 /// # pub use const_format;
1158 /// # fn main() {
1159 /// # use drizzle::postgres::prelude::*;
1160 /// # use drizzle::postgres::builder::QueryBuilder;
1161 /// # #[PostgresTable(name = "users")]
1162 /// # struct User {
1163 /// # #[column(serial, primary)]
1164 /// # id: i32,
1165 /// # name: String,
1166 /// # email: Option<String>,
1167 /// # }
1168 /// # #[PostgresTable(name = "posts")]
1169 /// # struct Post {
1170 /// # #[column(serial, primary)]
1171 /// # id: i32,
1172 /// # #[column(references = User::id)]
1173 /// # author_id: i32,
1174 /// # title: String,
1175 /// # }
1176 /// # #[derive(PostgresSchema)]
1177 /// # struct Schema {
1178 /// # user: User,
1179 /// # post: Post,
1180 /// # }
1181 /// # let db = QueryBuilder::new::<Schema>();
1182 /// # let Schema { user, post } = Schema::new();
1183 /// use drizzle::core::expr::gt;
1184 ///
1185 /// let query = db.delete(user).r#where(gt(user.id, 10));
1186 /// assert_eq!(query.to_sql().sql(), r#"DELETE FROM "users" WHERE "users"."id" > $1"#);
1187 /// # }
1188 /// ```
1189 pub fn delete<Table>(
1190 &self,
1191 table: Table,
1192 ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
1193 where
1194 Table: PostgresTable<'a>,
1195 {
1196 let sql = crate::helpers::delete::<Table, PostgresSchemaType, PostgresValue<'a>>(&table);
1197
1198 delete::DeleteBuilder {
1199 sql,
1200 schema: PhantomData,
1201 state: PhantomData,
1202 table: PhantomData,
1203 marker: PhantomData,
1204 row: PhantomData,
1205 grouped: PhantomData,
1206 }
1207 }
1208
1209 /// Starts a `WITH` clause from a common table expression (CTE).
1210 ///
1211 /// Build the CTE with `SelectBuilder::into_cte::<Tag>()`, then reference
1212 /// it in the main statement through its `.table` field. Chain more
1213 /// `.with(...)` calls to add more CTEs.
1214 ///
1215 /// # Examples
1216 ///
1217 /// ```rust
1218 /// # extern crate self as drizzle;
1219 /// # mod _drizzle {
1220 /// # pub mod core { pub use drizzle_core::*; }
1221 /// # pub mod error { pub use drizzle_core::error::*; }
1222 /// # pub mod types { pub use drizzle_types::*; }
1223 /// # pub mod migrations { pub use drizzle_migrations::*; }
1224 /// # pub use drizzle_types::Dialect;
1225 /// # pub use drizzle_types as ddl;
1226 /// # pub mod postgres {
1227 /// # pub mod values { pub use drizzle_postgres::values::*; }
1228 /// # pub mod traits { pub use drizzle_postgres::traits::*; }
1229 /// # pub mod common { pub use drizzle_postgres::common::*; }
1230 /// # pub mod attrs { pub use drizzle_postgres::attrs::*; }
1231 /// # pub mod builder { pub use drizzle_postgres::builder::*; }
1232 /// # pub mod helpers { pub use drizzle_postgres::helpers::*; }
1233 /// # pub mod expr { pub use drizzle_postgres::expr::*; }
1234 /// # pub mod types { pub use drizzle_postgres::types::*; }
1235 /// # #[cfg(feature = "aws-data-api")]
1236 /// # pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
1237 /// # pub struct Row;
1238 /// # impl Row {
1239 /// # pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
1240 /// # pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
1241 /// # pub fn len(&self) -> usize { unimplemented!() }
1242 /// # }
1243 /// # pub mod prelude {
1244 /// # pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
1245 /// # pub use drizzle_postgres::attrs::*;
1246 /// # pub use drizzle_postgres::common::PostgresSchemaType;
1247 /// # pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
1248 /// # pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
1249 /// # pub use drizzle_core::*;
1250 /// # }
1251 /// # }
1252 /// # }
1253 /// # pub use _drizzle::*;
1254 /// # pub use const_format;
1255 /// # fn main() {
1256 /// # use drizzle::postgres::prelude::*;
1257 /// # use drizzle::postgres::builder::QueryBuilder;
1258 /// # #[PostgresTable(name = "users")]
1259 /// # struct User {
1260 /// # #[column(serial, primary)]
1261 /// # id: i32,
1262 /// # name: String,
1263 /// # email: Option<String>,
1264 /// # }
1265 /// # #[PostgresTable(name = "posts")]
1266 /// # struct Post {
1267 /// # #[column(serial, primary)]
1268 /// # id: i32,
1269 /// # #[column(references = User::id)]
1270 /// # author_id: i32,
1271 /// # title: String,
1272 /// # }
1273 /// # #[derive(PostgresSchema)]
1274 /// # struct Schema {
1275 /// # user: User,
1276 /// # post: Post,
1277 /// # }
1278 /// # let db = QueryBuilder::new::<Schema>();
1279 /// # let Schema { user, post } = Schema::new();
1280 /// use drizzle::core::expr::gt;
1281 ///
1282 /// struct Recent;
1283 /// impl drizzle::core::Tag for Recent {
1284 /// const NAME: &'static str = "recent";
1285 /// }
1286 ///
1287 /// let recent = db
1288 /// .select((user.id, user.name))
1289 /// .from(user)
1290 /// .r#where(gt(user.id, 100))
1291 /// .into_cte::<Recent>();
1292 /// let r = recent.table;
1293 ///
1294 /// let query = db.with(&recent).select(r.name).from(&recent);
1295 /// assert_eq!(
1296 /// query.to_sql().sql(),
1297 /// r#"WITH "recent" AS (SELECT "users"."id", "users"."name" FROM "users" WHERE "users"."id" > $1) SELECT "recent"."name" FROM "recent""#
1298 /// );
1299 /// # }
1300 /// ```
1301 pub fn with<C>(&self, cte: &C) -> QueryBuilder<'a, Schema, CTEInit>
1302 where
1303 C: CTEDefinition<'a>,
1304 {
1305 let sql = SQL::from(Token::WITH).append(cte.cte_definition());
1306 QueryBuilder {
1307 sql,
1308 schema: PhantomData,
1309 state: PhantomData,
1310 table: PhantomData,
1311 marker: PhantomData,
1312 row: PhantomData,
1313 grouped: PhantomData,
1314 }
1315 }
1316}
1317
1318#[cfg(test)]
1319mod tests {
1320 use super::*;
1321
1322 #[test]
1323 fn test_query_builder_new() {
1324 let qb = QueryBuilder::new::<()>();
1325 let sql = qb.to_sql();
1326 assert_eq!(sql.sql(), "");
1327 assert_eq!(sql.params().count(), 0);
1328 }
1329
1330 #[test]
1331 fn test_builder_init_type() {
1332 let _state = BuilderInit;
1333 }
1334}