beyonder_store/
session_store.rs1use beyonder_core::{Session, SessionId};
2use rusqlite::params;
3
4use crate::{Store, StoreError, StoreResult};
5
6pub struct SessionStore<'a> {
7 store: &'a Store,
8}
9
10impl<'a> SessionStore<'a> {
11 pub fn new(store: &'a Store) -> Self {
12 Self { store }
13 }
14
15 pub fn insert(&self, session: &Session) -> StoreResult<()> {
16 let data = serde_json::to_string(session)?;
17 self.store.conn.execute(
18 r#"INSERT INTO sessions (id, name, created_at, last_active, working_dir, status, data)
19 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)"#,
20 params![
21 session.id.0,
22 session.name.as_deref(),
23 session.created_at.to_rfc3339(),
24 session.last_active.to_rfc3339(),
25 session.working_directory.to_string_lossy().as_ref(),
26 format!("{:?}", session.status),
27 data,
28 ],
29 )?;
30 Ok(())
31 }
32
33 pub fn get(&self, id: &SessionId) -> StoreResult<Session> {
34 let data: String = self
35 .store
36 .conn
37 .query_row(
38 "SELECT data FROM sessions WHERE id = ?1",
39 params![id.0],
40 |row| row.get(0),
41 )
42 .map_err(|_| StoreError::NotFound(id.0.clone()))?;
43 Ok(serde_json::from_str(&data)?)
44 }
45
46 pub fn list_active(&self) -> StoreResult<Vec<Session>> {
47 let mut stmt = self.store.conn.prepare(
48 "SELECT data FROM sessions WHERE status = 'Active' ORDER BY last_active DESC",
49 )?;
50 let sessions = stmt
51 .query_map([], |row| row.get::<_, String>(0))?
52 .filter_map(|r| r.ok())
53 .filter_map(|data| serde_json::from_str(&data).ok())
54 .collect();
55 Ok(sessions)
56 }
57
58 pub fn update(&self, session: &Session) -> StoreResult<()> {
59 let data = serde_json::to_string(session)?;
60 self.store.conn.execute(
61 "UPDATE sessions SET last_active = ?1, status = ?2, data = ?3 WHERE id = ?4",
62 params![
63 session.last_active.to_rfc3339(),
64 format!("{:?}", session.status),
65 data,
66 session.id.0,
67 ],
68 )?;
69 Ok(())
70 }
71}