cratestack_sqlx/query/read/
find_many_with.rs1use cratestack_core::{CoolContext, CoolError};
7
8use crate::{FilterExpr, OrderClause, sqlx};
9
10use super::find_many::FindMany;
11use super::side_load::run_side_load;
12
13#[derive(Debug, Clone)]
14pub struct FindManyWith<'a, M: 'static, PK: 'static, Rel: 'static, RelPK: 'static> {
15 parent: FindMany<'a, M, PK>,
16 relation: cratestack_sql::RelationInclude<M, Rel, RelPK>,
17}
18
19impl<'a, M: 'static, PK: 'static, Rel: 'static, RelPK: 'static>
20 FindManyWith<'a, M, PK, Rel, RelPK>
21{
22 pub(super) fn new(
23 parent: FindMany<'a, M, PK>,
24 relation: cratestack_sql::RelationInclude<M, Rel, RelPK>,
25 ) -> Self {
26 Self { parent, relation }
27 }
28
29 pub fn where_(mut self, filter: crate::Filter) -> Self {
30 self.parent = self.parent.where_(filter);
31 self
32 }
33
34 pub fn where_expr(mut self, filter: FilterExpr) -> Self {
35 self.parent = self.parent.where_expr(filter);
36 self
37 }
38
39 pub fn where_any(mut self, filters: impl IntoIterator<Item = FilterExpr>) -> Self {
40 self.parent = self.parent.where_any(filters);
41 self
42 }
43
44 pub fn where_optional<F>(mut self, filter: Option<F>) -> Self
45 where
46 F: Into<FilterExpr>,
47 {
48 self.parent = self.parent.where_optional(filter);
49 self
50 }
51
52 pub fn order_by(mut self, clause: OrderClause) -> Self {
53 self.parent = self.parent.order_by(clause);
54 self
55 }
56
57 pub fn limit(mut self, limit: i64) -> Self {
58 self.parent = self.parent.limit(limit);
59 self
60 }
61
62 pub fn offset(mut self, offset: i64) -> Self {
63 self.parent = self.parent.offset(offset);
64 self
65 }
66
67 pub fn for_update(mut self) -> Self {
72 self.parent = self.parent.for_update();
73 self
74 }
75
76 pub async fn run(self, ctx: &CoolContext) -> Result<Vec<(M, Option<Rel>)>, CoolError>
77 where
78 M: Clone,
79 for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
80 Rel: Clone,
81 for<'r> Rel:
82 Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + cratestack_sql::ModelPrimaryKey<RelPK>,
83 RelPK: Send
84 + Clone
85 + std::cmp::Eq
86 + std::hash::Hash
87 + cratestack_sql::IntoSqlValue
88 + sqlx::Type<sqlx::Postgres>
89 + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
90 {
91 let runtime = self.parent.runtime;
92 let relation = self.relation;
93 let parents = self.parent.run(ctx).await?;
94 run_side_load(runtime, &parents, relation, ctx, None::<&mut sqlx::Transaction<'_, sqlx::Postgres>>).await
95 }
96
97 pub async fn run_in_tx<'tx>(
98 self,
99 tx: &mut sqlx::Transaction<'tx, sqlx::Postgres>,
100 ctx: &CoolContext,
101 ) -> Result<Vec<(M, Option<Rel>)>, CoolError>
102 where
103 M: Clone,
104 for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
105 Rel: Clone,
106 for<'r> Rel:
107 Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + cratestack_sql::ModelPrimaryKey<RelPK>,
108 RelPK: Send
109 + Clone
110 + std::cmp::Eq
111 + std::hash::Hash
112 + cratestack_sql::IntoSqlValue
113 + sqlx::Type<sqlx::Postgres>
114 + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
115 {
116 let runtime = self.parent.runtime;
117 let relation = self.relation;
118 let parents = self.parent.run_in_tx(tx, ctx).await?;
119 run_side_load(runtime, &parents, relation, ctx, Some(tx)).await
120 }
121}