use anyhow::{Context, Result};
use deadpool_sqlite::Pool;
use rusqlite::OptionalExtension;
use rusqlite::params;
use crate::db::database::interact_err;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PlanCard {
pub session_id: String,
pub chat_id: i64,
pub thread_id: Option<i64>,
pub message_id: i64,
pub signature: String,
}
pub struct PlanCardRepository {
pool: Pool,
}
impl PlanCardRepository {
pub fn new(pool: Pool) -> Self {
Self { pool }
}
pub async fn get(&self, session_id: &str) -> Result<Option<PlanCard>> {
let sid = session_id.to_string();
self.pool
.get()
.await
.context("Failed to get connection")?
.interact(move |conn| {
conn.query_row(
"SELECT session_id, chat_id, thread_id, message_id, signature \
FROM plan_cards WHERE session_id = ?1",
params![sid],
|row| {
Ok(PlanCard {
session_id: row.get(0)?,
chat_id: row.get(1)?,
thread_id: row.get(2)?,
message_id: row.get(3)?,
signature: row.get(4)?,
})
},
)
.optional()
})
.await
.map_err(interact_err)?
.context("Failed to read plan card")
}
pub async fn set(&self, card: PlanCard) -> Result<()> {
self.pool
.get()
.await
.context("Failed to get connection")?
.interact(move |conn| {
conn.execute(
"INSERT INTO plan_cards \
(session_id, chat_id, thread_id, message_id, signature, updated_at) \
VALUES (?1, ?2, ?3, ?4, ?5, strftime('%s','now')) \
ON CONFLICT(session_id) DO UPDATE SET \
chat_id = excluded.chat_id, \
thread_id = excluded.thread_id, \
message_id = excluded.message_id, \
signature = excluded.signature, \
updated_at = excluded.updated_at",
params![
card.session_id,
card.chat_id,
card.thread_id,
card.message_id,
card.signature
],
)
})
.await
.map_err(interact_err)?
.context("Failed to write plan card")?;
Ok(())
}
pub async fn delete(&self, session_id: &str) -> Result<()> {
let sid = session_id.to_string();
self.pool
.get()
.await
.context("Failed to get connection")?
.interact(move |conn| {
conn.execute("DELETE FROM plan_cards WHERE session_id = ?1", params![sid])
})
.await
.map_err(interact_err)?
.context("Failed to delete plan card")?;
Ok(())
}
}