tank_tests/
transaction3.rs1use 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 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}