// file: kb_lib/src/db/queries/pair_metric.rs //! Queries for `kb_pair_metrics`. /// Inserts or updates one pair-metric row and returns its stable internal id. pub async fn upsert_pair_metric( database: &crate::KbDatabase, dto: &crate::KbPairMetricDto, ) -> Result { match database.connection() { crate::KbDatabaseConnection::Sqlite(pool) => { let query_result = sqlx::query( r#" INSERT INTO kb_pair_metrics ( pair_id, first_slot, last_slot, first_signature, last_signature, trade_count, buy_count, sell_count, cumulative_base_amount_raw, cumulative_quote_amount_raw, last_price_quote_per_base, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(pair_id) DO UPDATE SET first_slot = excluded.first_slot, last_slot = excluded.last_slot, first_signature = excluded.first_signature, last_signature = excluded.last_signature, trade_count = excluded.trade_count, buy_count = excluded.buy_count, sell_count = excluded.sell_count, cumulative_base_amount_raw = excluded.cumulative_base_amount_raw, cumulative_quote_amount_raw = excluded.cumulative_quote_amount_raw, last_price_quote_per_base = excluded.last_price_quote_per_base, updated_at = excluded.updated_at "#, ) .bind(dto.pair_id) .bind(dto.first_slot) .bind(dto.last_slot) .bind(dto.first_signature.clone()) .bind(dto.last_signature.clone()) .bind(dto.trade_count) .bind(dto.buy_count) .bind(dto.sell_count) .bind(dto.cumulative_base_amount_raw.clone()) .bind(dto.cumulative_quote_amount_raw.clone()) .bind(dto.last_price_quote_per_base) .bind(dto.created_at.to_rfc3339()) .bind(dto.updated_at.to_rfc3339()) .execute(pool) .await; if let Err(error) = query_result { return Err(crate::KbError::Db(format!( "cannot upsert kb_pair_metrics on sqlite: {}", error ))); } let id_result = sqlx::query_scalar::( r#" SELECT id FROM kb_pair_metrics WHERE pair_id = ? LIMIT 1 "#, ) .bind(dto.pair_id) .fetch_one(pool) .await; match id_result { Ok(id) => return Ok(id), Err(error) => { return Err(crate::KbError::Db(format!( "cannot fetch kb_pair_metrics id for pair_id '{}' on sqlite: {}", dto.pair_id, error ))); }, } }, } } /// Returns one pair-metric row identified by its pair id, if it exists. pub async fn get_pair_metric_by_pair_id( database: &crate::KbDatabase, pair_id: i64, ) -> Result, crate::KbError> { match database.connection() { crate::KbDatabaseConnection::Sqlite(pool) => { let query_result = sqlx::query_as::( r#" SELECT id, pair_id, first_slot, last_slot, first_signature, last_signature, trade_count, buy_count, sell_count, cumulative_base_amount_raw, cumulative_quote_amount_raw, last_price_quote_per_base, created_at, updated_at FROM kb_pair_metrics WHERE pair_id = ? LIMIT 1 "#, ) .bind(pair_id) .fetch_optional(pool) .await; let entity_option = match query_result { Ok(entity_option) => entity_option, Err(error) => { return Err(crate::KbError::Db(format!( "cannot read kb_pair_metrics by pair_id '{}' on sqlite: {}", pair_id, error ))); }, }; match entity_option { Some(entity) => return crate::KbPairMetricDto::try_from(entity).map(Some), None => return Ok(None), } }, } } /// Lists all pair-metric rows ordered by pair id. pub async fn list_pair_metrics( database: &crate::KbDatabase, ) -> Result, crate::KbError> { match database.connection() { crate::KbDatabaseConnection::Sqlite(pool) => { let query_result = sqlx::query_as::( r#" SELECT id, pair_id, first_slot, last_slot, first_signature, last_signature, trade_count, buy_count, sell_count, cumulative_base_amount_raw, cumulative_quote_amount_raw, last_price_quote_per_base, created_at, updated_at FROM kb_pair_metrics ORDER BY pair_id ASC "#, ) .fetch_all(pool) .await; let entities = match query_result { Ok(entities) => entities, Err(error) => { return Err(crate::KbError::Db(format!( "cannot list kb_pair_metrics on sqlite: {}", error ))); }, }; let mut dtos = std::vec::Vec::new(); for entity in entities { let dto_result = crate::KbPairMetricDto::try_from(entity); let dto = match dto_result { Ok(dto) => dto, Err(error) => return Err(error), }; dtos.push(dto); } return Ok(dtos); }, } }