kaizen/store/sqlite/
artifact_windows.rs1use super::*;
2
3impl Store {
4 pub fn files_touched_in_window(
6 &self,
7 workspace: &str,
8 start_ms: u64,
9 end_ms: u64,
10 ) -> Result<Vec<(String, String)>> {
11 let mut stmt = self.conn.prepare(
12 "SELECT DISTINCT ft.session_id, ft.path
13 FROM files_touched ft
14 JOIN sessions s ON s.id = ft.session_id
15 WHERE s.workspace = ?1
16 AND EXISTS (
17 SELECT 1 FROM events e
18 JOIN sessions ss ON ss.id = e.session_id
19 WHERE e.session_id = ft.session_id
20 AND (
21 (e.ts_ms >= ?2 AND e.ts_ms <= ?3)
22 OR (e.ts_ms < ?4 AND ss.started_at_ms >= ?2 AND ss.started_at_ms <= ?3)
23 )
24 )
25 ORDER BY ft.session_id, ft.path",
26 )?;
27 let out: Vec<(String, String)> = stmt
28 .query_map(
29 params![
30 workspace,
31 start_ms as i64,
32 end_ms as i64,
33 SYNTHETIC_TS_CEILING_MS,
34 ],
35 |r| Ok((r.get(0)?, r.get(1)?)),
36 )?
37 .filter_map(|r| r.ok())
38 .collect();
39 Ok(out)
40 }
41
42 pub fn skills_used_since(&self, workspace: &str, since_ms: u64) -> Result<Vec<String>> {
45 let mut stmt = self.conn.prepare(
46 "SELECT DISTINCT su.skill
47 FROM skills_used su
48 JOIN sessions s ON s.id = su.session_id
49 WHERE s.workspace = ?1
50 AND EXISTS (
51 SELECT 1 FROM events e
52 JOIN sessions ss ON ss.id = e.session_id
53 WHERE e.session_id = su.session_id
54 AND (e.ts_ms >= ?2 OR (e.ts_ms < ?3 AND ss.started_at_ms >= ?2))
55 )
56 ORDER BY su.skill",
57 )?;
58 let out: Vec<String> = stmt
59 .query_map(
60 params![workspace, since_ms as i64, SYNTHETIC_TS_CEILING_MS],
61 |r| r.get::<_, String>(0),
62 )?
63 .filter_map(|r| r.ok())
64 .filter(|s: &String| crate::store::event_index::is_valid_slug(s))
65 .collect();
66 Ok(out)
67 }
68
69 pub fn skills_used_in_window(
71 &self,
72 workspace: &str,
73 start_ms: u64,
74 end_ms: u64,
75 ) -> Result<Vec<(String, String)>> {
76 let mut stmt = self.conn.prepare(
77 "SELECT DISTINCT su.session_id, su.skill
78 FROM skills_used su
79 JOIN sessions s ON s.id = su.session_id
80 WHERE s.workspace = ?1
81 AND EXISTS (
82 SELECT 1 FROM events e
83 JOIN sessions ss ON ss.id = e.session_id
84 WHERE e.session_id = su.session_id
85 AND (
86 (e.ts_ms >= ?2 AND e.ts_ms <= ?3)
87 OR (e.ts_ms < ?4 AND ss.started_at_ms >= ?2 AND ss.started_at_ms <= ?3)
88 )
89 )
90 ORDER BY su.session_id, su.skill",
91 )?;
92 let out: Vec<(String, String)> = stmt
93 .query_map(
94 params![
95 workspace,
96 start_ms as i64,
97 end_ms as i64,
98 SYNTHETIC_TS_CEILING_MS,
99 ],
100 |r| Ok((r.get::<_, String>(0)?, r.get::<_, String>(1)?)),
101 )?
102 .filter_map(|r| r.ok())
103 .filter(|(_, skill): &(String, String)| crate::store::event_index::is_valid_slug(skill))
104 .collect();
105 Ok(out)
106 }
107
108 pub fn rules_used_since(&self, workspace: &str, since_ms: u64) -> Result<Vec<String>> {
110 let mut stmt = self.conn.prepare(
111 "SELECT DISTINCT ru.rule
112 FROM rules_used ru
113 JOIN sessions s ON s.id = ru.session_id
114 WHERE s.workspace = ?1
115 AND EXISTS (
116 SELECT 1 FROM events e
117 JOIN sessions ss ON ss.id = e.session_id
118 WHERE e.session_id = ru.session_id
119 AND (e.ts_ms >= ?2 OR (e.ts_ms < ?3 AND ss.started_at_ms >= ?2))
120 )
121 ORDER BY ru.rule",
122 )?;
123 let out: Vec<String> = stmt
124 .query_map(
125 params![workspace, since_ms as i64, SYNTHETIC_TS_CEILING_MS],
126 |r| r.get::<_, String>(0),
127 )?
128 .filter_map(|r| r.ok())
129 .filter(|s: &String| crate::store::event_index::is_valid_slug(s))
130 .collect();
131 Ok(out)
132 }
133
134 pub fn rules_used_in_window(
136 &self,
137 workspace: &str,
138 start_ms: u64,
139 end_ms: u64,
140 ) -> Result<Vec<(String, String)>> {
141 let mut stmt = self.conn.prepare(
142 "SELECT DISTINCT ru.session_id, ru.rule
143 FROM rules_used ru
144 JOIN sessions s ON s.id = ru.session_id
145 WHERE s.workspace = ?1
146 AND EXISTS (
147 SELECT 1 FROM events e
148 JOIN sessions ss ON ss.id = e.session_id
149 WHERE e.session_id = ru.session_id
150 AND (
151 (e.ts_ms >= ?2 AND e.ts_ms <= ?3)
152 OR (e.ts_ms < ?4 AND ss.started_at_ms >= ?2 AND ss.started_at_ms <= ?3)
153 )
154 )
155 ORDER BY ru.session_id, ru.rule",
156 )?;
157 let out: Vec<(String, String)> = stmt
158 .query_map(
159 params![
160 workspace,
161 start_ms as i64,
162 end_ms as i64,
163 SYNTHETIC_TS_CEILING_MS,
164 ],
165 |r| Ok((r.get::<_, String>(0)?, r.get::<_, String>(1)?)),
166 )?
167 .filter_map(|r| r.ok())
168 .filter(|(_, rule): &(String, String)| crate::store::event_index::is_valid_slug(rule))
169 .collect();
170 Ok(out)
171 }
172}