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
}
11

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

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

            
24
97
        Ok(())
25
97
    }
26
}
27

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

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

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

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

            
59
        sqlx::query!("INSERT INTO commodities (id) VALUES ($1)", &commodity.id,)
60
            .execute(&mut *conn)
61
            .await
62
            .unwrap();
63

            
64
        let result: Commodity = sqlx::query_as("SELECT * FROM commodities WHERE id = $1")
65
            .bind(commodity.id)
66
            .fetch_one(&mut *conn)
67
            .await
68
            .unwrap();
69

            
70
        assert_eq!(commodity.id, result.id);
71
    }
72

            
73
    #[sqlx::test(migrations = "../migrations")]
74
    async fn test_commodity_commit(pool: PgPool) {
75
        setup().await;
76
        let mut conn = pool.acquire().await.unwrap();
77
        let commodity = CommodityBuilder::new().id(Uuid::new_v4()).build().unwrap();
78

            
79
        commodity.commit(&mut *conn).await.unwrap();
80

            
81
        let result: Commodity = sqlx::query_as("SELECT * FROM commodities WHERE id = $1")
82
            .bind(commodity.id)
83
            .fetch_one(&mut *conn)
84
            .await
85
            .unwrap();
86

            
87
        assert_eq!(commodity.id, result.id);
88
    }
89
}