Skip to main content

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