diesel/query_builder/update_statement/
target.rs

1use crate::associations::{HasTable, Identifiable};
2use crate::dsl::Find;
3use crate::query_dsl::methods::FindDsl;
4use crate::query_source::Table;
5
6#[doc(hidden)]
7#[derive(Debug)]
8pub struct UpdateTarget<Table, WhereClause> {
9    pub table: Table,
10    pub where_clause: WhereClause,
11}
12
13/// A type which can be passed to [`update`] or [`delete`].
14///
15/// Apps will never need to implement this type directly. There are three kinds
16/// which implement this trait. Tables, queries which have only had `filter`
17/// called on them, and types which implement `Identifiable`.
18///
19/// When a table is passed to `update`, every row in the table will be updated.
20/// You can scope this down by calling [`filter`] which will
21/// result in `UPDATE your_table SET ... WHERE args_to_filter`. Passing a type
22/// which implements `Identifiable` is the same as passing
23/// `SomeStruct::table().find(some_struct)`.
24///
25/// [`update`]: crate::update()
26/// [`delete`]: crate::delete()
27/// [`filter`]: crate::query_builder::UpdateStatement::filter()
28#[diagnostic::on_unimplemented(
29    note = "only tables or select statements with only the filter clause applied are valid update targets"
30)]
31pub trait IntoUpdateTarget: HasTable {
32    /// What is the `WHERE` clause of this target?
33    type WhereClause;
34
35    /// Decomposes `self` into the table and where clause.
36    fn into_update_target(self) -> UpdateTarget<Self::Table, Self::WhereClause>;
37}
38
39impl<T, Tab, V> IntoUpdateTarget for T
40where
41    T: Identifiable<Table = Tab>,
42    Tab: Table + FindDsl<T::Id>,
43    Find<Tab, T::Id>: IntoUpdateTarget<Table = Tab, WhereClause = V>,
44{
45    type WhereClause = V;
46
47    fn into_update_target(self) -> UpdateTarget<Self::Table, Self::WhereClause> {
48        T::table().find(self.id()).into_update_target()
49    }
50}