@@ -27,70 +27,72 @@ impl Db {
2727 /// 前台切换基线(低频、practice_segments 对齐锚点)不被
2828 /// 高频写放大误删(2h 会话 ≈ 数百条高频,远未触发守卫)。
2929 pub fn add_event ( & self , new : & NewSessionEvent ) -> Result < SessionEvent > {
30- let conn = self . conn . lock ( ) . expect ( "db lock poisoned" ) ;
31- conn. execute ( "BEGIN TRANSACTION" , [ ] ) ?;
32- let result = ( || -> Result < SessionEvent > {
33- // 容量守卫:超预算先删最旧(同一事务,防写放大无限增长)
34- if crate :: session_events:: over_budget ( self . count_events_locked ( & conn, new. session_id ) ?) {
35- // 优先删高频噪声事件(可重建信号;基线/行为事件保留)
36- let deleted = conn. execute (
37- "DELETE FROM session_events WHERE id IN (
38- SELECT id FROM session_events
39- WHERE session_id = ?1
40- AND kind IN ('frame_switch', 'long_silence', 'volume_surge')
41- ORDER BY timestamp_ms ASC LIMIT 1
42- )" ,
43- params ! [ new. session_id] ,
44- ) ?;
45- if deleted == 0 {
46- // 无高频可删(异常会话全为基线/行为事件)→ 回退删最旧整体
47- conn. execute (
30+ self . with_conn ( |conn| {
31+ conn. execute ( "BEGIN TRANSACTION" , [ ] ) ?;
32+ let result = ( || -> Result < SessionEvent > {
33+ // 容量守卫:超预算先删最旧(同一事务,防写放大无限增长)
34+ if crate :: session_events:: over_budget ( self . count_events_locked ( conn, new. session_id ) ?) {
35+ // 优先删高频噪声事件(可重建信号;基线/行为事件保留)
36+ let deleted = conn. execute (
4837 "DELETE FROM session_events WHERE id IN (
49- SELECT id FROM session_events WHERE session_id = ?1 ORDER BY timestamp_ms ASC LIMIT 1
38+ SELECT id FROM session_events
39+ WHERE session_id = ?1
40+ AND kind IN ('frame_switch', 'long_silence', 'volume_surge')
41+ ORDER BY timestamp_ms ASC LIMIT 1
5042 )" ,
5143 params ! [ new. session_id] ,
5244 ) ?;
45+ if deleted == 0 {
46+ // 无高频可删(异常会话全为基线/行为事件)→ 回退删最旧整体
47+ conn. execute (
48+ "DELETE FROM session_events WHERE id IN (
49+ SELECT id FROM session_events WHERE session_id = ?1 ORDER BY timestamp_ms ASC LIMIT 1
50+ )" ,
51+ params ! [ new. session_id] ,
52+ ) ?;
53+ }
54+ }
55+ conn. execute (
56+ "INSERT INTO session_events (session_id, kind, timestamp_ms, payload_json)
57+ VALUES (?1, ?2, ?3, ?4)" ,
58+ params ! [
59+ new. session_id,
60+ new. kind. as_str( ) ,
61+ new. timestamp_ms as i64 ,
62+ new. payload. to_string( ) ,
63+ ] ,
64+ ) ?;
65+ Ok ( SessionEvent {
66+ id : conn. last_insert_rowid ( ) ,
67+ session_id : new. session_id ,
68+ kind : new. kind ,
69+ timestamp_ms : new. timestamp_ms ,
70+ payload : new. payload . clone ( ) ,
71+ } )
72+ } ) ( ) ;
73+ match result {
74+ Ok ( e) => {
75+ conn. execute ( "COMMIT" , [ ] ) ?;
76+ Ok ( e)
77+ }
78+ Err ( e) => {
79+ let _ = conn. execute ( "ROLLBACK" , [ ] ) ;
80+ Err ( e)
5381 }
5482 }
55- conn. execute (
56- "INSERT INTO session_events (session_id, kind, timestamp_ms, payload_json)
57- VALUES (?1, ?2, ?3, ?4)" ,
58- params ! [
59- new. session_id,
60- new. kind. as_str( ) ,
61- new. timestamp_ms as i64 ,
62- new. payload. to_string( ) ,
63- ] ,
64- ) ?;
65- Ok ( SessionEvent {
66- id : conn. last_insert_rowid ( ) ,
67- session_id : new. session_id ,
68- kind : new. kind ,
69- timestamp_ms : new. timestamp_ms ,
70- payload : new. payload . clone ( ) ,
71- } )
72- } ) ( ) ;
73- match result {
74- Ok ( e) => {
75- conn. execute ( "COMMIT" , [ ] ) ?;
76- Ok ( e)
77- }
78- Err ( e) => {
79- let _ = conn. execute ( "ROLLBACK" , [ ] ) ;
80- Err ( e)
81- }
82- }
83+ } )
8384 }
8485
8586 /// 列出会话全部信号事件(按时间轴升序;消费端过滤类型)。
8687 pub fn list_events ( & self , session_id : i64 ) -> Result < Vec < SessionEvent > > {
87- let conn = self . conn . lock ( ) . expect ( "db lock poisoned" ) ;
88- let mut stmt = conn. prepare (
89- "SELECT id, session_id, kind, timestamp_ms, payload_json
90- FROM session_events WHERE session_id = ?1 ORDER BY timestamp_ms ASC" ,
91- ) ?;
92- let rows = stmt. query_map ( params ! [ session_id] , row_to_event) ?;
93- rows. collect :: < rusqlite:: Result < Vec < _ > > > ( ) . map_err ( Into :: into)
88+ self . with_conn ( |conn| {
89+ let mut stmt = conn. prepare (
90+ "SELECT id, session_id, kind, timestamp_ms, payload_json
91+ FROM session_events WHERE session_id = ?1 ORDER BY timestamp_ms ASC" ,
92+ ) ?;
93+ let rows = stmt. query_map ( params ! [ session_id] , row_to_event) ?;
94+ rows. collect :: < rusqlite:: Result < Vec < _ > > > ( ) . map_err ( Into :: into)
95+ } )
9496 }
9597
9698 /// 按类型列出事件(章节检测等消费端按需过滤)。
@@ -99,13 +101,14 @@ impl Db {
99101 /// 登记豁免 dead_code(V1.0 周报聚合同样需要)。
100102 #[ allow( dead_code) ]
101103 pub fn list_events_by_kind ( & self , session_id : i64 , kind : EventKind ) -> Result < Vec < SessionEvent > > {
102- let conn = self . conn . lock ( ) . expect ( "db lock poisoned" ) ;
103- let mut stmt = conn. prepare (
104- "SELECT id, session_id, kind, timestamp_ms, payload_json
105- FROM session_events WHERE session_id = ?1 AND kind = ?2 ORDER BY timestamp_ms ASC" ,
106- ) ?;
107- let rows = stmt. query_map ( params ! [ session_id, kind. as_str( ) ] , row_to_event) ?;
108- rows. collect :: < rusqlite:: Result < Vec < _ > > > ( ) . map_err ( Into :: into)
104+ self . with_conn ( |conn| {
105+ let mut stmt = conn. prepare (
106+ "SELECT id, session_id, kind, timestamp_ms, payload_json
107+ FROM session_events WHERE session_id = ?1 AND kind = ?2 ORDER BY timestamp_ms ASC" ,
108+ ) ?;
109+ let rows = stmt. query_map ( params ! [ session_id, kind. as_str( ) ] , row_to_event) ?;
110+ rows. collect :: < rusqlite:: Result < Vec < _ > > > ( ) . map_err ( Into :: into)
111+ } )
109112 }
110113
111114 /// 会话事件计数(容量守卫内部用;锁已持有)。
0 commit comments