drizzle_sqlite/builder/
mod.rs

1use drizzle_core::Token;
2// Re-export common enums and traits from core
3pub use drizzle_core::builder::{BuilderInit, ExecutableState, OrderByClause};
4pub use drizzle_core::{
5    OrderBy, SQL, ToSQL,
6    traits::{SQLSchema, SQLTable},
7};
8
9// Local imports
10use crate::{
11    common::SQLiteSchemaType,
12    traits::{SQLiteSQL, SQLiteTable},
13    values::SQLiteValue,
14};
15use std::{fmt::Debug, marker::PhantomData};
16
17// Import modules - these provide specific builder types
18pub mod cte;
19pub mod delete;
20pub mod insert;
21pub mod prepared;
22pub mod select;
23pub mod update;
24
25// Re-export CTE types
26pub use cte::{CTEDefinition, CTEView};
27
28// Export state markers for easier use
29pub use delete::{DeleteInitial, DeleteReturningSet, DeleteWhereSet};
30pub use insert::{
31    Conflict, InsertInitial, InsertOnConflictSet, InsertReturningSet, InsertValuesSet,
32};
33pub use select::{
34    SelectFromSet, SelectGroupSet, SelectInitial, SelectJoinSet, SelectLimitSet, SelectOffsetSet,
35    SelectOrderSet, SelectWhereSet,
36};
37pub use update::{UpdateInitial, UpdateReturningSet, UpdateSetClauseSet, UpdateWhereSet};
38
39#[derive(Debug, Clone)]
40pub struct CTEInit;
41
42impl ExecutableState for CTEInit {}
43
44/// Main query builder for SQLite operations.
45///
46/// `QueryBuilder` provides a type-safe, fluent API for building SQL queries. It uses compile-time
47/// type checking to ensure queries are valid and properly structured.
48///
49/// ## Type Parameters
50///
51/// - `Schema`: The database schema type, ensuring queries only reference valid tables
52/// - `State`: The current builder state, enforcing proper query construction order
53/// - `Table`: The table type being operated on (for single-table operations)
54///
55/// ## Basic Usage
56///
57/// ```
58/// # mod drizzle {
59/// #     pub mod core { pub use drizzle_core::*; }
60/// #     pub mod error { pub use drizzle_core::error::*; }
61/// #     pub mod types { pub use drizzle_types::*; }
62/// #     pub mod migrations { pub use drizzle_migrations::*; }
63/// #     pub use drizzle_types::Dialect;
64/// #     pub use drizzle_types as ddl;
65/// #     pub mod sqlite {
66/// #         pub use drizzle_sqlite::*;
67/// #         pub mod prelude {
68/// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
69/// #             pub use drizzle_sqlite::{*, attrs::*};
70/// #             pub use drizzle_core::*;
71/// #         }
72/// #     }
73/// # }
74/// use drizzle::sqlite::prelude::*;
75/// use drizzle::sqlite::builder::QueryBuilder;
76///
77/// #[SQLiteTable(name = "users")]
78/// struct User {
79///     #[column(primary)]
80///     id: i32,
81///     name: String,
82/// }
83///
84/// #[derive(SQLiteSchema)]
85/// struct Schema {
86///     user: User,
87/// }
88///
89/// // Create a query builder for your schema
90/// let builder = QueryBuilder::new::<Schema>();
91/// let Schema { user } = Schema::new();
92///
93/// // Build queries using the fluent API
94/// let query = builder
95///     .select(user.name)
96///     .from(user);
97/// assert_eq!(query.to_sql().sql(), r#"SELECT "users"."name" FROM "users""#);
98/// ```
99///
100/// ## Query Types
101///
102/// The builder supports all major SQL operations:
103///
104/// ### SELECT Queries
105/// ```rust,no_run
106/// # mod drizzle {
107/// #     pub mod core { pub use drizzle_core::*; }
108/// #     pub mod error { pub use drizzle_core::error::*; }
109/// #     pub mod types { pub use drizzle_types::*; }
110/// #     pub mod migrations { pub use drizzle_migrations::*; }
111/// #     pub use drizzle_types::Dialect;
112/// #     pub use drizzle_types as ddl;
113/// #     pub mod sqlite {
114/// #         pub use drizzle_sqlite::*;
115/// #         pub mod prelude {
116/// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
117/// #             pub use drizzle_sqlite::{*, attrs::*};
118/// #             pub use drizzle_core::*;
119/// #         }
120/// #     }
121/// # }
122/// # use drizzle::sqlite::prelude::*;
123/// # use drizzle::core::expr::gt;
124/// # use drizzle::sqlite::builder::QueryBuilder;
125/// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
126/// # #[derive(SQLiteSchema)] struct Schema { user: User }
127/// # let builder = QueryBuilder::new::<Schema>();
128/// # let Schema { user } = Schema::new();
129/// let query = builder.select(user.name).from(user);
130/// let query = builder.select((user.id, user.name)).from(user).r#where(gt(user.id, 10));
131/// ```
132///
133/// ### INSERT Queries
134/// ```rust,no_run
135/// # mod drizzle {
136/// #     pub mod core { pub use drizzle_core::*; }
137/// #     pub mod error { pub use drizzle_core::error::*; }
138/// #     pub mod types { pub use drizzle_types::*; }
139/// #     pub mod migrations { pub use drizzle_migrations::*; }
140/// #     pub use drizzle_types::Dialect;
141/// #     pub use drizzle_types as ddl;
142/// #     pub mod sqlite {
143/// #         pub use drizzle_sqlite::*;
144/// #         pub mod prelude {
145/// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
146/// #             pub use drizzle_sqlite::{*, attrs::*};
147/// #             pub use drizzle_core::*;
148/// #         }
149/// #     }
150/// # }
151/// # use drizzle::sqlite::prelude::*;
152/// # use drizzle::sqlite::builder::QueryBuilder;
153/// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
154/// # #[derive(SQLiteSchema)] struct Schema { user: User }
155/// # let builder = QueryBuilder::new::<Schema>();
156/// # let Schema { user } = Schema::new();
157/// let query = builder
158///     .insert(user)
159///     .values([InsertUser::new("Alice")]);
160/// ```
161///
162/// ### UPDATE Queries
163/// ```rust,no_run
164/// # mod drizzle {
165/// #     pub mod core { pub use drizzle_core::*; }
166/// #     pub mod error { pub use drizzle_core::error::*; }
167/// #     pub mod types { pub use drizzle_types::*; }
168/// #     pub mod migrations { pub use drizzle_migrations::*; }
169/// #     pub use drizzle_types::Dialect;
170/// #     pub use drizzle_types as ddl;
171/// #     pub mod sqlite {
172/// #         pub use drizzle_sqlite::*;
173/// #         pub mod prelude {
174/// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
175/// #             pub use drizzle_sqlite::{*, attrs::*};
176/// #             pub use drizzle_core::*;
177/// #         }
178/// #     }
179/// # }
180/// # use drizzle::sqlite::prelude::*;
181/// # use drizzle::core::expr::eq;
182/// # use drizzle::sqlite::builder::QueryBuilder;
183/// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
184/// # #[derive(SQLiteSchema)] struct Schema { user: User }
185/// # let builder = QueryBuilder::new::<Schema>();
186/// # let Schema { user } = Schema::new();
187/// let query = builder
188///     .update(user)
189///     .set(UpdateUser::default().with_name("Bob"))
190///     .r#where(eq(user.id, 1));
191/// ```
192///
193/// ### DELETE Queries  
194/// ```rust,no_run
195/// # mod drizzle {
196/// #     pub mod core { pub use drizzle_core::*; }
197/// #     pub mod error { pub use drizzle_core::error::*; }
198/// #     pub mod types { pub use drizzle_types::*; }
199/// #     pub mod migrations { pub use drizzle_migrations::*; }
200/// #     pub use drizzle_types::Dialect;
201/// #     pub use drizzle_types as ddl;
202/// #     pub mod sqlite {
203/// #         pub use drizzle_sqlite::*;
204/// #         pub mod prelude {
205/// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
206/// #             pub use drizzle_sqlite::{*, attrs::*};
207/// #             pub use drizzle_core::*;
208/// #         }
209/// #     }
210/// # }
211/// # use drizzle::sqlite::prelude::*;
212/// # use drizzle::core::expr::lt;
213/// # use drizzle::sqlite::builder::QueryBuilder;
214/// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
215/// # #[derive(SQLiteSchema)] struct Schema { user: User }
216/// # let builder = QueryBuilder::new::<Schema>();
217/// # let Schema { user } = Schema::new();
218/// let query = builder
219///     .delete(user)
220///     .r#where(lt(user.id, 10));
221/// ```
222///
223/// ## Common Table Expressions (CTEs)
224///
225/// The builder supports WITH clauses for complex queries with typed field access:
226///
227/// ```rust
228/// # mod drizzle {
229/// #     pub mod core { pub use drizzle_core::*; }
230/// #     pub mod error { pub use drizzle_core::error::*; }
231/// #     pub mod types { pub use drizzle_types::*; }
232/// #     pub mod migrations { pub use drizzle_migrations::*; }
233/// #     pub use drizzle_types::Dialect;
234/// #     pub use drizzle_types as ddl;
235/// #     pub mod sqlite {
236/// #         pub use drizzle_sqlite::*;
237/// #         pub mod prelude {
238/// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
239/// #             pub use drizzle_sqlite::{*, attrs::*};
240/// #             pub use drizzle_core::*;
241/// #         }
242/// #     }
243/// # }
244/// # use drizzle::sqlite::prelude::*;
245/// # use drizzle::sqlite::builder::QueryBuilder;
246/// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
247/// # #[derive(SQLiteSchema)] struct Schema { user: User }
248/// # let builder = QueryBuilder::new::<Schema>();
249/// # let Schema { user } = Schema::new();
250/// // Create a CTE with typed field access using .as_cte()
251/// let active_users = builder
252///     .select((user.id, user.name))
253///     .from(user)
254///     .as_cte("active_users");
255///
256/// // Use the CTE with typed column access via Deref
257/// let query = builder
258///     .with(&active_users)
259///     .select(active_users.name)  // Typed field access!
260///     .from(&active_users);
261/// assert_eq!(
262///     query.to_sql().sql(),
263///     r#"WITH active_users AS (SELECT "users"."id", "users"."name" FROM "users") SELECT "active_users"."name" FROM "active_users""#
264/// );
265/// ```
266#[derive(Debug, Clone, Default)]
267pub struct QueryBuilder<'a, Schema = (), State = (), Table = ()> {
268    pub sql: SQL<'a, SQLiteValue<'a>>,
269    schema: PhantomData<Schema>,
270    state: PhantomData<State>,
271    table: PhantomData<Table>,
272}
273
274//------------------------------------------------------------------------------
275// QueryBuilder Implementation
276//------------------------------------------------------------------------------
277
278impl<'a, Schema, State, Table> ToSQL<'a, SQLiteValue<'a>>
279    for QueryBuilder<'a, Schema, State, Table>
280{
281    fn to_sql(&self) -> SQLiteSQL<'a> {
282        self.sql.clone()
283    }
284}
285
286impl<'a> QueryBuilder<'a> {
287    /// Creates a new query builder for the given schema type.
288    ///
289    /// This is the entry point for building SQL queries. The schema type parameter
290    /// ensures that only valid tables from your schema can be used in queries.
291    ///
292    /// # Examples
293    ///
294    /// ```rust
295    /// # mod drizzle {
296    /// #     pub mod core { pub use drizzle_core::*; }
297    /// #     pub mod error { pub use drizzle_core::error::*; }
298    /// #     pub mod types { pub use drizzle_types::*; }
299    /// #     pub mod migrations { pub use drizzle_migrations::*; }
300    /// #     pub use drizzle_types::Dialect;
301    /// #     pub use drizzle_types as ddl;
302    /// #     pub mod sqlite {
303    /// #         pub use drizzle_sqlite::*;
304    /// #         pub mod prelude {
305    /// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
306    /// #             pub use drizzle_sqlite::{*, attrs::*};
307    /// #             pub use drizzle_core::*;
308    /// #         }
309    /// #     }
310    /// # }
311    /// use drizzle::sqlite::prelude::*;
312    /// use drizzle::sqlite::builder::QueryBuilder;
313    ///
314    /// #[SQLiteTable(name = "users")]
315    /// struct User {
316    ///     #[column(primary)]
317    ///     id: i32,
318    ///     name: String,
319    /// }
320    ///
321    /// #[derive(SQLiteSchema)]
322    /// struct MySchema {
323    ///     user: User,
324    /// }
325    ///
326    /// let builder = QueryBuilder::new::<MySchema>();
327    /// ```
328    pub const fn new<S>() -> QueryBuilder<'a, S, BuilderInit> {
329        QueryBuilder {
330            sql: SQL::empty(),
331            schema: PhantomData,
332            state: PhantomData,
333            table: PhantomData,
334        }
335    }
336}
337
338impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
339    /// Begins a SELECT query with the specified columns.
340    ///
341    /// This method starts building a SELECT statement. You can select individual columns,
342    /// multiple columns as a tuple, or use `()` to select all columns.
343    ///
344    /// # Examples
345    ///
346    /// ```rust
347    /// # mod drizzle {
348    /// #     pub mod core { pub use drizzle_core::*; }
349    /// #     pub mod error { pub use drizzle_core::error::*; }
350    /// #     pub mod types { pub use drizzle_types::*; }
351    /// #     pub mod migrations { pub use drizzle_migrations::*; }
352    /// #     pub use drizzle_types::Dialect;
353    /// #     pub use drizzle_types as ddl;
354    /// #     pub mod sqlite {
355    /// #         pub use drizzle_sqlite::*;
356    /// #         pub mod prelude {
357    /// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
358    /// #             pub use drizzle_sqlite::{*, attrs::*};
359    /// #             pub use drizzle_core::*;
360    /// #         }
361    /// #     }
362    /// # }
363    /// # use drizzle::sqlite::prelude::*;
364    /// # use drizzle::sqlite::builder::QueryBuilder;
365    /// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
366    /// # #[derive(SQLiteSchema)] struct Schema { user: User }
367    /// # let builder = QueryBuilder::new::<Schema>();
368    /// # let Schema { user } = Schema::new();
369    /// // Select a single column
370    /// let query = builder.select(user.name).from(user);
371    /// assert_eq!(query.to_sql().sql(), r#"SELECT "users"."name" FROM "users""#);
372    ///
373    /// // Select multiple columns
374    /// let query = builder.select((user.id, user.name)).from(user);
375    /// assert_eq!(query.to_sql().sql(), r#"SELECT "users"."id", "users"."name" FROM "users""#);
376    /// ```
377    pub fn select<T>(&self, columns: T) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
378    where
379        T: ToSQL<'a, SQLiteValue<'a>>,
380    {
381        let sql = crate::helpers::select(columns);
382        select::SelectBuilder {
383            sql,
384            schema: PhantomData,
385            state: PhantomData,
386            table: PhantomData,
387        }
388    }
389
390    /// Begins a SELECT DISTINCT query with the specified columns.
391    ///
392    /// SELECT DISTINCT removes duplicate rows from the result set.
393    ///
394    /// # Examples
395    ///
396    /// ```rust
397    /// # mod drizzle {
398    /// #     pub mod core { pub use drizzle_core::*; }
399    /// #     pub mod error { pub use drizzle_core::error::*; }
400    /// #     pub mod types { pub use drizzle_types::*; }
401    /// #     pub mod migrations { pub use drizzle_migrations::*; }
402    /// #     pub use drizzle_types::Dialect;
403    /// #     pub use drizzle_types as ddl;
404    /// #     pub mod sqlite {
405    /// #         pub use drizzle_sqlite::*;
406    /// #         pub mod prelude {
407    /// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
408    /// #             pub use drizzle_sqlite::{*, attrs::*};
409    /// #             pub use drizzle_core::*;
410    /// #         }
411    /// #     }
412    /// # }
413    /// # use drizzle::sqlite::prelude::*;
414    /// # use drizzle::sqlite::builder::QueryBuilder;
415    /// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
416    /// # #[derive(SQLiteSchema)] struct Schema { user: User }
417    /// # let builder = QueryBuilder::new::<Schema>();
418    /// # let Schema { user } = Schema::new();
419    /// let query = builder.select_distinct(user.name).from(user);
420    /// assert_eq!(query.to_sql().sql(), r#"SELECT DISTINCT "users"."name" FROM "users""#);
421    /// ```
422    pub fn select_distinct<T>(
423        &self,
424        columns: T,
425    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
426    where
427        T: ToSQL<'a, SQLiteValue<'a>>,
428    {
429        let sql = crate::helpers::select_distinct(columns);
430        select::SelectBuilder {
431            sql,
432            schema: PhantomData,
433            state: PhantomData,
434            table: PhantomData,
435        }
436    }
437}
438
439impl<'a, Schema> QueryBuilder<'a, Schema, CTEInit> {
440    pub fn select<T>(&self, columns: T) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
441    where
442        T: ToSQL<'a, SQLiteValue<'a>>,
443    {
444        let sql = self.sql.clone().append(crate::helpers::select(columns));
445        select::SelectBuilder {
446            sql,
447            schema: PhantomData,
448            state: PhantomData,
449            table: PhantomData,
450        }
451    }
452
453    /// Begins a SELECT DISTINCT query with the specified columns after a CTE.
454    pub fn select_distinct<T>(
455        &self,
456        columns: T,
457    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial>
458    where
459        T: ToSQL<'a, SQLiteValue<'a>>,
460    {
461        let sql = self
462            .sql
463            .clone()
464            .append(crate::helpers::select_distinct(columns));
465        select::SelectBuilder {
466            sql,
467            schema: PhantomData,
468            state: PhantomData,
469            table: PhantomData,
470        }
471    }
472
473    /// Begins an INSERT query after a CTE.
474    pub fn insert<Table>(
475        &self,
476        table: Table,
477    ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
478    where
479        Table: SQLiteTable<'a>,
480    {
481        let sql = self.sql.clone().append(crate::helpers::insert::<
482            'a,
483            Table,
484            SQLiteSchemaType,
485            SQLiteValue<'a>,
486        >(table));
487
488        insert::InsertBuilder {
489            sql,
490            schema: PhantomData,
491            state: PhantomData,
492            table: PhantomData,
493        }
494    }
495
496    /// Begins an UPDATE query after a CTE.
497    pub fn update<Table>(
498        &self,
499        table: Table,
500    ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
501    where
502        Table: SQLiteTable<'a>,
503    {
504        let sql = self.sql.clone().append(crate::helpers::update::<
505            'a,
506            Table,
507            SQLiteSchemaType,
508            SQLiteValue<'a>,
509        >(table));
510
511        update::UpdateBuilder {
512            sql,
513            schema: PhantomData,
514            state: PhantomData,
515            table: PhantomData,
516        }
517    }
518
519    /// Begins a DELETE query after a CTE.
520    pub fn delete<Table>(
521        &self,
522        table: Table,
523    ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
524    where
525        Table: SQLiteTable<'a>,
526    {
527        let sql = self.sql.clone().append(crate::helpers::delete::<
528            'a,
529            Table,
530            SQLiteSchemaType,
531            SQLiteValue<'a>,
532        >(table));
533
534        delete::DeleteBuilder {
535            sql,
536            schema: PhantomData,
537            state: PhantomData,
538            table: PhantomData,
539        }
540    }
541
542    pub fn with<C>(&self, cte: C) -> QueryBuilder<'a, Schema, CTEInit>
543    where
544        C: CTEDefinition<'a>,
545    {
546        let sql = self
547            .sql
548            .clone()
549            .push(Token::COMMA)
550            .append(cte.cte_definition());
551        QueryBuilder {
552            sql,
553            schema: PhantomData,
554            state: PhantomData,
555            table: PhantomData,
556        }
557    }
558}
559
560impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
561    /// Begins an INSERT query for the specified table.
562    ///
563    /// This method starts building an INSERT statement. The table must be part of the schema
564    /// and will be type-checked at compile time.
565    ///
566    /// # Examples
567    ///
568    /// ```rust
569    /// # mod drizzle {
570    /// #     pub mod core { pub use drizzle_core::*; }
571    /// #     pub mod error { pub use drizzle_core::error::*; }
572    /// #     pub mod types { pub use drizzle_types::*; }
573    /// #     pub mod migrations { pub use drizzle_migrations::*; }
574    /// #     pub use drizzle_types::Dialect;
575    /// #     pub use drizzle_types as ddl;
576    /// #     pub mod sqlite {
577    /// #         pub use drizzle_sqlite::*;
578    /// #         pub mod prelude {
579    /// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
580    /// #             pub use drizzle_sqlite::{*, attrs::*};
581    /// #             pub use drizzle_core::*;
582    /// #         }
583    /// #     }
584    /// # }
585    /// # use drizzle::sqlite::prelude::*;
586    /// # use drizzle::sqlite::builder::QueryBuilder;
587    /// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
588    /// # #[derive(SQLiteSchema)] struct Schema { user: User }
589    /// # let builder = QueryBuilder::new::<Schema>();
590    /// # let Schema { user } = Schema::new();
591    /// let query = builder
592    ///     .insert(user)
593    ///     .values([InsertUser::new("Alice")]);
594    /// assert_eq!(query.to_sql().sql(), r#"INSERT INTO "users" ("name") VALUES (?)"#);
595    /// ```
596    pub fn insert<Table>(
597        &self,
598        table: Table,
599    ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
600    where
601        Table: SQLiteTable<'a>,
602    {
603        let sql = crate::helpers::insert(table);
604
605        insert::InsertBuilder {
606            sql,
607            schema: PhantomData,
608            state: PhantomData,
609            table: PhantomData,
610        }
611    }
612
613    /// Begins an UPDATE query for the specified table.
614    ///
615    /// This method starts building an UPDATE statement. The table must be part of the schema
616    /// and will be type-checked at compile time.
617    ///
618    /// # Examples
619    ///
620    /// ```rust
621    /// # mod drizzle {
622    /// #     pub mod core { pub use drizzle_core::*; }
623    /// #     pub mod error { pub use drizzle_core::error::*; }
624    /// #     pub mod types { pub use drizzle_types::*; }
625    /// #     pub mod migrations { pub use drizzle_migrations::*; }
626    /// #     pub use drizzle_types::Dialect;
627    /// #     pub use drizzle_types as ddl;
628    /// #     pub mod sqlite {
629    /// #         pub use drizzle_sqlite::*;
630    /// #         pub mod prelude {
631    /// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
632    /// #             pub use drizzle_sqlite::{*, attrs::*};
633    /// #             pub use drizzle_core::*;
634    /// #         }
635    /// #     }
636    /// # }
637    /// # use drizzle::sqlite::prelude::*;
638    /// # use drizzle::core::expr::eq;
639    /// # use drizzle::sqlite::builder::QueryBuilder;
640    /// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
641    /// # #[derive(SQLiteSchema)] struct Schema { user: User }
642    /// # let builder = QueryBuilder::new::<Schema>();
643    /// # let Schema { user } = Schema::new();
644    /// let query = builder
645    ///     .update(user)
646    ///     .set(UpdateUser::default().with_name("Bob"))
647    ///     .r#where(eq(user.id, 1));
648    /// assert_eq!(query.to_sql().sql(), r#"UPDATE "users" SET "name" = ? WHERE "users"."id" = ?"#);
649    /// ```
650    pub fn update<Table>(
651        &self,
652        table: Table,
653    ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
654    where
655        Table: SQLiteTable<'a>,
656    {
657        let sql = crate::helpers::update::<'a, Table, SQLiteSchemaType, SQLiteValue<'a>>(table);
658
659        update::UpdateBuilder {
660            sql,
661            schema: PhantomData,
662            state: PhantomData,
663            table: PhantomData,
664        }
665    }
666
667    /// Begins a DELETE query for the specified table.
668    ///
669    /// This method starts building a DELETE statement. The table must be part of the schema
670    /// and will be type-checked at compile time.
671    ///
672    /// # Examples
673    ///
674    /// ```rust
675    /// # mod drizzle {
676    /// #     pub mod core { pub use drizzle_core::*; }
677    /// #     pub mod error { pub use drizzle_core::error::*; }
678    /// #     pub mod types { pub use drizzle_types::*; }
679    /// #     pub mod migrations { pub use drizzle_migrations::*; }
680    /// #     pub use drizzle_types::Dialect;
681    /// #     pub use drizzle_types as ddl;
682    /// #     pub mod sqlite {
683    /// #         pub use drizzle_sqlite::*;
684    /// #         pub mod prelude {
685    /// #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
686    /// #             pub use drizzle_sqlite::{*, attrs::*};
687    /// #             pub use drizzle_core::*;
688    /// #         }
689    /// #     }
690    /// # }
691    /// # use drizzle::sqlite::prelude::*;
692    /// # use drizzle::core::expr::lt;
693    /// # use drizzle::sqlite::builder::QueryBuilder;
694    /// # #[SQLiteTable(name = "users")] struct User { #[column(primary)] id: i32, name: String }
695    /// # #[derive(SQLiteSchema)] struct Schema { user: User }
696    /// # let builder = QueryBuilder::new::<Schema>();
697    /// # let Schema { user } = Schema::new();
698    /// let query = builder
699    ///     .delete(user)
700    ///     .r#where(lt(user.id, 10));
701    /// assert_eq!(query.to_sql().sql(), r#"DELETE FROM "users" WHERE "users"."id" < ?"#);
702    /// ```
703    pub fn delete<Table>(
704        &self,
705        table: Table,
706    ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
707    where
708        Table: SQLiteTable<'a>,
709    {
710        let sql = crate::helpers::delete::<'a, Table, SQLiteSchemaType, SQLiteValue<'a>>(table);
711
712        delete::DeleteBuilder {
713            sql,
714            schema: PhantomData,
715            state: PhantomData,
716            table: PhantomData,
717        }
718    }
719
720    pub fn with<C>(&self, cte: C) -> QueryBuilder<'a, Schema, CTEInit>
721    where
722        C: CTEDefinition<'a>,
723    {
724        let sql = SQL::from(Token::WITH).append(cte.cte_definition());
725        QueryBuilder {
726            sql,
727            schema: PhantomData,
728            state: PhantomData,
729            table: PhantomData,
730        }
731    }
732}
733
734#[cfg(test)]
735mod tests {
736    use super::*;
737
738    #[test]
739    fn test_query_builder_new() {
740        let qb = QueryBuilder::new::<()>();
741        let sql = qb.to_sql();
742        assert_eq!(sql.sql(), "");
743        assert_eq!(sql.params().count(), 0);
744    }
745
746    #[test]
747    fn test_builder_init_type() {
748        let _state = BuilderInit;
749    }
750}