Skip to main content

cratestack_sqlx/delegate/
scoped_batch.rs

1//! Thin lifetime-and-context shims around the unscoped batch
2//! builders. The shape mirrors the existing single-row scoped wrappers:
3//! capture the request-bound `CoolContext` once at `.bind(ctx)` time,
4//! thread it into `.run()` automatically.
5
6use std::hash::Hash;
7
8use cratestack_core::{BatchResponse, CoolContext, CoolError};
9
10use crate::{
11    BatchCreate, BatchDelete, BatchGet, BatchUpdate, BatchUpsert, CreateModelInput,
12    UpdateModelInput, UpsertModelInput, sqlx,
13};
14
15#[derive(Debug, Clone)]
16pub struct ScopedBatchGet<'a, M: 'static, PK: 'static> {
17    request: BatchGet<'a, M, PK>,
18    ctx: CoolContext,
19}
20
21impl<'a, M: 'static, PK: 'static> ScopedBatchGet<'a, M, PK> {
22    pub(super) fn new(request: BatchGet<'a, M, PK>, ctx: CoolContext) -> Self {
23        Self { request, ctx }
24    }
25
26    pub async fn run(self) -> Result<BatchResponse<M>, CoolError>
27    where
28        for<'r> M:
29            Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + crate::ModelPrimaryKey<PK>,
30        PK: Clone
31            + Eq
32            + Hash
33            + Send
34            + sqlx::Type<sqlx::Postgres>
35            + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
36    {
37        self.request.run(&self.ctx).await
38    }
39}
40
41#[derive(Debug, Clone)]
42pub struct ScopedBatchCreate<'a, M: 'static, PK: 'static, I> {
43    request: BatchCreate<'a, M, PK, I>,
44    ctx: CoolContext,
45}
46
47impl<'a, M: 'static, PK: 'static, I> ScopedBatchCreate<'a, M, PK, I> {
48    pub(super) fn new(request: BatchCreate<'a, M, PK, I>, ctx: CoolContext) -> Self {
49        Self { request, ctx }
50    }
51}
52
53impl<'a, M: 'static, PK: 'static, I> ScopedBatchCreate<'a, M, PK, I>
54where
55    I: CreateModelInput<M> + Send,
56{
57    pub async fn run(self) -> Result<BatchResponse<M>, CoolError>
58    where
59        for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + serde::Serialize,
60    {
61        self.request.run(&self.ctx).await
62    }
63}
64
65#[derive(Debug, Clone)]
66pub struct ScopedBatchUpdate<'a, M: 'static, PK: 'static, I> {
67    request: BatchUpdate<'a, M, PK, I>,
68    ctx: CoolContext,
69}
70
71impl<'a, M: 'static, PK: 'static, I> ScopedBatchUpdate<'a, M, PK, I> {
72    pub(super) fn new(request: BatchUpdate<'a, M, PK, I>, ctx: CoolContext) -> Self {
73        Self { request, ctx }
74    }
75}
76
77impl<'a, M: 'static, PK: 'static, I> ScopedBatchUpdate<'a, M, PK, I>
78where
79    I: UpdateModelInput<M> + Send,
80{
81    pub async fn run(self) -> Result<BatchResponse<M>, CoolError>
82    where
83        for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + serde::Serialize,
84        PK: Clone
85            + Eq
86            + Hash
87            + Send
88            + sqlx::Type<sqlx::Postgres>
89            + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
90    {
91        self.request.run(&self.ctx).await
92    }
93}
94
95#[derive(Debug, Clone)]
96pub struct ScopedBatchDelete<'a, M: 'static, PK: 'static> {
97    request: BatchDelete<'a, M, PK>,
98    ctx: CoolContext,
99}
100
101impl<'a, M: 'static, PK: 'static> ScopedBatchDelete<'a, M, PK> {
102    pub(super) fn new(request: BatchDelete<'a, M, PK>, ctx: CoolContext) -> Self {
103        Self { request, ctx }
104    }
105
106    pub async fn run(self) -> Result<BatchResponse<M>, CoolError>
107    where
108        for<'r> M: Send
109            + Unpin
110            + sqlx::FromRow<'r, sqlx::postgres::PgRow>
111            + crate::ModelPrimaryKey<PK>
112            + serde::Serialize,
113        PK: Clone
114            + Eq
115            + Hash
116            + Send
117            + sqlx::Type<sqlx::Postgres>
118            + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
119    {
120        self.request.run(&self.ctx).await
121    }
122}
123
124#[derive(Debug, Clone)]
125pub struct ScopedBatchUpsert<'a, M: 'static, PK: 'static, I> {
126    request: BatchUpsert<'a, M, PK, I>,
127    ctx: CoolContext,
128}
129
130impl<'a, M: 'static, PK: 'static, I> ScopedBatchUpsert<'a, M, PK, I> {
131    pub(super) fn new(request: BatchUpsert<'a, M, PK, I>, ctx: CoolContext) -> Self {
132        Self { request, ctx }
133    }
134}
135
136impl<'a, M: 'static, PK: 'static, I> ScopedBatchUpsert<'a, M, PK, I>
137where
138    I: UpsertModelInput<M>,
139{
140    pub async fn run(self) -> Result<BatchResponse<M>, CoolError>
141    where
142        for<'r> M: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + serde::Serialize,
143        PK: Send + sqlx::Type<sqlx::Postgres> + for<'q> sqlx::Encode<'q, sqlx::Postgres>,
144    {
145        self.request.run(&self.ctx).await
146    }
147}