From 2fd864b85d4dbb9d69a8e58e0ceaf192d79c3322 Mon Sep 17 00:00:00 2001 From: jackwener Date: Thu, 16 Apr 2026 16:16:41 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E4=B8=BA=E7=A9=BA=E7=9A=84=20bug=EF=BC=88TEX?= =?UTF-8?q?T/BLOB=20=E5=85=BC=E5=AE=B9=EF=BC=89=EF=BC=8C=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=20fts/resource=20DB=EF=BC=8C=E8=B6=85=E6=97=B6=E8=B0=83?= =?UTF-8?q?=E4=B8=BA=20120s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cli/transport.rs | 4 ++-- src/daemon/mod.rs | 5 ++++- src/daemon/query.rs | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/cli/transport.rs b/src/cli/transport.rs index 6afa6e6..7865bbb 100644 --- a/src/cli/transport.rs +++ b/src/cli/transport.rs @@ -126,8 +126,8 @@ fn send_unix(req: Request) -> Result { let sock_path = config::sock_path(); let mut stream = UnixStream::connect(&sock_path) .context("连接 daemon socket 失败")?; - stream.set_read_timeout(Some(Duration::from_secs(30))).ok(); - stream.set_write_timeout(Some(Duration::from_secs(30))).ok(); + stream.set_read_timeout(Some(Duration::from_secs(120))).ok(); + stream.set_write_timeout(Some(Duration::from_secs(120))).ok(); let req_str = serde_json::to_string(&req)? + "\n"; stream.write_all(req_str.as_bytes())?; diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index 3058a99..2c24e87 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -55,6 +55,7 @@ async fn async_run() -> Result<()> { .filter(|k| { let k = k.replace('\\', "/"); k.contains("message/message_") && k.ends_with(".db") + && !k.contains("_fts") && !k.contains("_resource") }) .cloned() .collect(); @@ -143,7 +144,9 @@ async fn run_watcher( let rows = stmt.query_map([], |row| { Ok(( row.get::<_, String>(0)?, - row.get::<_, Vec>(1).unwrap_or_default(), + row.get::<_, Vec>(1) + .or_else(|_| row.get::<_, String>(1).map(|s| s.into_bytes())) + .unwrap_or_default(), row.get::<_, i64>(2)?, row.get::<_, i64>(3).unwrap_or(0), row.get::<_, String>(4).unwrap_or_default(), diff --git a/src/daemon/query.rs b/src/daemon/query.rs index e8706f6..612b5b1 100644 --- a/src/daemon/query.rs +++ b/src/daemon/query.rs @@ -81,7 +81,7 @@ pub async fn q_sessions(db: &DbCache, names: &Names, limit: usize) -> Result(0)?, row.get::<_, i64>(1).unwrap_or(0), - row.get::<_, Vec>(2).unwrap_or_default(), + get_content_bytes(row, 2), row.get::<_, i64>(3).unwrap_or(0), row.get::<_, i64>(4).unwrap_or(0), row.get::<_, String>(5).unwrap_or_default(), @@ -433,7 +433,7 @@ fn query_messages( row.get::<_, i64>(1)?, row.get::<_, i64>(2)?, row.get::<_, i64>(3)?, - row.get::<_, Vec>(4).unwrap_or_default(), + get_content_bytes(row, 4), row.get::<_, i64>(5).unwrap_or(0), )) })? @@ -497,7 +497,7 @@ fn search_in_table( row.get::<_, i64>(1)?, row.get::<_, i64>(2)?, row.get::<_, i64>(3)?, - row.get::<_, Vec>(4).unwrap_or_default(), + get_content_bytes(row, 4), row.get::<_, i64>(5).unwrap_or(0), )) })? @@ -561,6 +561,17 @@ fn sender_label( String::new() } +/// 读取消息内容列(兼容 TEXT 和 BLOB 两种存储类型) +/// +/// SQLite 中 message_content 在未压缩时为 TEXT,zstd 压缩后为 BLOB。 +/// rusqlite 的 Vec FromSql 只接受 BLOB,读 TEXT 会静默返回空。 +fn get_content_bytes(row: &rusqlite::Row<'_>, idx: usize) -> Vec { + // 先尝试 BLOB,再 fallback 到 TEXT→bytes + row.get::<_, Vec>(idx) + .or_else(|_| row.get::<_, String>(idx).map(|s| s.into_bytes())) + .unwrap_or_default() +} + fn decompress_message(data: &[u8], ct: i64) -> String { if ct == 4 && !data.is_empty() { // zstd 压缩