// file: kb_lib/src/db/queries/token.rs //! Queries for `kb_tokens`. /// Inserts or updates one normalized token row by mint. pub async fn upsert_token( database: &crate::KbDatabase, dto: &crate::KbTokenDto, ) -> Result { match database.connection() { crate::KbDatabaseConnection::Sqlite(pool) => { let decimals = dto.decimals.map(i64::from); let query_result = sqlx::query( r#" INSERT INTO kb_tokens ( mint, symbol, name, decimals, token_program, is_quote_token, first_seen_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(mint) DO UPDATE SET symbol = excluded.symbol, name = excluded.name, decimals = excluded.decimals, token_program = excluded.token_program, is_quote_token = excluded.is_quote_token, updated_at = excluded.updated_at "#, ) .bind(dto.mint.clone()) .bind(dto.symbol.clone()) .bind(dto.name.clone()) .bind(decimals) .bind(dto.token_program.clone()) .bind(if dto.is_quote_token { 1_i64 } else { 0_i64 }) .bind(dto.first_seen_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_tokens on sqlite: {}", error ))); } let id_result = sqlx::query_scalar::( r#" SELECT id FROM kb_tokens WHERE mint = ? LIMIT 1 "#, ) .bind(dto.mint.clone()) .fetch_one(pool) .await; match id_result { Ok(id) => Ok(id), Err(error) => Err(crate::KbError::Db(format!( "cannot fetch kb_tokens id for mint '{}' on sqlite: {}", dto.mint, error ))), } } } } /// Reads one normalized token row by mint. pub async fn get_token_by_mint( database: &crate::KbDatabase, mint: &str, ) -> Result, crate::KbError> { match database.connection() { crate::KbDatabaseConnection::Sqlite(pool) => { let query_result = sqlx::query_as::( r#" SELECT id, mint, symbol, name, decimals, token_program, is_quote_token, first_seen_at, updated_at FROM kb_tokens WHERE mint = ? LIMIT 1 "#, ) .bind(mint) .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_tokens '{}' on sqlite: {}", mint, error ))); } }; match entity_option { Some(entity) => { let dto_result = crate::KbTokenDto::try_from(entity); match dto_result { Ok(dto) => Ok(Some(dto)), Err(error) => Err(error), } } None => Ok(None), } } } }