// file: kb_lib/src/db/queries/pool_admin_event.rs //! Queries for `k_sol_pool_admin_events`. /// Returns one pool admin event by decoded event id. pub async fn query_pool_admin_events_get_by_decoded_event_id( database: &crate::Database, decoded_event_id: i64, ) -> Result, crate::Error> { match database.connection() { crate::DatabaseConnection::Sqlite(pool) => { let query_result = sqlx::query_as::( r#" SELECT id, transaction_id, decoded_event_id, dex_id, pool_id, pair_id, signature, slot, protocol_name, program_id, event_kind, pool_account, actor_wallet, admin_action, payload_json, executed_at, created_at FROM k_sol_pool_admin_events WHERE decoded_event_id = ? LIMIT 1 "#, ) .bind(decoded_event_id) .fetch_optional(pool) .await; let entity_option = match query_result { Ok(entity_option) => entity_option, Err(error) => { return Err(crate::Error::Db(format!( "cannot fetch k_sol_pool_admin_events by decoded_event_id '{}' on sqlite: {}", decoded_event_id, error ))); }, }; match entity_option { Some(entity) => { let dto_result = crate::PoolAdminEventDto::try_from(entity); match dto_result { Ok(dto) => return Ok(Some(dto)), Err(error) => return Err(error), } }, None => return Ok(None), } }, } } /// Inserts or updates one normalized pool admin event row. pub async fn query_pool_admin_events_upsert( database: &crate::Database, dto: &crate::PoolAdminEventDto, ) -> Result { let slot_i64 = match dto.slot { Some(slot) => { let slot_result = i64::try_from(slot); match slot_result { Ok(slot) => Some(slot), Err(error) => { return Err(crate::Error::Db(format!( "cannot convert pool admin event slot '{}' to i64: {}", slot, error ))); }, } }, None => None, }; match database.connection() { crate::DatabaseConnection::Sqlite(pool) => { let existing_id = match dto.decoded_event_id { Some(decoded_event_id) => { let existing_result = sqlx::query_scalar::( r#" SELECT id FROM k_sol_pool_admin_events WHERE decoded_event_id = ? LIMIT 1 "#, ) .bind(decoded_event_id) .fetch_optional(pool) .await; match existing_result { Ok(existing_id) => existing_id, Err(error) => { return Err(crate::Error::Db(format!( "cannot fetch k_sol_pool_admin_events id for decoded_event_id '{}' on sqlite: {}", decoded_event_id, error ))); }, } }, None => None, }; if let Some(id) = existing_id { let update_result = sqlx::query( r#" UPDATE k_sol_pool_admin_events SET transaction_id = ?, dex_id = ?, pool_id = ?, pair_id = ?, signature = ?, slot = ?, protocol_name = ?, program_id = ?, event_kind = ?, pool_account = ?, actor_wallet = ?, admin_action = ?, payload_json = ?, executed_at = ? WHERE id = ? "#, ) .bind(dto.transaction_id) .bind(dto.dex_id) .bind(dto.pool_id) .bind(dto.pair_id) .bind(dto.signature.clone()) .bind(slot_i64) .bind(dto.protocol_name.clone()) .bind(dto.program_id.clone()) .bind(dto.event_kind.clone()) .bind(dto.pool_account.clone()) .bind(dto.actor_wallet.clone()) .bind(dto.admin_action.clone()) .bind(dto.payload_json.clone()) .bind(dto.executed_at.to_rfc3339()) .bind(id) .execute(pool) .await; if let Err(error) = update_result { return Err(crate::Error::Db(format!( "cannot update k_sol_pool_admin_events id '{}' on sqlite: {}", id, error ))); } return Ok(id); } let insert_result = sqlx::query( r#" INSERT INTO k_sol_pool_admin_events ( transaction_id, decoded_event_id, dex_id, pool_id, pair_id, signature, slot, protocol_name, program_id, event_kind, pool_account, actor_wallet, admin_action, payload_json, executed_at, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "#, ) .bind(dto.transaction_id) .bind(dto.decoded_event_id) .bind(dto.dex_id) .bind(dto.pool_id) .bind(dto.pair_id) .bind(dto.signature.clone()) .bind(slot_i64) .bind(dto.protocol_name.clone()) .bind(dto.program_id.clone()) .bind(dto.event_kind.clone()) .bind(dto.pool_account.clone()) .bind(dto.actor_wallet.clone()) .bind(dto.admin_action.clone()) .bind(dto.payload_json.clone()) .bind(dto.executed_at.to_rfc3339()) .bind(dto.created_at.to_rfc3339()) .execute(pool) .await; if let Err(error) = insert_result { return Err(crate::Error::Db(format!( "cannot insert k_sol_pool_admin_events on sqlite: {}", error ))); } let id_result = sqlx::query_scalar::( r#" SELECT id FROM k_sol_pool_admin_events WHERE transaction_id = ? AND protocol_name = ? AND event_kind = ? AND signature = ? ORDER BY id DESC LIMIT 1 "#, ) .bind(dto.transaction_id) .bind(dto.protocol_name.clone()) .bind(dto.event_kind.clone()) .bind(dto.signature.clone()) .fetch_one(pool) .await; match id_result { Ok(id) => return Ok(id), Err(error) => { return Err(crate::Error::Db(format!( "cannot fetch inserted k_sol_pool_admin_events id for signature '{}' on sqlite: {}", dto.signature, error ))); }, } }, } } /// Lists recent pool admin events ordered from newest to oldest. pub async fn query_pool_admin_events_list_recent( database: &crate::Database, limit: u32, ) -> Result, crate::Error> { if limit == 0 { return Ok(std::vec::Vec::new()); } match database.connection() { crate::DatabaseConnection::Sqlite(pool) => { let query_result = sqlx::query_as::( r#" SELECT id, transaction_id, decoded_event_id, dex_id, pool_id, pair_id, signature, slot, protocol_name, program_id, event_kind, pool_account, actor_wallet, admin_action, payload_json, executed_at, created_at FROM k_sol_pool_admin_events ORDER BY id DESC LIMIT ? "#, ) .bind(i64::from(limit)) .fetch_all(pool) .await; let entities = match query_result { Ok(entities) => entities, Err(error) => { return Err(crate::Error::Db(format!( "cannot list k_sol_pool_admin_events on sqlite: {}", error ))); }, }; let mut dtos = std::vec::Vec::with_capacity(entities.len()); for entity in entities { let dto_result = crate::PoolAdminEventDto::try_from(entity); match dto_result { Ok(dto) => dtos.push(dto), Err(error) => return Err(error), } } return Ok(dtos); }, } } /// Deletes a stale pool admin materialization by decoded event id. pub async fn query_pool_admin_events_delete_by_decoded_event_id( database: &crate::Database, decoded_event_id: i64, ) -> Result { match database.connection() { crate::DatabaseConnection::Sqlite(pool) => { let delete_result = sqlx::query( r#" DELETE FROM k_sol_pool_admin_events WHERE decoded_event_id = ? "#, ) .bind(decoded_event_id) .execute(pool) .await; match delete_result { Ok(delete_result) => return Ok(delete_result.rows_affected()), Err(error) => { return Err(crate::Error::Db(format!( "cannot delete k_sol_pool_admin_events for decoded_event_id '{}' on sqlite: {}", decoded_event_id, error ))); }, } }, } }