fix: 修复消息内容为空的 bug(TEXT/BLOB 兼容),过滤 fts/resource DB,超时调为 120s

pull/2/head
jackwener 2026-04-16 16:16:41 +08:00
parent 3e7b4ed8ee
commit 2fd864b85d
3 changed files with 20 additions and 6 deletions

View File

@ -126,8 +126,8 @@ fn send_unix(req: Request) -> Result<Response> {
let sock_path = config::sock_path(); let sock_path = config::sock_path();
let mut stream = UnixStream::connect(&sock_path) let mut stream = UnixStream::connect(&sock_path)
.context("连接 daemon socket 失败")?; .context("连接 daemon socket 失败")?;
stream.set_read_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(30))).ok(); stream.set_write_timeout(Some(Duration::from_secs(120))).ok();
let req_str = serde_json::to_string(&req)? + "\n"; let req_str = serde_json::to_string(&req)? + "\n";
stream.write_all(req_str.as_bytes())?; stream.write_all(req_str.as_bytes())?;

View File

@ -55,6 +55,7 @@ async fn async_run() -> Result<()> {
.filter(|k| { .filter(|k| {
let k = k.replace('\\', "/"); let k = k.replace('\\', "/");
k.contains("message/message_") && k.ends_with(".db") k.contains("message/message_") && k.ends_with(".db")
&& !k.contains("_fts") && !k.contains("_resource")
}) })
.cloned() .cloned()
.collect(); .collect();
@ -143,7 +144,9 @@ async fn run_watcher(
let rows = stmt.query_map([], |row| { let rows = stmt.query_map([], |row| {
Ok(( Ok((
row.get::<_, String>(0)?, row.get::<_, String>(0)?,
row.get::<_, Vec<u8>>(1).unwrap_or_default(), row.get::<_, Vec<u8>>(1)
.or_else(|_| row.get::<_, String>(1).map(|s| s.into_bytes()))
.unwrap_or_default(),
row.get::<_, i64>(2)?, row.get::<_, i64>(2)?,
row.get::<_, i64>(3).unwrap_or(0), row.get::<_, i64>(3).unwrap_or(0),
row.get::<_, String>(4).unwrap_or_default(), row.get::<_, String>(4).unwrap_or_default(),

View File

@ -81,7 +81,7 @@ pub async fn q_sessions(db: &DbCache, names: &Names, limit: usize) -> Result<Val
Ok(( Ok((
row.get::<_, String>(0)?, row.get::<_, String>(0)?,
row.get::<_, i64>(1).unwrap_or(0), row.get::<_, i64>(1).unwrap_or(0),
row.get::<_, Vec<u8>>(2).unwrap_or_default(), get_content_bytes(row, 2),
row.get::<_, i64>(3).unwrap_or(0), row.get::<_, i64>(3).unwrap_or(0),
row.get::<_, i64>(4).unwrap_or(0), row.get::<_, i64>(4).unwrap_or(0),
row.get::<_, String>(5).unwrap_or_default(), row.get::<_, String>(5).unwrap_or_default(),
@ -433,7 +433,7 @@ fn query_messages(
row.get::<_, i64>(1)?, row.get::<_, i64>(1)?,
row.get::<_, i64>(2)?, row.get::<_, i64>(2)?,
row.get::<_, i64>(3)?, row.get::<_, i64>(3)?,
row.get::<_, Vec<u8>>(4).unwrap_or_default(), get_content_bytes(row, 4),
row.get::<_, i64>(5).unwrap_or(0), row.get::<_, i64>(5).unwrap_or(0),
)) ))
})? })?
@ -497,7 +497,7 @@ fn search_in_table(
row.get::<_, i64>(1)?, row.get::<_, i64>(1)?,
row.get::<_, i64>(2)?, row.get::<_, i64>(2)?,
row.get::<_, i64>(3)?, row.get::<_, i64>(3)?,
row.get::<_, Vec<u8>>(4).unwrap_or_default(), get_content_bytes(row, 4),
row.get::<_, i64>(5).unwrap_or(0), row.get::<_, i64>(5).unwrap_or(0),
)) ))
})? })?
@ -561,6 +561,17 @@ fn sender_label(
String::new() String::new()
} }
/// 读取消息内容列(兼容 TEXT 和 BLOB 两种存储类型)
///
/// SQLite 中 message_content 在未压缩时为 TEXTzstd 压缩后为 BLOB。
/// rusqlite 的 Vec<u8> FromSql 只接受 BLOB读 TEXT 会静默返回空。
fn get_content_bytes(row: &rusqlite::Row<'_>, idx: usize) -> Vec<u8> {
// 先尝试 BLOB再 fallback 到 TEXT→bytes
row.get::<_, Vec<u8>>(idx)
.or_else(|_| row.get::<_, String>(idx).map(|s| s.into_bytes()))
.unwrap_or_default()
}
fn decompress_message(data: &[u8], ct: i64) -> String { fn decompress_message(data: &[u8], ct: i64) -> String {
if ct == 4 && !data.is_empty() { if ct == 4 && !data.is_empty() {
// zstd 压缩 // zstd 压缩