cratestack_sqlx/query/read/
find_many_with.rs1use cratestack_core::{CratestackContext, CratestackError};
7
8use crate::{FilterExpr, OrderClause, sqlx};
9
10use super::find_many::FindMany;
11use super::side_load::run_side_load;
12
13#[derive(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(
77 self,
78 ctx: &CratestackContext,
79 ) -> Result<Vec<(M, Option<Rel>)>, CratestackError>
80 where
81 M: Clone,
82 for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
83 Rel: Clone,
84 for<'r> Rel: Send
85 + Unpin
86 + sqlx::FromRow<'r, sqlx::postgres::PgRow>
87 + cratestack_sql::ModelPrimaryKey<RelPK>,
88 RelPK: Send
89 + Clone
90 + std::cmp::Eq
91 + std::hash::Hash
92 + cratestack_sql::IntoSqlValue
93 + sqlx::Type<sqlx::Postgres>
94 + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
95 {
96 let runtime = self.parent.runtime;
97 let relation = self.relation;
98 let parents = self.parent.run(ctx).await?;
99 run_side_load(
100 runtime,
101 &parents,
102 relation,
103 ctx,
104 None::<&mut sqlx::Transaction<'_, sqlx::Postgres>>,
105 )
106 .await
107 }
108
109 pub async fn run_in_tx<'tx>(
110 self,
111 tx: &mut sqlx::Transaction<'tx, sqlx::Postgres>,
112 ctx: &CratestackContext,
113 ) -> Result<Vec<(M, Option<Rel>)>, CratestackError>
114 where
115 M: Clone,
116 for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
117 Rel: Clone,
118 for<'r> Rel: Send
119 + Unpin
120 + sqlx::FromRow<'r, sqlx::postgres::PgRow>
121 + cratestack_sql::ModelPrimaryKey<RelPK>,
122 RelPK: Send
123 + Clone
124 + std::cmp::Eq
125 + std::hash::Hash
126 + cratestack_sql::IntoSqlValue
127 + sqlx::Type<sqlx::Postgres>
128 + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
129 {
130 let runtime = self.parent.runtime;
131 let relation = self.relation;
132 let parents = self.parent.run_in_tx(tx, ctx).await?;
133 run_side_load(runtime, &parents, relation, ctx, Some(tx)).await
134 }
135}