diff --git a/README.md b/README.md index de483c9..36f16d1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MetonaSqlark
-
+
@@ -26,15 +26,17 @@
- 🚰 **流式查询** — `queryStream`/`stream()` 逐行回调,Aria LSM 惰性扫描不物化结果集(v0.4.0)
- 🧩 **派生表** — `FROM (SELECT ...)` 子查询作为行源,多列 ON 哈希连接,COUNT(DISTINCT),NULLS FIRST/LAST(v0.4.0)
- 🔗 **Query Builder API** — 链式 `.select().where().orderBy().limit().execute()`
-- 🔄 **事务回滚** — Memory/IndexedDB/Hybrid/Aria 四引擎事务原子性,自动回滚,MVCC 版本链接入读写路径
+- 🔄 **事务回滚** — Memory/KVStore/Hybrid/Aria 四引擎事务原子性,自动回滚,MVCC 版本链接入读写路径
- 🔗 **外键级联** — ON DELETE + ON UPDATE(CASCADE / SET NULL / RESTRICT)全引擎支持,支持更新主键(v0.4.2)
- 🛡 **崩溃恢复自愈** — 残缺 SSTable 打开自动跳过、`db.repair()` 自愈(含孤儿页面清理与残留清理)、`db.clearAll()` 重置、迁移版本持久化(v0.4.2/v0.5.0)
- 🧵 **关闭时序与后台任务加固** — 后台 flush/compaction 串行入队(close 排空后才关闭存储,失败显式报告 `ARIA_BACKGROUND_ERROR`)
- 📏 **SSTable 编码修复** — 块大小按 UTF-8 字节精确计算、长度字段 u32、v1/v2 双格式兼容(v0.4.4)
- 🌲 **RB-Tree 完整实现** — 标准红黑树插入+删除修复,O(log n) 保证
-- ⚡ **性能优化** — SSTableReader 二分查找统一、IndexedDB 索引利用、crypto 实例化避免全局状态
-- 🌐 **浏览器兼容** — Chrome 80+ / Firefox 80+ / Safari 14+ / Edge 80+ / Node.js 16+
-- 🧪 **1049 测试 · 89.3% 覆盖率** — 64 套件 + 12 个 Playwright 真实 Chromium e2e(含崩溃注入),生产级质量保证
+- ⚡ **性能优化** — SSTableReader 二分查找统一、KVStore 内存热路径 O(1) 读、crypto 实例化避免全局状态
+- 🛡 **级联环路保护** — A→B→A 循环引用 + CASCADE 不无限递归(visited 保护,全引擎)(v0.6.1)
+- ⚛️ **多表事务真原子** — 事务 commit / 级联更新合并单条日志记录(崩溃无部分提交)(v0.6.1)
+- 🌐 **浏览器兼容** — Chrome 102+ / Firefox 111+ / Safari 15.2+ / Edge 102+ / Node.js 16+
+- 🧪 **1049 测试 · 89.3% 覆盖率** — 65 套件 + 12 个 Playwright 真实 Chromium e2e(含崩溃注入),生产级质量保证
---
@@ -327,19 +329,19 @@ const { data, loading, refresh } = useSqlarkQuery(db, 'SELECT * FROM users');
## 📊 存储模式对比
-| 特性 | Memory | Disk (KVStore) | Disk (OPFS) | Hybrid | Aria |
-|------|--------|----------------|-------------|--------|------|
-| **持久化** | ❌ 重启丢失 | ✅ KVStore(OPFS) | ✅ OPFS(schema 持久化) | ✅ 内存+磁盘 | ✅ 后端决定 |
-| **事务回滚** | ✅ 快照 | ✅ 原子日志 flush | ✅ 快照 | ✅ 双引擎 | ✅ MVCC |
-| **多 key 原子写** | — | ✅ 单日志记录原子(v0.6.0) | — | ✅ 委托磁盘 | ✅ WAL 单文件原子 |
-| **二级索引** | ✅ Hash | ✅ Hash(重启恢复) | ✅ Hash(重启恢复) | ✅ Hash | ✅ LSM(重启恢复) |
-| **查询性能** | ⚡ O(1) PK | ⚡ O(1) PK(内存热路径) | 🟡 O(1) PK | ⚡ O(1) PK | ⚡ O(log n) |
-| **数据上限** | 内存限制 | 磁盘可用(行级存储,大表可行) | ~磁盘可用(整表 JSON,≤1000 行) | 磁盘可用 | 内存限制 |
-| **浏览器** | 全部 | Chrome/Edge 102+ / Firefox 111+ / Safari 15.2+ | 同上 | 同上 | 同上 |
-| **多标签页** | — | —(无事务锁,Hybrid 场景) | ❌ 无保护 | ❌ 无保护 | ✅ Web Locks 独占锁(v0.5.0) |
-| **全库加密** | — | — | — | — | ✅ AES-GCM(v0.5.0) |
-| **适用场景** | 缓存/测试 | 标准持久化(替代 IndexedDB) | 小数据集 | 速度+持久化 | 大规模/分析 |
-| **测试覆盖** | 30+ | 50+(含 10 万级压力) | 15 | 15+ | 400+ |
+| 特性 | Memory | Disk (KVStore) | Hybrid | Aria |
+|------|--------|----------------|--------|------|
+| **持久化** | ❌ 重启丢失 | ✅ KVStore(OPFS) | ✅ 内存+磁盘 | ✅ 后端决定 |
+| **事务回滚** | ✅ 快照 | ✅ 原子日志 flush | ✅ 双引擎 | ✅ MVCC |
+| **多 key 原子写** | — | ✅ 单日志记录原子(v0.6.0/0.6.1) | ✅ 委托磁盘 | ✅ WAL 单文件原子 |
+| **二级索引** | ✅ Hash | ✅ Hash(重启恢复) | ✅ Hash | ✅ LSM(重启恢复) |
+| **查询性能** | ⚡ O(1) PK | ⚡ O(1) PK(内存热路径) | ⚡ O(1) PK | ⚡ O(log n) |
+| **数据上限** | 内存限制 | 磁盘可用(行级存储,大表可行) | 磁盘可用 | 内存限制 |
+| **浏览器** | 全部 | Chrome/Edge 102+ / Firefox 111+ / Safari 15.2+ | 同上 | 同上 |
+| **多标签页** | — | —(无事务锁,Hybrid 场景) | ❌ 无保护 | ✅ Web Locks 独占锁(v0.5.0) |
+| **全库加密** | — | — | — | ✅ AES-GCM(v0.5.0) |
+| **适用场景** | 缓存/测试 | 标准持久化(替代 IndexedDB) | 速度+持久化 | 大规模/分析 |
+| **测试覆盖** | 30+ | 50+(含 10 万级压力 + 异常场景) | 15+ | 400+ |
### Memory 模式
- **环境**: 所有浏览器、Node.js
@@ -354,21 +356,15 @@ const { data, loading, refresh } = useSqlarkQuery(db, 'SELECT * FROM users');
二级索引(重启恢复)、schema/数据/索引完整持久化、10 万级数据量压力验证
- **适用**: 标准前端数据库持久化(v0.6.0 替代 IndexedDB)
-### Disk (OPFS) 模式
-- **环境**: Chrome 102+ / Edge 102+ / Firefox 111+ / Safari 15.2+(Origin Private File System)
-- **限制**: 每次写入重写整表 JSON 文件(大表性能差,不建议 >1000 行);多标签页并发写无保护(Hybrid 模式)
-- **能力**: 完整 CRUD、重启自动加载数据(空表/索引/schema 完整保留,v0.4.2)、事务回滚、并发写安全(内存快照一致)
-- **适用**: 小数据集持久化(大表请用 Aria + OPFS 页面化存储)
-
### Hybrid 模式
- **环境**: 所有浏览器
-- **限制**: 磁盘引擎决定底层限制(IndexedDB ~2GB / OPFS 需 OPFS 支持浏览器)
+- **限制**: 磁盘引擎决定底层限制(KVStore 需 OPFS 支持浏览器)
- **能力**: write-through 双写(内存+磁盘)、提交顺序保证(磁盘优先)、读从内存
- **适用**: 需要内存速度 + 磁盘持久化的混合场景
### Aria 模式
-- **环境**: 所有浏览器(后端可选 IndexedDB / OPFS / Memory)
-- **限制**: Memory 后端重启丢失;IndexedDB 后端受配额限制;OPFS 后端需 OPFS 支持(Chrome 102+ / Firefox 111+ / Safari 15.2+);同一库仅允许一个标签页打开(Web Locks 独占锁,第二个标签页抛 `ARIA_LOCKED`)
+- **环境**: 所有浏览器(后端可选 OPFS / Memory)
+- **限制**: Memory 后端重启丢失;OPFS 后端需 OPFS 支持(Chrome 102+ / Firefox 111+ / Safari 15.2+);同一库仅允许一个标签页打开(Web Locks 独占锁,第二个标签页抛 `ARIA_LOCKED`)
- **能力**: LSM-Tree 存储引擎、SSTable 4KB 页面化物理存储(OPFS 后端默认启用,BufferPool LRU 缓存)、二级索引(跨重启恢复)、MVCC 事务、WAL 分片文件原子写入崩溃恢复(真追加 + 空洞检测)、ON UPDATE/DELETE 外键级联、Bloom Filter、**全库 AES-GCM 透明加密**(v0.5.0)、LZ4 压缩、Savepoint、EXPLAIN、ANALYZE、REINDEX、VACUUM、`repair()` 自愈(含孤儿页面清理)
- **适用**: 大规模数据分析、需要自研引擎可控性的高级场景
@@ -457,8 +453,8 @@ npm run typecheck # 类型检查
| 指标 | 数值 |
|------|------|
-| 测试用例 | 1022 |
-| 测试套件 | 64(+12 Playwright e2e) |
+| 测试用例 | 1049 |
+| 测试套件 | 65(+12 Playwright e2e) |
| 行覆盖率 | 89.3% |
| SQL 关键字 | 72 |
| 存储引擎 | 5(Memory / **KVStore** / OPFS / Hybrid / **Aria**) |
@@ -491,7 +487,8 @@ src/
├── core.ts # 主类
├── constants.ts # 类型定义 + 配置 + DatabaseError
├── connection-manager.ts # 连接池管理
-├── engine/ # 存储引擎(Memory/IndexedDB/OPFS/Aria)
+├── engine/ # 存储引擎(Memory/KVStore/OPFS/Aria + kvstore 自研 KV 引擎)
+├── migration/ # 旧 IndexedDB 数据迁移工具(一次性)
├── hybrid/ # 混合引擎(write-through)
├── table/ # 表管理 + Schema 校验
├── query/ # AST + Builder + Compiler + Executor
diff --git a/site/benchmark.html b/site/benchmark.html
index 6b3bd8c..a571b54 100644
--- a/site/benchmark.html
+++ b/site/benchmark.html
@@ -3,7 +3,7 @@