Skip to main content

a3s_orm/query/
update.rs

1use std::marker::PhantomData;
2
3use crate::ast::{Assignment, QueryNode, TableNode, UpdateNode};
4use crate::expression::{Column, Expression, Selection};
5use crate::schema::Table;
6use crate::value::IntoSqlValue;
7
8use super::Query;
9
10#[derive(Clone, Debug)]
11pub struct UpdateQuery<T: Table, O = ()> {
12    node: UpdateNode,
13    marker: PhantomData<fn() -> (T, O)>,
14}
15
16pub fn update_table<T: Table>() -> UpdateQuery<T> {
17    UpdateQuery {
18        node: UpdateNode {
19            table: TableNode {
20                name: T::NAME,
21                alias: None,
22            },
23            assignments: Vec::new(),
24            filter: None,
25            returning: Vec::new(),
26        },
27        marker: PhantomData,
28    }
29}
30
31impl<T: Table, O> UpdateQuery<T, O> {
32    pub fn set<V>(mut self, column: Column<T, V>, value: impl IntoSqlValue<V>) -> Self {
33        self.node.assignments.push(Assignment {
34            table: column.table_name(),
35            column: column.name(),
36            value: value.into_sql_value(),
37        });
38        self
39    }
40
41    pub fn filter(mut self, expression: Expression) -> Self {
42        self.node.filter = Some(match self.node.filter.take() {
43            Some(existing) => existing.and(expression),
44            None => expression,
45        });
46        self
47    }
48
49    pub fn returning<S: Selection>(mut self, selection: S) -> UpdateQuery<T, S::Output> {
50        self.node.returning.extend(selection.expressions());
51        UpdateQuery {
52            node: self.node,
53            marker: PhantomData,
54        }
55    }
56}
57
58impl<T: Table, O> Query for UpdateQuery<T, O> {
59    type Output = O;
60
61    fn compile(self, dialect: &impl crate::Dialect) -> crate::Result<crate::CompiledQuery> {
62        crate::compiler::compile(QueryNode::Update(self.node), dialect)
63    }
64}