kaizen/store/sqlite/
samples.rs1use super::*;
2
3impl Store {
4 pub fn append_session_sample(
5 &self,
6 session_id: &str,
7 ts_ms: u64,
8 pid: u32,
9 cpu_percent: Option<f64>,
10 rss_bytes: Option<u64>,
11 ) -> Result<()> {
12 self.conn.execute(
13 "INSERT OR REPLACE INTO session_samples (session_id, ts_ms, pid, cpu_percent, rss_bytes)
14 VALUES (?1, ?2, ?3, ?4, ?5)",
15 params![
16 session_id,
17 ts_ms as i64,
18 pid as i64,
19 cpu_percent,
20 rss_bytes.map(|b| b as i64)
21 ],
22 )?;
23 Ok(())
24 }
25
26 pub fn list_session_sample_aggs_in_window(
28 &self,
29 workspace: &str,
30 start_ms: u64,
31 end_ms: u64,
32 ) -> Result<Vec<SessionSampleAgg>> {
33 let mut stmt = self.conn.prepare(
34 "SELECT ss.session_id, COUNT(*) AS n,
35 MAX(ss.cpu_percent), MAX(ss.rss_bytes)
36 FROM session_samples ss
37 JOIN sessions s ON s.id = ss.session_id
38 WHERE s.workspace = ?1 AND s.started_at_ms >= ?2 AND s.started_at_ms <= ?3
39 GROUP BY ss.session_id",
40 )?;
41 let rows = stmt.query_map(params![workspace, start_ms as i64, end_ms as i64], |r| {
42 let sid: String = r.get(0)?;
43 let n: i64 = r.get(1)?;
44 let max_cpu: Option<f64> = r.get(2)?;
45 let max_rss: Option<i64> = r.get(3)?;
46 Ok(SessionSampleAgg {
47 session_id: sid,
48 sample_count: n as u64,
49 max_cpu_percent: max_cpu.unwrap_or(0.0),
50 max_rss_bytes: max_rss.map(|x| x as u64).unwrap_or(0),
51 })
52 })?;
53 rows.map(|r| r.map_err(anyhow::Error::from)).collect()
54 }
55}