Skip to main content

cratestack_sqlx/delegate/
scoped_find_many_with.rs

1//! Context-bound wrapper around [`crate::FindManyWith`] —
2//! `find_many().include(...)` resolved against a `CoolContext`.
3
4use cratestack_core::{CoolContext, CoolError};
5
6use crate::{Filter, FilterExpr, OrderClause, sqlx};
7
8#[derive(Debug, Clone)]
9pub struct ScopedFindManyWith<'a, M: 'static, PK: 'static, Rel: 'static, RelPK: 'static> {
10    pub(super) request: crate::FindManyWith<'a, M, PK, Rel, RelPK>,
11    pub(super) ctx: CoolContext,
12}
13
14impl<'a, M: 'static, PK: 'static, Rel: 'static, RelPK: 'static>
15    ScopedFindManyWith<'a, M, PK, Rel, RelPK>
16{
17    pub(super) fn new(
18        request: crate::FindManyWith<'a, M, PK, Rel, RelPK>,
19        ctx: CoolContext,
20    ) -> Self {
21        Self { request, ctx }
22    }
23
24    pub fn where_(mut self, filter: Filter) -> Self {
25        self.request = self.request.where_(filter);
26        self
27    }
28
29    pub fn where_expr(mut self, filter: FilterExpr) -> Self {
30        self.request = self.request.where_expr(filter);
31        self
32    }
33
34    pub fn where_any(mut self, filters: impl IntoIterator<Item = FilterExpr>) -> Self {
35        self.request = self.request.where_any(filters);
36        self
37    }
38
39    pub fn where_optional<F>(mut self, filter: Option<F>) -> Self
40    where
41        F: Into<FilterExpr>,
42    {
43        self.request = self.request.where_optional(filter);
44        self
45    }
46
47    pub fn order_by(mut self, clause: OrderClause) -> Self {
48        self.request = self.request.order_by(clause);
49        self
50    }
51
52    pub fn limit(mut self, limit: i64) -> Self {
53        self.request = self.request.limit(limit);
54        self
55    }
56
57    pub fn offset(mut self, offset: i64) -> Self {
58        self.request = self.request.offset(offset);
59        self
60    }
61
62    /// See [`crate::FindManyWith::for_update`].
63    pub fn for_update(mut self) -> Self {
64        self.request = self.request.for_update();
65        self
66    }
67
68    pub async fn run(self) -> Result<Vec<(M, Option<Rel>)>, CoolError>
69    where
70        M: Clone,
71        for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
72        Rel: Clone,
73        for<'r> Rel: Send
74            + Unpin
75            + sqlx::FromRow<'r, sqlx::postgres::PgRow>
76            + cratestack_sql::ModelPrimaryKey<RelPK>,
77        RelPK: Send
78            + Clone
79            + std::cmp::Eq
80            + std::hash::Hash
81            + cratestack_sql::IntoSqlValue
82            + sqlx::Type<sqlx::Postgres>
83            + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
84    {
85        self.request.run(&self.ctx).await
86    }
87
88    pub async fn run_in_tx<'tx>(
89        self,
90        tx: &mut sqlx::Transaction<'tx, sqlx::Postgres>,
91    ) -> Result<Vec<(M, Option<Rel>)>, CoolError>
92    where
93        M: Clone,
94        for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
95        Rel: Clone,
96        for<'r> Rel: Send
97            + Unpin
98            + sqlx::FromRow<'r, sqlx::postgres::PgRow>
99            + cratestack_sql::ModelPrimaryKey<RelPK>,
100        RelPK: Send
101            + Clone
102            + std::cmp::Eq
103            + std::hash::Hash
104            + cratestack_sql::IntoSqlValue
105            + sqlx::Type<sqlx::Postgres>
106            + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
107    {
108        self.request.run_in_tx(tx, &self.ctx).await
109    }
110}