From 68ac629f44ede15935ddfd696675415f969ea032 Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 23 Jul 2026 11:49:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(sql-console):=20=E5=86=99=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8E=E5=85=A8=E9=87=8F=E5=A4=B1=E6=95=88=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SQL 控制台执行 UPDATE/DELETE 等 SQL 直改 DB 时绕过了 server function 的 正常缓存失效路径,导致 moka 单篇缓存(TTL 600s)与 SSR 磁盘缓存继续吐出 陈旧数据(含已删除文章),近 10 分钟的陈旧窗口。 - execute_sql 执行成功后,若含写语句则全量失效文章/搜索/评论缓存 + SSR 公开页磁盘缓存 + bump 全局世代号 - cache.rs 新增 invalidate_all_comments(评论列表 + 待审数) - 抽 writes_affect_cache 纯函数 + 3 个单测覆盖写/只读/混合语句 --- src/api/database/sql_console.rs | 60 +++++++++++++++++++++++++++++++++ src/cache.rs | 10 ++++++ 2 files changed, 70 insertions(+) diff --git a/src/api/database/sql_console.rs b/src/api/database/sql_console.rs index 296f33d..2d60297 100644 --- a/src/api/database/sql_console.rs +++ b/src/api/database/sql_console.rs @@ -191,6 +191,16 @@ fn is_read_only(stmt: &sqlparser::ast::Statement) -> bool { matches!(stmt, Statement::Query(_) | Statement::Explain { .. }) } +/// 判断一组语句中是否含有写操作(非只读语句)。 +/// +/// SQL 控制台执行写操作(INSERT/UPDATE/DELETE/TRUNCATE/ALTER/DROP 等)可能直改 +/// posts/comments/tags 等业务表,绕过 server function 的正常缓存失效路径。 +/// 抽成纯函数便于单测「哪些语句集合应触发兜底失效」。 +#[cfg(feature = "server")] +fn writes_affect_cache(stmts: &[sqlparser::ast::Statement]) -> bool { + stmts.iter().any(|s| !is_read_only(s)) +} + /// 把一列的值转成 JSON(按 PG 类型名分发)。 #[cfg(feature = "server")] fn col_to_json(row: &tokio_postgres::Row, idx: usize) -> serde_json::Value { @@ -305,6 +315,18 @@ pub async fn execute_sql(sql: String, opts: ExecuteSqlOpts) -> Result