1
use sqlx::{Connection, query_file, types::Uuid};
2
use supp_macro::Builder;
3

            
4
use crate::error::{CommodityError, FinanceError};
5

            
6
#[derive(Debug, sqlx::FromRow, Builder)]
7
#[builder(error_kind = "FinanceError")]
8
pub struct Commodity {
9
    pub id: Uuid,
10
    pub fraction: i64,
11
}
12

            
13
impl Commodity {
14
146
    pub async fn commit<E>(&self, conn: &mut E) -> Result<(), FinanceError>
15
146
    where
16
146
        E: Connection<Database = sqlx::Postgres>,
17
146
    {
18
146
        let mut tr = conn.begin().await?;
19

            
20
146
        query_file!("sql/commodity_insert.sql", &self.id, &self.fraction,)
21
146
            .execute(&mut *tr)
22
146
            .await?;
23
146
        tr.commit().await?;
24

            
25
146
        Ok(())
26
146
    }
27
}
28

            
29
#[cfg(test)]
30
mod commodity_tests {
31
    use super::*;
32
    #[cfg(feature = "testlog")]
33
    use env_logger;
34
    #[cfg(feature = "testlog")]
35
    use log;
36
    use sqlx::PgPool;
37
    use tokio::sync::OnceCell;
38

            
39
    /// Context for keeping environment intact
40
    static CONTEXT: OnceCell<()> = OnceCell::const_new();
41

            
42
6
    async fn setup() {
43
4
        CONTEXT
44
4
            .get_or_init(|| async {
45
                #[cfg(feature = "testlog")]
46
2
                let _ = env_logger::builder()
47
2
                    .is_test(true)
48
2
                    .filter_level(log::LevelFilter::Trace)
49
2
                    .try_init();
50
4
            })
51
4
            .await;
52
4
    }
53

            
54
    #[sqlx::test(migrations = "../migrations")]
55
    async fn test_commodity_store(pool: PgPool) {
56
        setup().await;
57
        let mut conn = pool.acquire().await.unwrap();
58
        let commodity = Commodity {
59
            id: Uuid::new_v4(),
60
            fraction: 100,
61
        };
62

            
63
        sqlx::query!(
64
            "INSERT INTO commodities (id, fraction) \
65
		      VALUES ($1, $2)",
66
            &commodity.id,
67
            &commodity.fraction
68
        )
69
        .execute(&mut *conn)
70
        .await
71
        .unwrap();
72

            
73
        let result: Commodity = sqlx::query_as("SELECT * FROM commodities WHERE fraction = 100")
74
            .fetch_one(&mut *conn)
75
            .await
76
            .unwrap();
77

            
78
        assert_eq!(commodity.id, result.id);
79
    }
80

            
81
    #[sqlx::test(migrations = "../migrations")]
82
    async fn test_commodity_commit(pool: PgPool) {
83
        setup().await;
84
        let mut conn = pool.acquire().await.unwrap();
85
        let commodity = CommodityBuilder::new()
86
            .fraction(1000)
87
            .id(Uuid::new_v4())
88
            .build()
89
            .unwrap();
90

            
91
        commodity.commit(&mut *conn).await.unwrap();
92

            
93
        let result: Commodity = sqlx::query_as("SELECT * FROM commodities WHERE fraction = 1000")
94
            .fetch_one(&mut *conn)
95
            .await
96
            .unwrap();
97

            
98
        assert_eq!(commodity.id, result.id);
99
    }
100
}