From 29543444daf6c5907abfa3d1346c3ade615eb2e5 Mon Sep 17 00:00:00 2001 From: xiaoxixi Date: Sun, 10 May 2026 14:36:40 +0800 Subject: [PATCH] feat(storage): add load_messages_after_timestamp, load_session_timelines, get_max_message_seq --- src/storage/memory.rs | 24 ++++++++++++++++++++++ src/storage/mod.rs | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/storage/memory.rs b/src/storage/memory.rs index 49ea476..12d35d4 100644 --- a/src/storage/memory.rs +++ b/src/storage/memory.rs @@ -250,6 +250,30 @@ impl super::Storage { Ok(result.rows_affected()) } + + /// Load timeline entries for a specific session. + pub async fn load_session_timelines( + &self, + session_id: &str, + limit: usize, + ) -> Result, StorageError> { + let rows = sqlx::query( + r#" + SELECT id, key, content, category, importance, + session_id, created_at, updated_at + FROM memories + WHERE session_id = ? AND category = 'timeline' + ORDER BY created_at DESC + LIMIT ? + "#, + ) + .bind(session_id) + .bind(limit as i64) + .fetch_all(self.pool()) + .await?; + + parse_memory_rows(&rows) + } } fn parse_memory_rows( diff --git a/src/storage/mod.rs b/src/storage/mod.rs index ce97c34..276ebb9 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -571,6 +571,52 @@ impl Storage { .collect()) } + pub async fn get_max_message_seq(&self, session_id: &str) -> Result { + let row = sqlx::query( + "SELECT COALESCE(MAX(seq), 0) as max_seq FROM messages WHERE session_id = ?", + ) + .bind(session_id) + .fetch_one(self.pool()) + .await?; + Ok(row.get::("max_seq")) + } + + pub async fn load_messages_after_timestamp( + &self, + session_id: &str, + after_ts: i64, + ) -> Result, StorageError> { + let rows = sqlx::query( + r#" + SELECT id, session_id, seq, role, content, media_refs, tool_call_id, tool_name, tool_calls, source, created_at + FROM messages + WHERE session_id = ? AND created_at > ? + ORDER BY seq ASC + "#, + ) + .bind(session_id) + .bind(after_ts) + .fetch_all(self.pool()) + .await?; + + Ok(rows + .into_iter() + .map(|row| crate::storage::message::MessageMeta { + id: row.get("id"), + session_id: row.get("session_id"), + seq: row.get("seq"), + role: row.get("role"), + content: row.get("content"), + media_refs: row.get("media_refs"), + tool_call_id: row.get("tool_call_id"), + tool_name: row.get("tool_name"), + tool_calls: row.get("tool_calls"), + source: row.get("source"), + created_at: row.get("created_at"), + }) + .collect()) + } + pub async fn list_all_active_sessions( &self, limit: i64,