use sqlx::PgPool; pub async fn set_fact( pg_pool: &PgPool, interaction_id: String, channel_id: Option, author_id: String, fact_name: String, fact_value: String, ) -> Result<(), String> { let Ok(rows) = sqlx::query!(" INSERT INTO facts (\"last_interaction_id\", \"channel_id\", \"author_id\", \"name\", \"value\") VALUES ($1, $2, $3, $4, $5) ON CONFLICT ON CONSTRAINT facts_origin_key DO UPDATE SET value = $5, version = facts.version + 1 ", interaction_id.to_string(), channel_id.map(|cid| cid.to_string()), author_id.to_string(), fact_name, fact_value, ).execute(pg_pool).await.map(|rows| rows.rows_affected()) else { return Err("Error saving fact.".to_string()); }; if rows != 1 { return Err("Error saving fact".to_string()); } Ok(()) } #[derive(Clone)] pub struct FactResponse { pub value: String, pub version: i32, pub created_at: time::OffsetDateTime, pub updated_at: time::OffsetDateTime, } pub async fn get_fact( pg_pool: &PgPool, channel_id: Option, author_id: String, fact_name: String, ) -> Result, String>{ let Ok(facts) = sqlx::query_as!(FactResponse, " SELECT \"value\", \"version\", \"created_at\", \"updated_at\" FROM facts WHERE channel_id IS NOT DISTINCT FROM $1 AND author_id = $2 AND name = $3 ", channel_id.map(|cid| cid.to_string()), author_id.to_string(), fact_name).fetch_all(pg_pool).await else { return Err("Querying facts failed".to_string()); }; if facts.is_empty() { return Ok(None); } if facts.len() > 1 { return Err("Too many facts found, wtf, impossible".to_string()); } Ok(Some(facts[0].clone())) }