1use sqlx::{Database, Executor};
2
3use crate::execute::{InstrumentedExecute, InstrumentedFetch, InstrumentedPool};
4
5pub struct InstrumentedQueryBuilder<Q> {
6 pub query: Q,
7 pub sql: &'static str,
8}
9
10impl<'q, DB, A> InstrumentedQueryBuilder<sqlx::query::Query<'q, DB, A>>
11where
12 DB: Database,
13 A: 'q + Send + sqlx::IntoArguments<'q, DB>,
14{
15 pub async fn execute<P>(self, pool: &P) -> Result<DB::QueryResult, sqlx::Error>
16 where
17 P: InstrumentedPool<Database = DB> + Send + Sync,
18 for<'c> &'c P: Executor<'c, Database = DB>,
19 {
20 self.query.execute_instrumented(pool, self.sql).await
21 }
22
23 pub async fn fetch_one<P>(self, pool: &P) -> Result<DB::Row, sqlx::Error>
24 where
25 P: InstrumentedPool<Database = DB> + Send + Sync,
26 for<'c> &'c P: Executor<'c, Database = DB>,
27 {
28 self.query.fetch_one_instrumented(pool, self.sql).await
29 }
30
31 pub async fn fetch_optional<P>(self, pool: &P) -> Result<Option<DB::Row>, sqlx::Error>
32 where
33 P: InstrumentedPool<Database = DB> + Send + Sync,
34 for<'c> &'c P: Executor<'c, Database = DB>,
35 {
36 self.query.fetch_optional_instrumented(pool, self.sql).await
37 }
38
39 pub async fn fetch_all<P>(self, pool: &P) -> Result<Vec<DB::Row>, sqlx::Error>
40 where
41 P: InstrumentedPool<Database = DB> + Send + Sync,
42 for<'c> &'c P: Executor<'c, Database = DB>,
43 {
44 self.query.fetch_all_instrumented(pool, self.sql).await
45 }
46}
47
48impl<'q, DB, F, A, O> InstrumentedQueryBuilder<sqlx::query::Map<'q, DB, F, A>>
50where
51 DB: Database,
52 F: FnMut(DB::Row) -> Result<O, sqlx::Error> + Send,
53 O: Send + Unpin,
54 A: 'q + Send + sqlx::IntoArguments<'q, DB>,
55{
56 pub async fn fetch_one<P>(self, pool: &P) -> Result<O, sqlx::Error>
57 where
58 P: InstrumentedPool<Database = DB> + Send + Sync,
59 for<'c> &'c P: Executor<'c, Database = DB>,
60 {
61 self.query.fetch_one_instrumented(pool, self.sql).await
62 }
63
64 pub async fn fetch_optional<P>(self, pool: &P) -> Result<Option<O>, sqlx::Error>
65 where
66 P: InstrumentedPool<Database = DB> + Send + Sync,
67 for<'c> &'c P: Executor<'c, Database = DB>,
68 {
69 self.query.fetch_optional_instrumented(pool, self.sql).await
70 }
71
72 pub async fn fetch_all<P>(self, pool: &P) -> Result<Vec<O>, sqlx::Error>
73 where
74 P: InstrumentedPool<Database = DB> + Send + Sync,
75 for<'c> &'c P: Executor<'c, Database = DB>,
76 {
77 self.query.fetch_all_instrumented(pool, self.sql).await
78 }
79}
80
81impl<'q, DB, O, A> InstrumentedQueryBuilder<sqlx::query::QueryScalar<'q, DB, O, A>>
83where
84 DB: Database,
85 O: Send + Unpin + for<'r> sqlx::Decode<'r, DB> + sqlx::Type<DB>,
86 A: 'q + Send + sqlx::IntoArguments<'q, DB>,
87 usize: sqlx::ColumnIndex<DB::Row>,
88{
89 pub async fn fetch_one<P>(self, pool: &P) -> Result<O, sqlx::Error>
90 where
91 P: InstrumentedPool<Database = DB> + Send + Sync,
92 for<'c> &'c P: Executor<'c, Database = DB>,
93 {
94 self.query.fetch_one_instrumented(pool, self.sql).await
95 }
96
97 pub async fn fetch_optional<P>(self, pool: &P) -> Result<Option<O>, sqlx::Error>
98 where
99 P: InstrumentedPool<Database = DB> + Send + Sync,
100 for<'c> &'c P: Executor<'c, Database = DB>,
101 {
102 self.query.fetch_optional_instrumented(pool, self.sql).await
103 }
104
105 pub async fn fetch_all<P>(self, pool: &P) -> Result<Vec<O>, sqlx::Error>
106 where
107 P: InstrumentedPool<Database = DB> + Send + Sync,
108 for<'c> &'c P: Executor<'c, Database = DB>,
109 {
110 self.query.fetch_all_instrumented(pool, self.sql).await
111 }
112}