1use anyhow::Result;
4use codex_utils_absolute_path::AbsolutePathBuf;
5use sqlx::Row;
6use std::path::Path;
7use std::path::PathBuf;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct ThreadStateAuditRow {
12 pub id: String,
13 pub rollout_path: PathBuf,
14 pub archived: bool,
15 pub source: String,
16 pub model_provider: String,
17}
18
19pub async fn read_thread_state_audit_rows(path: &Path) -> Result<Vec<ThreadStateAuditRow>> {
21 let sqlite = crate::SqliteConfig::from_sqlite_home(AbsolutePathBuf::try_from(
22 path.parent().unwrap_or(path),
23 )?);
24 let pool = sqlite.open_read_only_pool(path).await?;
25 let rows = sqlx::query(
26 r#"
27SELECT id, rollout_path, archived, source, model_provider
28FROM threads
29 "#,
30 )
31 .fetch_all(&pool)
32 .await?;
33 pool.close().await;
34
35 rows.into_iter()
36 .map(|row| {
37 let archived: i64 = row.try_get("archived")?;
38 Ok(ThreadStateAuditRow {
39 id: row.try_get("id")?,
40 rollout_path: PathBuf::from(row.try_get::<String, _>("rollout_path")?),
41 archived: archived != 0,
42 source: row.try_get("source")?,
43 model_provider: row.try_get("model_provider")?,
44 })
45 })
46 .collect()
47}