drizzle_postgres/builder/
update.rs

1use crate::ToPostgresSQL;
2use crate::common::PostgresSchemaType;
3use crate::values::PostgresValue;
4use drizzle_core::{SQL, SQLTable};
5use std::fmt::Debug;
6use std::marker::PhantomData;
7
8// Import the ExecutableState trait
9use super::ExecutableState;
10
11//------------------------------------------------------------------------------
12// Type State Markers
13//------------------------------------------------------------------------------
14
15/// Marker for the initial state of UpdateBuilder
16#[derive(Debug, Clone, Copy, Default)]
17pub struct UpdateInitial;
18
19/// Marker for the state after SET clause
20#[derive(Debug, Clone, Copy, Default)]
21pub struct UpdateSetClauseSet;
22
23/// Marker for the state after WHERE clause
24#[derive(Debug, Clone, Copy, Default)]
25pub struct UpdateWhereSet;
26
27/// Marker for the state after RETURNING clause
28#[derive(Debug, Clone, Copy, Default)]
29pub struct UpdateReturningSet;
30
31// Mark states that can execute update queries
32impl ExecutableState for UpdateSetClauseSet {}
33impl ExecutableState for UpdateWhereSet {}
34impl ExecutableState for UpdateReturningSet {}
35
36//------------------------------------------------------------------------------
37// UpdateBuilder Definition
38//------------------------------------------------------------------------------
39
40/// Builds an UPDATE query specifically for PostgreSQL
41pub type UpdateBuilder<'a, Schema, State, Table> = super::QueryBuilder<'a, Schema, State, Table>;
42
43//------------------------------------------------------------------------------
44// Initial State Implementation
45//------------------------------------------------------------------------------
46
47impl<'a, Schema, Table> UpdateBuilder<'a, Schema, UpdateInitial, Table>
48where
49    Table: SQLTable<'a, PostgresSchemaType, PostgresValue<'a>>,
50{
51    /// Sets the values to update and transitions to the SetClauseSet state
52    #[inline]
53    pub fn set(
54        self,
55        values: Table::Update,
56    ) -> UpdateBuilder<'a, Schema, UpdateSetClauseSet, Table> {
57        let sql = crate::helpers::set::<'a, Table, PostgresSchemaType, PostgresValue<'a>>(values);
58        UpdateBuilder {
59            sql: self.sql.append(sql),
60            schema: PhantomData,
61            state: PhantomData,
62            table: PhantomData,
63        }
64    }
65}
66
67//------------------------------------------------------------------------------
68// Post-SET Implementation
69//------------------------------------------------------------------------------
70
71impl<'a, S, T> UpdateBuilder<'a, S, UpdateSetClauseSet, T> {
72    /// Adds a WHERE condition and transitions to the WhereSet state
73    #[inline]
74    pub fn r#where(
75        self,
76        condition: SQL<'a, PostgresValue<'a>>,
77    ) -> UpdateBuilder<'a, S, UpdateWhereSet, T> {
78        let where_sql = crate::helpers::r#where(condition);
79        UpdateBuilder {
80            sql: self.sql.append(where_sql),
81            schema: PhantomData,
82            state: PhantomData,
83            table: PhantomData,
84        }
85    }
86
87    /// Adds a RETURNING clause and transitions to the ReturningSet state
88    #[inline]
89    pub fn returning(
90        self,
91        columns: impl ToPostgresSQL<'a>,
92    ) -> UpdateBuilder<'a, S, UpdateReturningSet, T> {
93        let returning_sql = crate::helpers::returning(columns);
94        UpdateBuilder {
95            sql: self.sql.append(returning_sql),
96            schema: PhantomData,
97            state: PhantomData,
98            table: PhantomData,
99        }
100    }
101}
102
103//------------------------------------------------------------------------------
104// Post-WHERE Implementation
105//------------------------------------------------------------------------------
106
107impl<'a, S, T> UpdateBuilder<'a, S, UpdateWhereSet, T> {
108    /// Adds a RETURNING clause after WHERE
109    #[inline]
110    pub fn returning(
111        self,
112        columns: impl ToPostgresSQL<'a>,
113    ) -> UpdateBuilder<'a, S, UpdateReturningSet, T> {
114        let returning_sql = crate::helpers::returning(columns);
115        UpdateBuilder {
116            sql: self.sql.append(returning_sql),
117            schema: PhantomData,
118            state: PhantomData,
119            table: 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_update_builder_creation() {
131        let builder = UpdateBuilder::<(), UpdateInitial, ()> {
132            sql: SQL::raw("UPDATE test"),
133            schema: PhantomData,
134            state: PhantomData,
135            table: PhantomData,
136        };
137
138        assert_eq!(builder.to_sql().sql(), "UPDATE test");
139    }
140}