Skip to main content

tank_tests/
transaction3.rs

1use std::{pin::pin, sync::LazyLock};
2use tank::{
3    Connection, Entity, Executor, QueryBuilder, Transaction, cols, future::join, stream::StreamExt,
4};
5use tokio::sync::Mutex;
6
7static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
8
9#[derive(Entity)]
10struct Table {
11    #[tank(primary_key)]
12    id: u32,
13    value: i32,
14}
15
16pub async fn transaction3(connection: &mut impl Connection) {
17    let _lock = MUTEX.lock().await;
18
19    // Setup
20    Table::drop_table(connection, true, false)
21        .await
22        .expect("Failed to drop Table table");
23    Table::create_table(connection, true, true)
24        .await
25        .expect("Failed to create Table table");
26
27    Table::insert_many(
28        connection,
29        &[
30            Table { id: 1, value: 5 },
31            Table { id: 2, value: 9 },
32            Table { id: 3, value: -2 },
33        ],
34    )
35    .await
36    .expect("Failed to insert values");
37    async fn query_sum(c: &mut impl Executor) -> Table {
38        Table::from_row(
39            pin!(
40                c.fetch(
41                    QueryBuilder::new()
42                        .select(cols!(0 as id, SUM(value) as value))
43                        .from(Table::table())
44                        .build(&c.driver()),
45                )
46            )
47            .next()
48            .await
49            .expect("Didn't find the result")
50            .expect("Error while fetching"),
51        )
52        .expect("Unexpected row format")
53    }
54    let sum = query_sum(connection).await;
55    assert_eq!(sum.id, 0);
56    assert_eq!(sum.value, 12);
57
58    let mut c1 = connection.duplicate().await.expect("Failed to duplicate 1");
59    let mut c2 = connection.duplicate().await.expect("Failed to duplicate 2");
60    let mut t1 = c1.begin().await.expect("Failed to begin 1");
61    let mut t2 = c2.begin().await.expect("Failed to begin 2");
62    let f1 = async {
63        Table { id: 4, value: 4 }
64            .save(&mut t1)
65            .await
66            .expect("Failed to save 1");
67        assert_eq!(query_sum(&mut t1).await.value, 16);
68        t1.commit().await.expect("Failed to commit t1");
69    };
70    let f2 = async {
71        Table { id: 5, value: 3 }
72            .save(&mut t2)
73            .await
74            .expect("Failed to save 2");
75        let sum = query_sum(&mut t2).await.value;
76        assert!(matches!(sum, 15 | 19));
77        t2.rollback().await.expect("Failed to rollback");
78    };
79    join(f1, f2).await;
80}