tank_core/
executor.rs

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    /// General method to send any query and return any result type (either row or count)
19    fn run(&mut self, query: Query<Self::Driver>)
20    -> impl Stream<Item = Result<QueryResult>> + Send;
21
22    /// Execute the query and returns the rows.
23    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    /// Execute the query and return the total number of rows affected.
37    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    /// Append entities to a table. Defaults to insert query for drivers that do not support this feature.
53    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}