ig_client/storage/
utils.rs

1use crate::application::models::transaction::Transaction;
2use crate::error::AppError;
3use sqlx::Executor;
4
5/// Stores a list of transactions in the database
6///
7/// # Arguments
8/// * `pool` - PostgreSQL connection pool
9/// * `txs` - List of transactions to store
10///
11/// # Returns
12/// * `Result<usize, AppError>` - Number of transactions inserted or an error
13pub async fn store_transactions(
14    pool: &sqlx::PgPool,
15    txs: &[Transaction],
16) -> Result<usize, AppError> {
17    let mut tx = pool.begin().await?;
18    let mut inserted = 0;
19
20    for t in txs {
21        let result = tx
22            .execute(
23                sqlx::query(
24                    r#"
25                    INSERT INTO ig_options (
26                        reference, deal_date, underlying, strike,
27                        option_type, expiry, transaction_type, pnl_eur, is_fee, raw
28                    )
29                    VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)
30                    ON CONFLICT (raw_hash) DO NOTHING
31                    "#,
32                )
33                .bind(&t.reference)
34                .bind(t.deal_date)
35                .bind(&t.underlying)
36                .bind(t.strike)
37                .bind(&t.option_type)
38                .bind(t.expiry)
39                .bind(&t.transaction_type)
40                .bind(t.pnl_eur)
41                .bind(t.is_fee)
42                .bind(&t.raw_json),
43            )
44            .await?;
45
46        inserted += result.rows_affected() as usize;
47    }
48
49    tx.commit().await?;
50    Ok(inserted)
51}