From 687c0128412d0a07f8e3db042e5d6abe1baf4cce Mon Sep 17 00:00:00 2001 From: LIm1tZz7 <36764786+TheBadRoger@users.noreply.github.com> Date: Sun, 27 Sep 2026 22:21:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 - AGENTS.md | 2 +- README.md | 18 ---- benchmark/fullchain/run-p2.txt | 67 ------------ chusql-engine/test.ghci | 102 ------------------ .../frontend/src/core/uiSettings.test.ts | 1 - chusql-web/src/ChuSQL/Web/UiSettings.hs | 1 - chusql-web/test/Spec.hs | 2 +- 8 files changed, 2 insertions(+), 194 deletions(-) delete mode 100644 benchmark/fullchain/run-p2.txt delete mode 100644 chusql-engine/test.ghci diff --git a/.gitignore b/.gitignore index e0781f4..200d02c 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,3 @@ chusql-web/static/ Thumbs.db ehthumbs.db desktop.ini - -# Isolated UI verification build (the live server may lock the default executable) -.stack-work-ui/ diff --git a/AGENTS.md b/AGENTS.md index 202a4ad..2f903d2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -35,7 +35,7 @@ 4. **等价改造不许改结果**。典型:等值连接换哈希表,输出顺序必须和嵌套循环一致(左表序为主、右表序为辅,同键下右行保序);认不出等值键或某侧空表时退回嵌套循环(决策 9)。 5. **存储接口分 `schema` 与 `snapshot`**:语义检查与优化只走 `schema`,不许再拉全库行(决策 10)。 6. **测试的位置约定**:Haskell 引擎测试全部在 `chusql-engine/test/Spec.hs`;Web 在 `chusql-web/test/Spec.hs`(web 是独立包,不能反向依赖 engine 的测试);Rust 在 `chusql-storage/tests/*_test.rs`,另有 `src/log.rs` 里 3 条单元测试。新增测试放同一处,不另起目录。 -7. **只留根目录一个 README**:性能基准的跑法/结果/踩坑都写进 `README.md`;设计长文写 `docs/ENGINE_INTRO.md`、`docs/STORAGE_INTRO.md`,P3 的规格写 `docs/WEB_SPEC.md`。 +7. **只留根目录一个 README**:性能基准的跑法/结果/踩坑都写进 `README.md`;设计长文写 `docs/ENGINE_INTRO.md`、`docs/STORAGE_INTRO.md`,CLI 与接口说明写 `docs/COMMANDS.md`。 8. 改任何**决策**或**已知问题**,同一轮内更新 `projectplan.txt`。 --- diff --git a/README.md b/README.md index 41606b3..3572083 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ | `chusql-storage/` | Rust | 存储引擎:磁盘IO、B+树、缓冲池、WAL、崩溃恢复、并发控制 | | `chusql-web/` | Haskell + React/TypeScript | Web 管理端:Scotty REST API + VS Code Dark+ 风格数据库 Web IDE | | `script/` | PowerShell | `chusql.ps1` / `chusql.cmd`:一键启动 / 子命令 / 设置管理 | -| `docs/` | Markdown | 设计长文:ENGINE_INTRO / STORAGE_INTRO / WEB_SPEC | # 架构分层 @@ -37,23 +36,6 @@ - 事务日志和崩溃恢复 - 并发控制 -# 配置 - -服务端与前端各有一份配置文件,互不影响: - -| 文件 | 归属 | 内容 | 读写方式 | -| ------------------------------- | ------------------ | ------------------------------------------------------------------------ | ---------------------------------------- | -| `script/chusql.settings.json` | chusql-web 服务端 | 端口、监听地址、会话、限流、分页上限、账号、存储进程参数 | `chusql.ps1 config set`、`/api/settings` | -| `script/chusql.ui.settings.json`| 前端 IDE(浏览器) | 字体链、字号、行高、Tab 宽度、分页大小、NULL 文本、自动补全、Minimap 等 | `GET` / `PUT /api/ui-settings` | - -服务端配置的优先级是 `命令行 > 设置文件 > 环境变量 > 内置默认`;前端配置只有设置文件与内置默认两层。 - -前端配置由 chusql-web 负责落盘,**不经过 Rust 存储进程**,也不写进 `chusql-storage.toml`。前端在本地 -`localStorage` 留一份缓存,后端不可用时(例如开发用的 MockAdapter)自动回退到本地,行为与没有这份配置时一致。 - -两份文件都是本机专用、不入库(见 `.gitignore`)。`chusql-web/static/` 是 vite 构建产物,同样不入库, -需要时在 `chusql-web/frontend` 下跑 `npm run build` 生成;缺失时依赖它的构建产物契约测试会记为 pending。 - # 性能基准 | 指标 | 200 × 200 | 500 × 500 | 1000 × 1000 | diff --git a/benchmark/fullchain/run-p2.txt b/benchmark/fullchain/run-p2.txt deleted file mode 100644 index 3cd2ff4..0000000 --- a/benchmark/fullchain/run-p2.txt +++ /dev/null @@ -1,67 +0,0 @@ -全链路基准:Haskell 引擎 ←命名管道→ Rust 存储进程 -存储进程:../../chusql-storage/target\release\server.exe -管道:chusql-fullchain-145262202226 -数据目录:C:\Users\32402\AppData\Local\Temp\chusql-fullchain-145262202226 -数据规模:users = 1000 行,orders = 1000 行 -计时:墙上时钟(单调);每条语句都走完整链路 - -[启动] 存储进程就绪,用时 0.05 s - -[建表] -CREATE TABLE users 2.3 ms 0 行 -CREATE TABLE orders 1.6 ms 0 行 - -[写入:每条 INSERT 都是一次完整落盘] -1000 条 INSERT INTO users 2949.8 ms 2.950 ms/条 -1000 条 INSERT INTO orders 3244.4 ms 3.244 ms/条 - -[分解:同一条 INSERT 拆成两半,都用原始 IPC,不经过引擎] -CREATE TABLE raw_users 1.9 ms 0 行 -list_catalog(取结构) 23.3 ms 0.116 ms/次 -原始 IPC insert × 1000 2992.4 ms 2.992 ms/条 - -[读取与查询:整条语句,含引擎侧的解析与语义检查] -SELECT * FROM users 1.9 ms 1000 行 -SELECT name FROM users WHERE age > 90 2.5 ms 90 行 - -[读取与查询:连接] -JOIN + WHERE(哈希连接) 5.4 ms 90 行 - -[点查] -lookup_by_index(原始 IPC,按 id) 7.7 ms 0.077 ms/次(命中 100/100) -SELECT ... WHERE id = k(走 Lookup) 0.4 ms 1 行 - -[批量插入:一条语句带多行,N 行只落一次盘] -CREATE TABLE batch_t 3.0 ms 0 行 -多行 INSERT 58.8 ms 0.059 ms/行(100 行/条 × 10 条语句) - -[行级删除:代价和删几行无关,只和扫描 + 一次落盘有关] -DELETE FROM users WHERE id = k(1 行) 4.8 ms 0 行 -DELETE FROM users(全部) 20.2 ms 0 行 - -[二级索引:没有索引回退扫描,建完索引走索引] -CREATE TABLE items 2.1 ms 0 行 - (先把 1000 行灌进 items:53.2 ms) -SELECT ... WHERE code = k(无索引) 1.8 ms 1 行 -CREATE INDEX ON items (code) 9.8 ms 0 行 -SELECT ... WHERE code = k(走索引) 0.2 ms 1 行 - -[数据字典统计] - batch_t 1000 行 索引=id - 统计=age:100 id:1000 name:1000 - items 1000 行 索引=id code - 统计=code:1000 id:1000 - orders 1000 行 索引=id - 统计=id:1000 product:50 user_id:1000 - raw_users 1000 行 索引=id - 统计=age:100 id:1000 name:1000 - users 0 行 索引=id - 统计=age:0 id:0 name:0 - -[校验] -age > 90 命中 90(按数据分布应为 90 行) -JOIN 命中 90(每个用户恰好 1 张订单,应与上一行相同 = 90) -多行 INSERT 灌进去 1000 行(应为 1000) -二级索引那一行:code = 3501 应该查到 id = 500 - -[收尾] 停存储进程、清理数据目录 diff --git a/chusql-engine/test.ghci b/chusql-engine/test.ghci deleted file mode 100644 index a010257..0000000 --- a/chusql-engine/test.ghci +++ /dev/null @@ -1,102 +0,0 @@ --- ============================================================================ --- ChuSQL DROP TABLE + 统计信息 手测脚本 --- 用法: --- 1. 另开终端起 Rust server:cd chusql-storage && cargo run --bin chusql-storage --- 2. GHCi 里执行::script ghci-scripts/drop-table-test.ghci --- ============================================================================ - -:set -XOverloadedStrings - -import ChuSQL.Storage -import ChuSQL.Storage.IPC -import ChuSQL.Model -import ChuSQL.Engine -import ChuSQL.Syntax.AST -import ChuSQL.Syntax.Parser - --- 辅助:把一条 SQL 字符串跑到底 -let runSql sql = case parseQuery sql of { Left e -> putStrLn ("parse error: " ++ e); Right q -> runIPCStorage (runQueryM q) >>= print } - --- ============================================================================ --- 2. 清场:如果 demo3 存在就删掉 --- ============================================================================ -putStrLn ">>> [2] cleanup" -runSql "DROP TABLE demo3" - --- ============================================================================ --- 3. 建表 --- ============================================================================ -putStrLn ">>> [3] CREATE TABLE" -runSql "CREATE TABLE demo3 (id INT, name TEXT)" - --- ============================================================================ --- 4. describe:列应为 id/name,行数应为 0 --- ============================================================================ -putStrLn ">>> [4] describe (row_count should be 0)" -doDescribeTable "demo3" - --- ============================================================================ --- 5. 空表能扫 --- ============================================================================ -putStrLn ">>> [5] scan empty table" -runIPCStorage (scan "demo3") - --- ============================================================================ --- 6. 插 3 行 --- ============================================================================ -putStrLn ">>> [6] INSERT 3 rows" -runSql "INSERT INTO demo3 (id, name) VALUES (1, 'Alice')" -runSql "INSERT INTO demo3 (id, name) VALUES (2, 'Bob')" -runSql "INSERT INTO demo3 (id, name) VALUES (3, 'Carol')" - --- ============================================================================ --- 7. describe:行数应为 3 --- ============================================================================ -putStrLn ">>> [7] describe (row_count should be 3)" -doDescribeTable "demo3" - --- ============================================================================ --- 8. 扫回三行 --- ============================================================================ -putStrLn ">>> [8] scan 3 rows" -runIPCStorage (scan "demo3") - --- ============================================================================ --- 9. SQL SELECT,走索引 --- ============================================================================ -putStrLn ">>> [9] SELECT WHERE id = 2" -runSql "SELECT name FROM demo3 WHERE id = 2" - --- ============================================================================ --- 10. 重复建表应报错 --- ============================================================================ -putStrLn ">>> [10] CREATE TABLE again (should fail)" -runSql "CREATE TABLE demo3 (x INT)" - --- ============================================================================ --- 11. 删表 --- ============================================================================ -putStrLn ">>> [11] DROP TABLE" -runSql "DROP TABLE demo3" - --- ============================================================================ --- 12. 删后再查,应报 unknown table --- ============================================================================ -putStrLn ">>> [12a] scan after drop (should fail)" -runIPCStorage (scan "demo3") -putStrLn ">>> [12b] describe after drop (should fail)" -doDescribeTable "demo3" - --- ============================================================================ --- 13. 删不存在的表应报错 --- ============================================================================ -putStrLn ">>> [13] DROP TABLE nope (should fail)" -runSql "DROP TABLE nope" - --- ============================================================================ --- 14. 列出所有表,不应含 demo3 --- ============================================================================ -putStrLn ">>> [14] list_tables" -doListTables - -putStrLn ">>> done. check chusql-storage/data/ for disk state" diff --git a/chusql-web/frontend/src/core/uiSettings.test.ts b/chusql-web/frontend/src/core/uiSettings.test.ts index e9473d1..a21ad2e 100644 --- a/chusql-web/frontend/src/core/uiSettings.test.ts +++ b/chusql-web/frontend/src/core/uiSettings.test.ts @@ -35,7 +35,6 @@ describe('uiSettings', () => { sqlLineNumbers: false, autocomplete: 'yes', minimap: true, - confirmBeforeCommit: 1, unknownKey: 5, }), { status: 200 })); vi.stubGlobal('fetch', request); diff --git a/chusql-web/src/ChuSQL/Web/UiSettings.hs b/chusql-web/src/ChuSQL/Web/UiSettings.hs index a19486e..e96b9df 100644 --- a/chusql-web/src/ChuSQL/Web/UiSettings.hs +++ b/chusql-web/src/ChuSQL/Web/UiSettings.hs @@ -80,7 +80,6 @@ validateUiSettings (A.Object o) = Map.fromList <$> mapM checkField (KM.toList o) "sqlLineNumbers" -> pair key <$> boolValue key value "autocomplete" -> pair key <$> boolValue key value "minimap" -> pair key <$> boolValue key value - "confirmBeforeCommit" -> pair key <$> boolValue key value _ -> Left ("unknown setting: " ++ T.unpack key) pair key value = (key, value) diff --git a/chusql-web/test/Spec.hs b/chusql-web/test/Spec.hs index 08ababc..a38ff5a 100644 --- a/chusql-web/test/Spec.hs +++ b/chusql-web/test/Spec.hs @@ -1403,7 +1403,7 @@ settingsSpec staticDir = do -- | 一份完整的合法 IDE 设置请求体 uiSettingsBody :: BL.ByteString -uiSettingsBody = "{\"uiFonts\":[\"JetBrains Mono\",\"Consolas\"],\"gridFonts\":[\"Consolas\"],\"sqlFonts\":[\"Mono\"],\"uiFontSize\":13,\"gridFontSize\":12,\"gridRowHeight\":24,\"sqlFontSize\":13,\"sqlLineHeight\":20,\"sqlTabSize\":2,\"pageSize\":200,\"nullText\":\"NULL\",\"sqlLineNumbers\":true,\"autocomplete\":true,\"minimap\":false,\"confirmBeforeCommit\":true}" +uiSettingsBody = "{\"uiFonts\":[\"JetBrains Mono\",\"Consolas\"],\"gridFonts\":[\"Consolas\"],\"sqlFonts\":[\"Mono\"],\"uiFontSize\":13,\"gridFontSize\":12,\"gridRowHeight\":24,\"sqlFontSize\":13,\"sqlLineHeight\":20,\"sqlTabSize\":2,\"pageSize\":200,\"nullText\":\"NULL\",\"sqlLineNumbers\":true,\"autocomplete\":true,\"minimap\":false}" -- | 上面那份设置解出来的值 fullUiSettings :: A.Value