es_entity/
one_time_executor.rs1use crate::operation::AtomicOperation;
4
5pub struct OneTimeExecutor<'c, E>
25where
26 E: sqlx::PgExecutor<'c>,
27{
28 now: Option<chrono::DateTime<chrono::Utc>>,
29 executor: E,
30 _phantom: std::marker::PhantomData<&'c ()>,
31}
32
33impl<'c, E> OneTimeExecutor<'c, E>
34where
35 E: sqlx::PgExecutor<'c>,
36{
37 fn new(executor: E, now: Option<chrono::DateTime<chrono::Utc>>) -> Self {
38 OneTimeExecutor {
39 executor,
40 now,
41 _phantom: std::marker::PhantomData,
42 }
43 }
44
45 pub fn maybe_now(&self) -> Option<chrono::DateTime<chrono::Utc>> {
46 self.now
47 }
48
49 pub async fn fetch_one<'q, F, O, A>(
51 self,
52 query: sqlx::query::Map<'q, sqlx::Postgres, F, A>,
53 ) -> Result<O, sqlx::Error>
54 where
55 F: FnMut(sqlx::postgres::PgRow) -> Result<O, sqlx::Error> + Send,
56 O: Send + Unpin,
57 A: 'q + Send + sqlx::IntoArguments<'q, sqlx::Postgres>,
58 {
59 query.fetch_one(self.executor).await
60 }
61
62 pub async fn fetch_all<'q, F, O, A>(
64 self,
65 query: sqlx::query::Map<'q, sqlx::Postgres, F, A>,
66 ) -> Result<Vec<O>, sqlx::Error>
67 where
68 F: FnMut(sqlx::postgres::PgRow) -> Result<O, sqlx::Error> + Send,
69 O: Send + Unpin,
70 A: 'q + Send + sqlx::IntoArguments<'q, sqlx::Postgres>,
71 {
72 query.fetch_all(self.executor).await
73 }
74
75 pub async fn fetch_optional<'q, F, O, A>(
77 self,
78 query: sqlx::query::Map<'q, sqlx::Postgres, F, A>,
79 ) -> Result<Option<O>, sqlx::Error>
80 where
81 F: FnMut(sqlx::postgres::PgRow) -> Result<O, sqlx::Error> + Send,
82 O: Send + Unpin,
83 A: 'q + Send + sqlx::IntoArguments<'q, sqlx::Postgres>,
84 {
85 query.fetch_optional(self.executor).await
86 }
87}
88
89pub trait IntoOneTimeExecutor<'c>: IntoOneTimeExecutorAt<'c> + 'c {}
100impl<'c, T> IntoOneTimeExecutor<'c> for T where T: IntoOneTimeExecutorAt<'c> + 'c {}
101
102pub trait IntoOneTimeExecutorAt<'c> {
107 type Executor: sqlx::PgExecutor<'c>;
109
110 fn into_executor(self) -> OneTimeExecutor<'c, Self::Executor>
112 where
113 Self: 'c;
114}
115
116impl<'c, E> IntoOneTimeExecutorAt<'c> for OneTimeExecutor<'c, E>
117where
118 E: sqlx::PgExecutor<'c> + 'c,
119{
120 type Executor = E;
121
122 fn into_executor(self) -> OneTimeExecutor<'c, Self::Executor>
123 where
124 Self: 'c,
125 {
126 self
127 }
128}
129
130impl<'c> IntoOneTimeExecutorAt<'c> for &sqlx::PgPool {
131 type Executor = &'c sqlx::PgPool;
132
133 fn into_executor(self) -> OneTimeExecutor<'c, Self::Executor>
134 where
135 Self: 'c,
136 {
137 OneTimeExecutor::new(self, None)
138 }
139}
140
141impl<'c, O> IntoOneTimeExecutorAt<'c> for &mut O
142where
143 O: AtomicOperation,
144{
145 type Executor = &'c mut sqlx::PgConnection;
146
147 fn into_executor(self) -> OneTimeExecutor<'c, Self::Executor>
148 where
149 Self: 'c,
150 {
151 let now = self.maybe_now();
152 OneTimeExecutor::new(self.as_executor(), now)
153 }
154}