1use crate::{
2 AsEntity, AsQuery, Driver, DynQuery, Query, QueryResult, RawQuery, Result, Row, RowsAffected,
3 stream::{Stream, StreamExt},
4 writer::SqlWriter,
5};
6use anyhow::anyhow;
7use convert_case::{Case, Casing};
8use std::{
9 future::{self, Future},
10 mem,
11 pin::{Pin, pin},
12 task::{self, Poll},
13};
14
15struct Fetched<S>(S);
17
18impl<S, R> Stream for Fetched<S>
19where
20 S: Stream<Item = Result<QueryResult<R>>>,
21{
22 type Item = Result<R>;
23
24 #[inline(always)]
25 fn poll_next(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> {
26 let mut inner = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
27 loop {
28 match inner.as_mut().poll_next(cx) {
29 Poll::Ready(Some(Ok(QueryResult::Row(row)))) => return Poll::Ready(Some(Ok(row))),
30 Poll::Ready(Some(Ok(QueryResult::Affected(_)))) => {}
31 Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(e))),
32 Poll::Ready(None) => return Poll::Ready(None),
33 Poll::Pending => return Poll::Pending,
34 }
35 }
36 }
37
38 #[inline(always)]
39 fn size_hint(&self) -> (usize, Option<usize>) {
40 self.0.size_hint()
41 }
42}
43
44pub trait Executor: Send {
48 type Driver: Driver;
50
51 fn accepts_multiple_statements(&self) -> bool {
53 true
54 }
55
56 fn driver(&self) -> Self::Driver {
58 Default::default()
59 }
60
61 fn prepare<'s>(
63 &'s mut self,
64 query: impl AsQuery<Self::Driver> + 's,
65 ) -> impl Future<Output = Result<Query<Self::Driver>>> + Send {
66 let mut query = query.as_query();
67 let query = mem::take(query.as_mut());
68 async {
69 match query {
70 Query::Raw(RawQuery(sql)) => self.do_prepare(sql).await,
71 Query::Prepared(..) => Ok(query),
72 }
73 }
74 }
75
76 fn do_prepare(
78 &mut self,
79 _sql: String,
80 ) -> impl Future<Output = Result<Query<Self::Driver>>> + Send {
81 future::ready(Err(anyhow!(
82 "{} does not support prepare",
83 self.driver().name().to_case(Case::Pascal)
84 )))
85 }
86
87 fn run<'s>(
89 &'s mut self,
90 query: impl AsQuery<Self::Driver> + 's,
91 ) -> impl Stream<Item = Result<QueryResult<impl Row + 's>>> + Send;
92
93 fn fetch<'s>(
95 &'s mut self,
96 query: impl AsQuery<Self::Driver> + 's,
97 ) -> impl Stream<Item = Result<impl Row + 's>> + Send {
98 Fetched(self.run(query))
99 }
100
101 fn execute<'s>(
103 &'s mut self,
104 query: impl AsQuery<Self::Driver> + 's,
105 ) -> impl Future<Output = Result<RowsAffected>> + Send {
106 let stream = self.run(query);
107 async move {
108 let mut stream = pin!(stream);
109 let mut affected = RowsAffected::default();
110 while let Some(item) = stream.next().await {
111 if let QueryResult::Affected(a) = item? {
112 affected.extend([a]);
113 }
114 }
115 Ok(affected)
116 }
117 }
118
119 fn append<It>(&mut self, entities: It) -> impl Future<Output = Result<RowsAffected>> + Send
121 where
122 It: IntoIterator + Send,
123 It::IntoIter: Send,
124 It::Item: AsEntity,
125 {
126 let mut query = DynQuery::default();
127 self.driver()
128 .sql_writer()
129 .write_insert(&mut query, entities, false);
130 self.execute(query)
131 }
132}
133
134impl<S: Executor + ?Sized> Executor for &mut S {
135 type Driver = S::Driver;
136
137 fn accepts_multiple_statements(&self) -> bool {
138 (**self).accepts_multiple_statements()
139 }
140
141 fn driver(&self) -> Self::Driver {
142 (**self).driver()
143 }
144
145 fn prepare<'s>(
146 &'s mut self,
147 query: impl AsQuery<Self::Driver> + 's,
148 ) -> impl Future<Output = Result<Query<Self::Driver>>> + Send {
149 (**self).prepare(query)
150 }
151
152 fn do_prepare(
153 &mut self,
154 sql: String,
155 ) -> impl Future<Output = Result<Query<Self::Driver>>> + Send {
156 (**self).do_prepare(sql)
157 }
158
159 fn run<'s>(
160 &'s mut self,
161 query: impl AsQuery<Self::Driver> + 's,
162 ) -> impl Stream<Item = Result<QueryResult<impl Row + 's>>> + Send {
163 (**self).run(query)
164 }
165
166 fn fetch<'s>(
167 &'s mut self,
168 query: impl AsQuery<Self::Driver> + 's,
169 ) -> impl Stream<Item = Result<impl Row + 's>> + Send {
170 (**self).fetch(query)
171 }
172
173 fn execute<'s>(
174 &'s mut self,
175 query: impl AsQuery<Self::Driver> + 's,
176 ) -> impl Future<Output = Result<RowsAffected>> + Send {
177 (**self).execute(query)
178 }
179
180 fn append<It>(&mut self, entities: It) -> impl Future<Output = Result<RowsAffected>> + Send
181 where
182 It: IntoIterator + Send,
183 It::IntoIter: Send,
184 It::Item: AsEntity,
185 {
186 (**self).append(entities)
187 }
188}