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: Send
82 + Unpin
83 + sqlx::FromRow<'r, sqlx::postgres::PgRow>
84 + cratestack_sql::ModelPrimaryKey<RelPK>,
85 RelPK: Send
86 + Clone
87 + std::cmp::Eq
88 + std::hash::Hash
89 + cratestack_sql::IntoSqlValue
90 + sqlx::Type<sqlx::Postgres>
91 + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
92 {
93 let runtime = self.parent.runtime;
94 let relation = self.relation;
95 let parents = self.parent.run(ctx).await?;
96 run_side_load(
97 runtime,
98 &parents,
99 relation,
100 ctx,
101 None::<&mut sqlx::Transaction<'_, sqlx::Postgres>>,
102 )
103 .await
104 }
105
106 pub async fn run_in_tx<'tx>(
107 self,
108 tx: &mut sqlx::Transaction<'tx, sqlx::Postgres>,
109 ctx: &CoolContext,
110 ) -> Result<Vec<(M, Option<Rel>)>, CoolError>
111 where
112 M: Clone,
113 for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
114 Rel: Clone,
115 for<'r> Rel: Send
116 + Unpin
117 + sqlx::FromRow<'r, sqlx::postgres::PgRow>
118 + cratestack_sql::ModelPrimaryKey<RelPK>,
119 RelPK: Send
120 + Clone
121 + std::cmp::Eq
122 + std::hash::Hash
123 + cratestack_sql::IntoSqlValue
124 + sqlx::Type<sqlx::Postgres>
125 + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
126 {
127 let runtime = self.parent.runtime;
128 let relation = self.relation;
129 let parents = self.parent.run_in_tx(tx, ctx).await?;
130 run_side_load(runtime, &parents, relation, ctx, Some(tx)).await
131 }
132}