Skip to main content

cratestack_sqlx/delegate/
scoped_update_many.rs

1//! `update_many().where_(...).set(...)` wrappers — predicate-driven
2//! bulk UPDATE bound to a `CratestackContext`.
3
4use cratestack_core::{CratestackContext, CratestackError};
5
6use crate::audit::RunInTxOutcome;
7use crate::{Filter, FilterExpr, UpdateMany, UpdateManySet, UpdateModelInput, sqlx};
8
9#[derive(Debug, Clone)]
10pub struct ScopedUpdateMany<'a, M: 'static, PK: 'static> {
11    request: UpdateMany<'a, M, PK>,
12    ctx: CratestackContext,
13}
14
15impl<'a, M: 'static, PK: 'static> ScopedUpdateMany<'a, M, PK> {
16    pub(super) fn new(request: UpdateMany<'a, M, PK>, ctx: CratestackContext) -> Self {
17        Self { request, ctx }
18    }
19
20    pub fn where_(mut self, filter: Filter) -> Self {
21        self.request = self.request.where_(filter);
22        self
23    }
24
25    pub fn where_expr(mut self, filter: FilterExpr) -> Self {
26        self.request = self.request.where_expr(filter);
27        self
28    }
29
30    pub fn where_any(mut self, filters: impl IntoIterator<Item = FilterExpr>) -> Self {
31        self.request = self.request.where_any(filters);
32        self
33    }
34
35    /// See [`UpdateMany::where_optional`].
36    pub fn where_optional<F>(mut self, filter: Option<F>) -> Self
37    where
38        F: Into<FilterExpr>,
39    {
40        self.request = self.request.where_optional(filter);
41        self
42    }
43
44    pub fn set<I>(self, input: I) -> ScopedUpdateManySet<'a, M, PK, I> {
45        ScopedUpdateManySet {
46            request: self.request.set(input),
47            ctx: self.ctx,
48        }
49    }
50}
51
52#[derive(Debug, Clone)]
53pub struct ScopedUpdateManySet<'a, M: 'static, PK: 'static, I> {
54    request: UpdateManySet<'a, M, PK, I>,
55    ctx: CratestackContext,
56}
57
58impl<'a, M: 'static, PK: 'static, I> ScopedUpdateManySet<'a, M, PK, I>
59where
60    I: UpdateModelInput<M>,
61{
62    pub fn preview_sql(&self) -> String {
63        self.request.preview_sql()
64    }
65
66    pub async fn run(self) -> Result<cratestack_core::BatchSummary, CratestackError>
67    where
68        for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + serde::Serialize,
69    {
70        self.request.run(&self.ctx).await
71    }
72
73    pub async fn run_in_tx<'tx>(
74        self,
75        tx: &mut sqlx::Transaction<'tx, sqlx::Postgres>,
76    ) -> Result<RunInTxOutcome<cratestack_core::BatchSummary>, CratestackError>
77    where
78        for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + serde::Serialize,
79    {
80        self.request.run_in_tx(tx, &self.ctx).await
81    }
82}