清理
This commit is contained in:
1 parent
7600f0f9ed
commit
687c012841
8 files changed
+2
-194
No files matched your search
@@ -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/
|
||||
@@ -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`。
|
||||
|
||||
---
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
[收尾] 停存储进程、清理数据目录
|
||||
@@ -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"
|
||||
@@ -35,7 +35,6 @@ describe('uiSettings', () => {
|
||||
sqlLineNumbers: false,
|
||||
autocomplete: 'yes',
|
||||
minimap: true,
|
||||
confirmBeforeCommit: 1,
|
||||
unknownKey: 5,
|
||||
}), { status: 200 }));
|
||||
vi.stubGlobal('fetch', request);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user