vs_store/store/
sessions.rs1use rusqlite::params;
4
5use super::{epoch_secs, Store};
6use crate::error::{Result, StoreError};
7use crate::types::{Session, SessionStatus};
8
9impl Store {
10 pub fn create_session(&mut self, id: &str, policy_id: Option<&str>) -> Result<Session> {
12 let now = epoch_secs();
13 self.conn().execute(
14 "INSERT INTO sessions(id, created_at, policy_id, status, closed_at)
15 VALUES (?1, ?2, ?3, 'open', NULL)",
16 params![id, now, policy_id],
17 )?;
18 Ok(Session {
19 id: id.to_string(),
20 created_at: now,
21 policy_id: policy_id.map(str::to_string),
22 status: SessionStatus::Open,
23 closed_at: None,
24 })
25 }
26
27 pub fn close_session(&mut self, id: &str) -> Result<Session> {
29 let now = epoch_secs();
30 let n = self.conn().execute(
31 "UPDATE sessions SET status='closed', closed_at=?2 WHERE id=?1 AND status='open'",
32 params![id, now],
33 )?;
34 if n == 0 {
35 return Err(StoreError::NotFound {
36 kind: "session",
37 id: id.to_string(),
38 });
39 }
40 self.get_session(id)?.ok_or(StoreError::NotFound {
41 kind: "session",
42 id: id.to_string(),
43 })
44 }
45
46 pub fn get_session(&self, id: &str) -> Result<Option<Session>> {
47 let mut stmt = self.conn().prepare("SELECT * FROM sessions WHERE id=?1")?;
48 let mut rows = stmt.query([id])?;
49 if let Some(row) = rows.next()? {
50 Ok(Some(Session::from_row(row)?))
51 } else {
52 Ok(None)
53 }
54 }
55
56 pub fn list_sessions(&self) -> Result<Vec<Session>> {
57 let mut stmt = self
58 .conn()
59 .prepare("SELECT * FROM sessions ORDER BY created_at DESC")?;
60 let rows = stmt.query_map([], Session::from_row)?;
61 Ok(rows.collect::<rusqlite::Result<Vec<_>>>()?)
62 }
63}