1use crate::{
2 Driver, Entity, Query, QueryResult, Result, RowLabeled, RowsAffected,
3 stream::{Stream, StreamExt, TryStreamExt},
4 writer::SqlWriter,
5};
6use std::future::Future;
7
8pub trait Executor: Send + Sized {
9 type Driver: Driver;
10
11 fn driver(&self) -> &Self::Driver;
12
13 fn prepare(
14 &mut self,
15 query: String,
16 ) -> impl Future<Output = Result<Query<Self::Driver>>> + Send;
17
18 fn run(&mut self, query: Query<Self::Driver>)
20 -> impl Stream<Item = Result<QueryResult>> + Send;
21
22 fn fetch<'s>(
24 &'s mut self,
25 query: Query<Self::Driver>,
26 ) -> impl Stream<Item = Result<RowLabeled>> + Send + 's {
27 self.run(query).filter_map(|v| async move {
28 match v {
29 Ok(QueryResult::RowLabeled(v)) => Some(Ok(v)),
30 Err(e) => Some(Err(e)),
31 _ => None,
32 }
33 })
34 }
35
36 fn execute(
38 &mut self,
39 query: Query<Self::Driver>,
40 ) -> impl Future<Output = Result<RowsAffected>> + Send {
41 self.run(query)
42 .filter_map(|v| async move {
43 match v {
44 Ok(QueryResult::Affected(v)) => Some(Ok(v)),
45 Err(e) => Some(Err(e)),
46 _ => None,
47 }
48 })
49 .try_collect()
50 }
51
52 fn append<'a, E, It>(
54 &mut self,
55 entities: It,
56 ) -> impl Future<Output = Result<RowsAffected>> + Send
57 where
58 E: Entity + 'a,
59 It: IntoIterator<Item = &'a E> + Send,
60 {
61 let mut query = String::new();
62 self.driver()
63 .sql_writer()
64 .write_insert(&mut query, entities, false);
65 self.execute(query.into())
66 }
67}