perspt_store/store/
sessions.rs1use super::*;
2
3impl SessionStore {
4 pub fn create_session(&self, session: &SessionRecord) -> Result<()> {
6 self.conn.lock().unwrap().execute(
7 r#"
8 INSERT INTO sessions (session_id, task, working_dir, merkle_root, detected_toolchain, status)
9 VALUES (?, ?, ?, ?, ?, ?)
10 "#,
11 [
12 &session.session_id,
13 &session.task,
14 &session.working_dir,
15 &session.merkle_root.as_ref().map(hex::encode).unwrap_or_default(),
16 &session.detected_toolchain.clone().unwrap_or_default(),
17 &session.status,
18 ],
19 )?;
20 Ok(())
21 }
22
23 pub fn get_session(&self, session_id: &str) -> Result<Option<SessionRecord>> {
25 let conn = self.conn.lock().unwrap();
26 let mut stmt = conn.prepare(
27 "SELECT session_id, task, working_dir, merkle_root, detected_toolchain, status FROM sessions \
28 WHERE session_id = ?"
29 )?;
30
31 let mut rows = stmt.query([session_id])?;
32 if let Some(row) = rows.next()? {
33 let merkle_root: Option<Vec<u8>> = row.get(3).ok();
36
37 Ok(Some(SessionRecord {
38 session_id: row.get(0)?,
39 task: row.get(1)?,
40 working_dir: row.get(2)?,
41 merkle_root,
42 detected_toolchain: row.get(4)?,
43 status: row.get(5)?,
44 }))
45 } else {
46 Ok(None)
47 }
48 }
49
50 pub fn get_session_dir(&self, session_id: &str) -> Result<PathBuf> {
52 let data_dir = dirs::data_local_dir()
53 .context("Could not find local data directory")?
54 .join("perspt")
55 .join("sessions")
56 .join(session_id);
57 Ok(data_dir)
58 }
59
60 pub fn create_session_dir(&self, session_id: &str) -> Result<PathBuf> {
62 let dir = self.get_session_dir(session_id)?;
63 if !dir.exists() {
64 std::fs::create_dir_all(&dir).context("Failed to create session directory")?;
65 }
66 Ok(dir)
67 }
68
69 pub fn list_recent_sessions(&self, limit: usize) -> Result<Vec<SessionRecord>> {
71 self.list_sessions_paginated(limit, 0)
72 }
73
74 pub fn list_sessions_paginated(
76 &self,
77 limit: usize,
78 offset: usize,
79 ) -> Result<Vec<SessionRecord>> {
80 let conn = self.conn.lock().unwrap();
81 let mut stmt = conn.prepare(
82 "SELECT session_id, task, working_dir, merkle_root, detected_toolchain, status
83 FROM sessions ORDER BY created_at DESC LIMIT ? OFFSET ?",
84 )?;
85
86 let mut rows = stmt.query([limit.to_string(), offset.to_string()])?;
87 let mut records = Vec::new();
88
89 while let Some(row) = rows.next()? {
90 let merkle_root: Option<Vec<u8>> = row.get(3).ok();
91
92 records.push(SessionRecord {
93 session_id: row.get(0)?,
94 task: row.get(1)?,
95 working_dir: row.get(2)?,
96 merkle_root,
97 detected_toolchain: row.get(4)?,
98 status: row.get(5)?,
99 });
100 }
101
102 Ok(records)
103 }
104
105 pub fn count_sessions(&self) -> Result<usize> {
107 let conn = self.conn.lock().unwrap();
108 let mut stmt = conn.prepare("SELECT COUNT(*) FROM sessions")?;
109 let mut rows = stmt.query([])?;
110 if let Some(row) = rows.next()? {
111 let count: i64 = row.get(0)?;
112 Ok(count as usize)
113 } else {
114 Ok(0)
115 }
116 }
117
118 pub fn update_session_status(&self, session_id: &str, status: &str) -> Result<()> {
120 self.conn.lock().unwrap().execute(
121 "UPDATE sessions SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE session_id = ?",
122 [status, session_id],
123 )?;
124 Ok(())
125 }
126}