Skip to main content

drizzle_postgres/builder/
delete.rs

1use crate::values::PostgresValue;
2use core::fmt::Debug;
3use core::marker::PhantomData;
4use drizzle_core::ToSQL;
5
6// Import the ExecutableState trait
7use super::ExecutableState;
8
9//------------------------------------------------------------------------------
10// Type State Markers
11//------------------------------------------------------------------------------
12
13/// Marker for the initial state of `DeleteBuilder`
14#[derive(Debug, Clone, Copy, Default)]
15pub struct DeleteInitial;
16
17/// Marker for the state after WHERE clause
18#[derive(Debug, Clone, Copy, Default)]
19pub struct DeleteWhereSet;
20
21/// Marker for the state after RETURNING clause
22#[derive(Debug, Clone, Copy, Default)]
23pub struct DeleteReturningSet;
24
25// Mark states that can execute delete queries
26impl ExecutableState for DeleteInitial {}
27impl ExecutableState for DeleteWhereSet {}
28impl ExecutableState for DeleteReturningSet {}
29
30//------------------------------------------------------------------------------
31// DeleteBuilder Definition
32//------------------------------------------------------------------------------
33
34/// Builds a DELETE query specifically for `PostgreSQL`
35pub type DeleteBuilder<'a, Schema, State, Table, Marker = (), Row = ()> =
36    super::QueryBuilder<'a, Schema, State, Table, Marker, Row>;
37
38type ReturningMarker<Table, Columns> = drizzle_core::Scoped<
39    <Columns as drizzle_core::IntoSelectTarget>::Marker,
40    drizzle_core::Cons<Table, drizzle_core::Nil>,
41>;
42
43type ReturningRow<Table, Columns> =
44    <<Columns as drizzle_core::IntoSelectTarget>::Marker as drizzle_core::ResolveRow<Table>>::Row;
45
46type ReturningBuilder<'a, S, T, Columns> = DeleteBuilder<
47    'a,
48    S,
49    DeleteReturningSet,
50    T,
51    ReturningMarker<T, Columns>,
52    ReturningRow<T, Columns>,
53>;
54
55//------------------------------------------------------------------------------
56// Initial State Implementation
57//------------------------------------------------------------------------------
58
59impl<'a, S, T> DeleteBuilder<'a, S, DeleteInitial, T> {
60    /// Adds a WHERE condition to the query
61    #[inline]
62    pub fn r#where<E>(self, condition: E) -> DeleteBuilder<'a, S, DeleteWhereSet, T>
63    where
64        E: drizzle_core::expr::Expr<'a, PostgresValue<'a>>,
65        E::SQLType: drizzle_core::types::BooleanLike,
66    {
67        let where_sql = crate::helpers::r#where(condition);
68        DeleteBuilder {
69            sql: self.sql.append(where_sql),
70            schema: PhantomData,
71            state: PhantomData,
72            table: PhantomData,
73            marker: PhantomData,
74            row: PhantomData,
75            grouped: PhantomData,
76        }
77    }
78
79    /// Adds a RETURNING clause to the query
80    #[inline]
81    pub fn returning<Columns>(self, columns: Columns) -> ReturningBuilder<'a, S, T, Columns>
82    where
83        Columns: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
84        Columns::Marker: drizzle_core::ResolveRow<T>,
85    {
86        let returning_sql = crate::helpers::returning(columns);
87        DeleteBuilder {
88            sql: self.sql.append(returning_sql),
89            schema: PhantomData,
90            state: PhantomData,
91            table: PhantomData,
92            marker: PhantomData,
93            row: PhantomData,
94            grouped: PhantomData,
95        }
96    }
97}
98
99//------------------------------------------------------------------------------
100// Post-WHERE Implementation
101//------------------------------------------------------------------------------
102
103impl<'a, S, T> DeleteBuilder<'a, S, DeleteWhereSet, T> {
104    /// Adds a RETURNING clause after WHERE
105    #[inline]
106    pub fn returning<Columns>(self, columns: Columns) -> ReturningBuilder<'a, S, T, Columns>
107    where
108        Columns: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
109        Columns::Marker: drizzle_core::ResolveRow<T>,
110    {
111        let returning_sql = crate::helpers::returning(columns);
112        DeleteBuilder {
113            sql: self.sql.append(returning_sql),
114            schema: PhantomData,
115            state: PhantomData,
116            table: PhantomData,
117            marker: PhantomData,
118            row: PhantomData,
119            grouped: PhantomData,
120        }
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127    use drizzle_core::{SQL, ToSQL};
128
129    #[test]
130    fn test_delete_builder_creation() {
131        let builder = DeleteBuilder::<(), DeleteInitial, ()> {
132            sql: SQL::raw("DELETE FROM test"),
133            schema: PhantomData,
134            state: PhantomData,
135            table: PhantomData,
136            marker: PhantomData,
137            row: PhantomData,
138            grouped: PhantomData,
139        };
140
141        assert_eq!(builder.to_sql().sql(), "DELETE FROM test");
142    }
143}