tank_sqlite/
transaction.rs

1use crate::{SqliteConnection, SqliteDriver};
2use tank_core::{
3    Driver, Executor, Query, QueryResult, Result, RowLabeled, SqlWriter, Transaction,
4    future::TryFutureExt, stream::Stream,
5};
6
7pub struct SqliteTransaction<'c> {
8    connection: &'c mut SqliteConnection,
9}
10
11impl<'c> SqliteTransaction<'c> {
12    pub async fn new(connection: &'c mut SqliteConnection) -> Result<Self> {
13        let result = Self { connection };
14        let mut sql = String::new();
15        result
16            .connection
17            .driver()
18            .sql_writer()
19            .write_transaction_begin(&mut sql);
20        result.connection.execute(sql.into()).await?;
21        Ok(result)
22    }
23}
24
25impl<'c> Executor for SqliteTransaction<'c> {
26    type Driver = SqliteDriver;
27
28    fn driver(&self) -> &SqliteDriver {
29        self.connection.driver()
30    }
31
32    fn prepare(
33        &mut self,
34        query: String,
35    ) -> impl Future<Output = Result<Query<SqliteDriver>>> + Send {
36        self.connection.prepare(query)
37    }
38
39    fn run(
40        &mut self,
41        query: tank_core::Query<Self::Driver>,
42    ) -> impl Stream<Item = Result<QueryResult>> + Send {
43        self.connection.run(query)
44    }
45
46    fn fetch<'s>(
47        &'s mut self,
48        query: Query<SqliteDriver>,
49    ) -> impl Stream<Item = Result<RowLabeled>> + Send + 's {
50        self.connection.fetch(query)
51    }
52
53    fn execute(
54        &mut self,
55        query: tank_core::Query<Self::Driver>,
56    ) -> impl Future<Output = tank_core::Result<tank_core::RowsAffected>> + Send {
57        self.connection.execute(query)
58    }
59
60    fn append<'a, E, It>(
61        &mut self,
62        entities: It,
63    ) -> impl Future<Output = tank_core::Result<tank_core::RowsAffected>> + Send
64    where
65        E: tank_core::Entity + 'a,
66        It: IntoIterator<Item = &'a E> + Send,
67    {
68        self.connection.append(entities)
69    }
70}
71
72impl<'c> Transaction<'c> for SqliteTransaction<'c> {
73    fn commit(self) -> impl Future<Output = Result<()>> {
74        let mut sql = String::new();
75        self.driver()
76            .sql_writer()
77            .write_transaction_commit(&mut sql);
78        self.connection.execute(sql.into()).map_ok(|_| ())
79    }
80
81    fn rollback(self) -> impl Future<Output = Result<()>> {
82        let mut sql = String::new();
83        self.driver()
84            .sql_writer()
85            .write_transaction_rollback(&mut sql);
86        self.connection.execute(sql.into()).map_ok(|_| ())
87    }
88}