hypercall_db_diesel/
oracle.rs1use anyhow::{Context, Result};
7use diesel::prelude::*;
8use tracing::debug;
9
10use crate::database_handler::DatabaseHandler;
11use crate::models::{NewOraclePriceSample, NewOracleSettlementPrice, OracleSettlementPrice};
12use crate::schema::{oracle_price_samples, oracle_settlement_prices};
13use hypercall_db::types::oracle::{NewOraclePriceSampleInput, NewOracleSettlementPriceInput};
14
15impl hypercall_db::OracleWriter for DatabaseHandler {
16 fn save_oracle_price_samples_sync(&self, samples: &[NewOraclePriceSampleInput]) -> Result<()> {
17 if samples.is_empty() {
18 return Ok(());
19 }
20
21 let mut conn = self.pool().get().context("Failed to get DB connection")?;
22
23 let new_samples: Vec<NewOraclePriceSample> = samples
24 .iter()
25 .map(|s| NewOraclePriceSample {
26 symbol: s.symbol.clone(),
27 expiry_timestamp: s.expiry_timestamp,
28 sample_timestamp_ms: s.sample_timestamp_ms,
29 price: s.price,
30 source: s.source.clone(),
31 })
32 .collect();
33
34 diesel::insert_into(oracle_price_samples::table)
35 .values(&new_samples)
36 .on_conflict((
37 oracle_price_samples::symbol,
38 oracle_price_samples::expiry_timestamp,
39 oracle_price_samples::sample_timestamp_ms,
40 oracle_price_samples::source,
41 ))
42 .do_nothing()
43 .execute(&mut conn)?;
44
45 debug!("Persisted {} oracle price samples", samples.len(),);
46
47 Ok(())
48 }
49
50 fn save_oracle_settlement_price_sync(
51 &self,
52 settlement: &NewOracleSettlementPriceInput,
53 ) -> Result<()> {
54 let mut conn = self.pool().get().context("Failed to get DB connection")?;
55
56 let new_settlement = NewOracleSettlementPrice {
57 symbol: settlement.symbol.clone(),
58 expiry_timestamp: settlement.expiry_timestamp,
59 settlement_price: settlement.settlement_price,
60 sample_count: settlement.sample_count,
61 window_start: settlement.window_start,
62 window_end: settlement.window_end,
63 algorithm: settlement.algorithm.clone(),
64 };
65
66 diesel::insert_into(oracle_settlement_prices::table)
67 .values(&new_settlement)
68 .on_conflict((
69 oracle_settlement_prices::symbol,
70 oracle_settlement_prices::expiry_timestamp,
71 ))
72 .do_nothing()
73 .execute(&mut conn)?;
74
75 Ok(())
76 }
77
78 fn get_oracle_settlement_price_sync(
79 &self,
80 symbol: &str,
81 expiry_timestamp: i64,
82 ) -> Result<Option<f64>> {
83 let mut conn = self.pool().get().context("Failed to get DB connection")?;
84
85 let result: Option<OracleSettlementPrice> = oracle_settlement_prices::table
86 .filter(oracle_settlement_prices::symbol.eq(symbol))
87 .filter(oracle_settlement_prices::expiry_timestamp.eq(expiry_timestamp))
88 .first(&mut conn)
89 .optional()?;
90
91 Ok(result.map(|r| r.settlement_price))
92 }
93}