release: v0.3.2 — 质量加固 + SQL扩展 + 表达式 + 并发同步
v0.2.6 质量加固: - 修复 AriaEngine 二级索引 SSTable 互相覆盖(命名空间隔离) - 修复 LSM 多版本读取顺序错误 + MergeIterator 取最新来源 - 重写 LZ4 压缩器(往返一致性 + 缓冲区溢出) - sstableCache LRU 上限 + 预加载兜底(BufferPool 配置生效) - 修复 React/Vue 集成 import type 运行时 bug + exports 子路径 - 新增 38 个测试(LZ4往返/Crypto/集成), 删除伪测试 v0.3.0 SQL 功能扩展: - 多语句 parseAll + 事务语句 BEGIN/COMMIT/ROLLBACK - INSERT INTO ... SELECT + UNION/UNION ALL + EXISTS 关联子查询 - CREATE/DROP INDEX 五引擎实现 + 别名 WHERE 修复 - benchmark 页面 + 36 个新测试 v0.3.1 表达式与性能: - CASE WHEN 表达式(SELECT 列/WHERE/聚合) - JOIN + 关联子查询逐行绑定 - WAL 批量组提交(写放大 O(N)→O(1)) - 修复 pending frozen 可见性 + flush 缓存竞争 v0.3.2 并发: - CASE WHEN 用于 WHERE/聚合 + JOIN 哈希连接 - 多标签页同步(multiTabSync + BroadcastChannel) - IndexedDB schema 持久化(reopen 后表结构恢复) - 修复 where-matcher 顶层 $not - 修复 CJS 产物 .js 被 ESM 解析(exports 空) — .cjs 后缀 + exports 修正 - 836 测试 / 44 套件 / 81.0% 覆盖率
This commit is contained in:
+336
-241
@@ -1,241 +1,336 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to MetonaSqlark will be documented in this file.
|
||||
|
||||
## [0.2.5] - 2026-07-29
|
||||
|
||||
### Fixed
|
||||
- **版本号统一** — `constants.ts` VERSION 从 `'0.2.0'` 更新为 `'0.2.5'`,修正 `index.ts`/`utils.ts`/`CONTRIBUTING.md` 中过时的版本注释和数据
|
||||
- **AriaEngine OPFS 后端映射** — `core.ts` 中 `mode: 'aria'` + `diskEngine: 'opfs'` 时实际使用 Memory 后端的 bug 已修复
|
||||
- **`_onError` 接入执行路径** — `query()`/`defineTable()`/`dropTable()`/`transaction()`/`importTable()` 的 catch 路径现在调用 `_onError` 全局错误回调
|
||||
- **`maxRowsPerQuery` 生效** — `QueryExecutor` 构造时接收 `maxRowsPerQuery` 参数,SELECT 结果在返回前截断
|
||||
- **WAL full 模式真正同步** — `WAL.append()` 改为 `async`,`full` 模式下 `await this.store.append()` 真正等待写入完成,不再 fire-and-forget
|
||||
- **PluginManager.install 传 db 实例** — `register()` 增加可选 `db` 参数,`core.ts` 初始化时传入 `this`,插件可获取 db 引用
|
||||
|
||||
### Changed
|
||||
- **SSTableReader 二分查找统一** — `locateBlockGE`/`locateBlockLE` 从线性扫描改为二分查找,rangeScan 性能在大型 SSTable 下不再退化
|
||||
- **crypto 实例化** — 全局状态改为 `CryptoManager` 类,每个 AriaEngine 实例可拥有独立加密配置,保留全局函数向后兼容
|
||||
- **compactLevelSync 接口公开化** — LSM 新增 public `compactLevel()` 方法,`vacuum()` 不再使用 `as any` 绕过 private 访问
|
||||
- **WAL 大小阈值接入 checkpoint** — `CheckpointManager` 接收 `walSizeThreshold` 参数,WAL 缓冲超阈值时自动触发 checkpoint
|
||||
|
||||
### Added
|
||||
- **ALTER TABLE 语法** — 支持 `ALTER TABLE ... ADD COLUMN` / `DROP COLUMN`(含可选 COLUMN 关键字)
|
||||
- **TRUNCATE TABLE 语法** — 支持 `TRUNCATE TABLE name` 快速清空表数据
|
||||
- **MVCC 接入读写路径** — 事务内 insert/update/delete 调用 `mvcc.writeVersion`/`mvcc.deleteVersion`,版本链作为 undo log
|
||||
- **IndexedDB 索引利用** — `IndexedDBEngine.find` 等值查询时优先使用 IDB 索引(`idx_col` 命名约定),避免全量 getAll
|
||||
- **SQL 注入防护** — React `useTable` / Vue `useSqlarkTable` 增加表名合法性校验(`/^[a-zA-Z_][a-zA-Z0-9_]*$/`)
|
||||
|
||||
---
|
||||
|
||||
## [0.2.4] - 2026-07-27
|
||||
|
||||
### Added
|
||||
- **二级索引** — 每列可独立维护 LSM Tree 索引,`$eq`/`$in`/`$gt`/`$lt` 走索引 O(log n)
|
||||
- **MVCC 接入引擎** — MVCCManager 正式投产,替换 ad-hoc txnSnapshot
|
||||
- **MVCC 自动 GC** — 每 10 次 checkpoint 自动回收过旧版本(保留最新 100 个)
|
||||
- **Bloom Filter 序列化** — 写入 SSTable footer + 读取时加载 + 查询时 probe 快速否定
|
||||
- **WAL 大小阈值** — `walSizeThreshold` 配置(默认 16MB),超阈值强制 checkpoint
|
||||
- **内存预算** — `maxMemoryMB` 配置(默认 64MB)
|
||||
|
||||
### Changed
|
||||
- **WAL 默认同步模式** — `walSyncMode` 从 `'batch'` 改为 `'full'`,消除 crash 丢数据风险
|
||||
- **查询优化** — `tryIndexLookup` 扩展支持非 PK 列索引查找
|
||||
|
||||
---
|
||||
|
||||
## [0.2.3] - 2026-07-27
|
||||
|
||||
### Fixed
|
||||
- **RB-Tree fixDelete 完整实现** — 补全标准红黑树删除修复,保证 O(log n)
|
||||
- **LSM SSTable 缓存预热** — `init()` 预加载所有 SSTable,消除 cache miss
|
||||
- **OPFS 数据恢复** — `open()` 自动从 OPFS 文件加载已有表数据到内存
|
||||
- **Aria WAL 事务恢复** — 两阶段恢复:仅回放已提交事务,未提交数据不回放
|
||||
- **LZ4 格式修复** — 重写 token 格式,消除中间字面量 token 歧义
|
||||
|
||||
---
|
||||
|
||||
## [0.2.2] - 2026-07-27
|
||||
|
||||
### Added
|
||||
- **OPFS 自研存储后端** — AriaEngine 新增 `OPFSBackend`,纯浏览器文件系统 API,零 IndexedDB 依赖
|
||||
- 每个 key 对应一个二进制文件,存储在 `navigator.storage.getDirectory()` 下
|
||||
- 支持 read/write/delete/list/exists/clear 完整接口
|
||||
- 页面文件(4KB)、WAL 日志、Schema、SSTable 全部存储为独立文件
|
||||
- `{ dbName }/pg_1`, `{ dbName }/__wal_0`, `{ dbName }/__aria_schemas` ...
|
||||
|
||||
### Changed
|
||||
- `AriaEngineConfig.storageBackend` 已支持 `'opfs'`,`AriaEngine.open()` 自动选择 OPFSBackend
|
||||
|
||||
---
|
||||
|
||||
## [0.2.1] - 2026-07-27
|
||||
|
||||
### Fixed
|
||||
- **WAL CRC 校验验证** — 恢复时计算并验证 CRC32,损坏记录自动跳过并告警
|
||||
- **Hybrid 引擎提交顺序** — commit 先写磁盘再写内存,磁盘失败回滚内存,消除数据不一致风险
|
||||
- **RESTRICT 外键行为修正** — 检测到引用行时抛出 `FOREIGN_KEY_VIOLATION`,不再静默保留孤儿
|
||||
- **SSTable rangeScan 边界保护** — 空索引或 startBlockIdx > endBlockIdx 时安全返回
|
||||
|
||||
### Added
|
||||
- **ColumnDef 约束激活** — `maxLength`/`min`/`max` 约束在 `checkFieldType` 中正式生效
|
||||
- **查询结果上限** — `DatabaseConfig.maxRowsPerQuery`(默认 0 不限制),防止超大结果集 OOM
|
||||
- **onError 全局回调** — 配置中的 `onError` 回调实际接入 CRUD 异常路径
|
||||
- **debug 调试模式** — `DatabaseConfig.debug: true` 输出 `[MetonaSqlark:name]` 前缀的结构化日志
|
||||
- **浏览器兼容性声明** — README 增加 Chrome 80+/Firefox 80+/Safari 14+/Edge 80+ 支持矩阵
|
||||
|
||||
### Changed
|
||||
- MemoryEngine RESTRICT 外键行为:从"不级联保留孤儿"改为"禁止删除抛异常"
|
||||
- Hybrid 引擎 commitTransaction 磁盘优先于内存
|
||||
- DB_DEFAULTS 新增 `maxRowsPerQuery: 0` 和 `debug: false`
|
||||
|
||||
---
|
||||
|
||||
## [0.2.0] - 2026-07-27
|
||||
|
||||
### Added
|
||||
- **AriaEngine 自研存储引擎** — 基于 LSM-Tree 的页面式存储引擎,19 个新模块,~3500 行 TypeScript
|
||||
- **页面格式层** (`page/`): 4KB Slotted Page 编解码、Tuple 二进制序列化、CRC32 校验
|
||||
- **Buffer Pool** (`buffer/`): LRU 页面缓存 + 驱逐策略,可控内存占用
|
||||
- **LSM-Tree 索引** (`index/`): MemTable (红黑树) + 多级 SSTable + Leveled Compaction
|
||||
- **Bloom Filter** (`index/bloom.ts`): FNV-1a + Murmur 双哈希,快速键否定判定
|
||||
- **SSTable 构建器/读取器** (`index/sstable_builder.ts`, `sstable.ts`): 二分查找 + 范围扫描
|
||||
- **Merge Iterator** (`index/merge_iterator.ts`): 最小堆多路归并,去重保留最新值
|
||||
- **WAL** (`wal/`): 二进制日志格式 (LSN/type/txnId/table/key/json/CRC) + Checkpoint 管理
|
||||
- **MVCC** (`transaction/mvcc.ts`): 版本链 + 快照隔离 + GC
|
||||
- **存储后端** (`store/`): IndexedDB / Memory 双后端抽象
|
||||
- **LZ4 压缩** (`compression/lz4.ts`): 简易页面级压缩
|
||||
- **`mode: 'aria'`** — 新增存储模式,可通过 `MetonaSqlark.create({ mode: 'aria' })` 激活
|
||||
- **Schema 持久化** — 表结构自动保存到 `__aria_schemas`,重启自动恢复
|
||||
- **SSTable 元数据管理** — SSTable 索引信息持久化,启动时自动扫描加载
|
||||
- **事务感知 CRUD** — insert/update/delete 在事务中缓冲到 snapshot,commit 批量写入 LSM
|
||||
- **244 个 AriaEngine 专项测试** — 覆盖生命周期/表管理/CRUD/事务/持久化/SQL 集成/页面格式/LSM/压缩
|
||||
|
||||
### Changed
|
||||
- `StorageMode` 类型新增 `'aria'`
|
||||
- `STORAGE_MODES` 数组新增 `'aria'`
|
||||
- `createEngine()` 支持 `mode: 'aria'` 分支
|
||||
- 测试从 318 → **526**,套件从 20 → **27**
|
||||
- 新增 7 个模块级测试文件:`aria-page`、`aria-index`、`aria-sstable`、`aria-buffer`、`aria-wal-mvcc`、`aria-compress`、`aria`
|
||||
- LRUList 修复 size 追踪 bug
|
||||
- WAL 存储改为按记录独立 key(避免拼接缓冲区越界)
|
||||
- CheckpointManager 解耦 BufferPool 依赖
|
||||
|
||||
### Fixed
|
||||
- **LZ4 压缩无限循环** — 字面量分支在发现匹配后回退导致 litLen=0 死循环,CI 卡死根因
|
||||
- **SSTableReader.get() 自比较 bug** — 参数 key 被循环变量遮蔽导致永远返回第一条
|
||||
- **CheckpointManager 测试 null 引用** — 改为 Mock 对象避免 TypeError 导致进程无法退出
|
||||
- **IndexedDB 持久化测试** — 替换为 Memory Backend 验证,消除 fake-indexeddb timer 堆积
|
||||
- **LSM.flush() 不必要 setTimeout** — 替换为 Promise.resolve(),消除额外 timer 延迟
|
||||
|
||||
---
|
||||
|
||||
## [0.1.14] - 2026-07-26
|
||||
|
||||
### Fixed
|
||||
- **IndexedDB 事务原子性**: `flushToIDB` 改为单 IDB 事务包裹 clear+insert,消除崩溃丢数据风险
|
||||
- **多标签页冲突**: `open()` 添加 `onversionchange` 监听,其他标签页升级版本时自动关闭过期连接
|
||||
- **Memory 引擎幂等**: `open()` 重复调用安全无副作用
|
||||
- 关闭时清理 `onversionchange` 监听器,防止内存泄漏
|
||||
|
||||
---
|
||||
|
||||
## [0.1.13] - 2026-07-26
|
||||
|
||||
### Added
|
||||
- **事务回滚机制**: `IStorageEngine` 新增 `beginTransaction/commitTransaction/rollbackTransaction` 接口
|
||||
- MemoryEngine: 快照式回滚(深拷贝 tables/schemas/indexes)
|
||||
- IndexedDBEngine: 延迟写入策略(事务中仅写内存,commit 批量刷 IDB)
|
||||
- OPFSEngine: 快照式回滚(commit 批量写文件)
|
||||
- HybridEngine: 同时代理内存+磁盘引擎事务
|
||||
- **子查询支持**: SQL Parser + Executor 支持 `IN (SELECT ...)` 和 `op (SELECT ...)` 子查询
|
||||
- AST 新增 `SubqueryExpression` 类型
|
||||
- Parser 在 IN 和比较运算符后检测子查询
|
||||
- Executor 新增 `resolveSubqueries()` 递归解析,自动执行子查询并替换为具体值
|
||||
- **外键级联操作**: ColumnDef 新增 `onDelete/onUpdate` 选项
|
||||
- 支持 `CASCADE`(递归级联删除)、`SET NULL`、`RESTRICT`
|
||||
- SQL Parser 解析 `REFERENCES table(col) ON DELETE CASCADE ON UPDATE CASCADE`
|
||||
- MemoryEngine 内置 `cascadeDelete()` 递归级联逻辑
|
||||
- **连接池管理**: `MetonaSqlark.connect()` 静态方法
|
||||
- 同名数据库复用已打开实例,引用计数管理
|
||||
- `db.disconnect()` 释放连接,归零自动 close
|
||||
- `MetonaSqlark.disconnectAll()` 强制关闭所有连接
|
||||
|
||||
### Changed
|
||||
- `TransactionManager.execute()` 调用引擎层 begin/commit/rollback 实现真正原子性
|
||||
- IndexedDBEngine CRUD 事务感知:活跃事务中延迟 IDB 写入
|
||||
- ASTColumnDef / astColumnToColumnDef 支持 references/onDelete/onUpdate 透传
|
||||
|
||||
### Fixed
|
||||
- IndexedDBEngine 事务中 find/count 从内存缓存读取(保证读到未提交变更)
|
||||
- SQL Parser parseColumnDef 循环条件扩展,避免 REFERENCES 语法解析中断
|
||||
|
||||
---
|
||||
|
||||
## [0.1.12] - 2026-07-26
|
||||
|
||||
### Added
|
||||
- `MeSqlark` 别名导出,与 `MetonaSqlark` 完全等价
|
||||
- `metona-sqlark.cjs.js` CommonJS 构建产物
|
||||
- 完善的 `where-matcher.ts` 消除 220+ 行重复代码
|
||||
- `$col` 列引用支持 JOIN ON 条件
|
||||
- `$and/$or` 嵌套支持(字段级 + 顶层)
|
||||
- `$not` 逻辑非操作符
|
||||
- `$like` 正则缓存加速
|
||||
- `projectColumns` 列投影支持 `table.column` 格式
|
||||
- `DISTINCT` 去重支持(O(n) 时间,列值拼接优化)
|
||||
- 测试覆盖率提升至 93.46%(264 测试/15 套件)
|
||||
|
||||
### Changed
|
||||
- `where-matcher` 统一 MemoryEngine / IndexedDBEngine / Executor 的 WHERE 逻辑
|
||||
- JOIN ON 匹配支持 `$col` 语法
|
||||
- LIKE 正则改为缓存式编译
|
||||
- Executor DISTINCT 用列值拼接代替 JSON.stringify
|
||||
- JOIN 嵌套循环连接优化:避免 ON 时对象扩散
|
||||
|
||||
### Fixed
|
||||
- IndexedDBEngine `update/delete` 方法正确同步内存缓存
|
||||
- OPFSEngine `getTableNames` 兼容 `entries()` 返回值
|
||||
- SQL Parser 正确处理字符串转义字符
|
||||
- SQL Parser 正确处理表别名(无 AS 关键字)
|
||||
- SQL Parser 解析 `IS NULL` / `IS NOT NULL` / `NOT LIKE`
|
||||
- `peekTokenIs` 方法正确暴露给语法分析
|
||||
- 多处边界条件空值/假值处理
|
||||
|
||||
---
|
||||
|
||||
## [0.1.11] - 2026-07-25
|
||||
|
||||
### Added
|
||||
- React 集成 hooks: `useQuery`, `useTable`, `useDatabase`
|
||||
- Vue 集成 composables: `useSqlarkQuery`, `useSqlarkTable`, `useSqlarkDatabase`
|
||||
- 发布订阅系统: `subscribe()`, `emit()`
|
||||
- 数据迁移系统: `addMigration()`, `migrateTo()`
|
||||
- 导入导出: `exportTable()`, `exportAll()`, `importTable()`
|
||||
- 完整 SQL 解析器: `Lexer` + `Parser`(递归下降)
|
||||
- SQL 支持: SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE
|
||||
- JOIN 支持: INNER, LEFT, RIGHT, CROSS
|
||||
- GROUP BY + HAVING + 聚合函数 (COUNT, SUM, AVG, MIN, MAX)
|
||||
- DISTINCT, ORDER BY, LIMIT, OFFSET
|
||||
- WHERE 条件: AND, OR, NOT, IN, LIKE, IS NULL
|
||||
- Query Builder 链式 API: `select().where().orderBy().limit().execute()`
|
||||
- 插件系统: 14 种生命周期钩子 + PluginManager
|
||||
- Metadata 系统: ColumnDef 完整约束 (type/primaryKey/required/unique/index/default/references/maxLength/min/max)
|
||||
|
||||
### Changed
|
||||
- 架构重构为分层设计:Engine → QueryExecutor → Table/QueryBuilder → SQL Parser → Public API
|
||||
- AST 作为统一中间表示,SQL 和 QueryBuilder 行为完全一致
|
||||
- 测试框架完善:core / edge / groupby / join / query-system / sql / table / engine / transaction / plugin / hybrid 全覆盖
|
||||
|
||||
---
|
||||
|
||||
## [0.0.1] - 2026-07-24
|
||||
|
||||
### Added
|
||||
- 初始项目骨架
|
||||
- TypeScript 配置(严格模式)
|
||||
- Rollup 构建(UMD / ESM / CJS / min / .d.ts)
|
||||
- Jest + jsdom 测试环境
|
||||
- ESLint + @typescript-eslint
|
||||
- Gitea Actions CI 工作流
|
||||
- 示例站点(index / demo / docs)
|
||||
- 构建脚本 build.sh
|
||||
# Changelog
|
||||
|
||||
All notable changes to MetonaSqlark will be documented in this file.
|
||||
|
||||
## [0.3.2] - 2026-08-08
|
||||
|
||||
### Added
|
||||
- **CASE WHEN 用于 WHERE** — `WHERE CASE WHEN cond THEN a ELSE b END = 'x'` 逐行求值(含 NOT/AND/OR 组合)
|
||||
- **CASE WHEN 用于聚合** — `SUM(CASE WHEN age > 18 THEN 1 ELSE 0 END)`、`COUNT/AVG/MIN/MAX(CASE...)`、`GROUP BY + CASE` 非聚合列
|
||||
- **JOIN 哈希连接** — 等值 ON + 右表主键/索引列时,收集左表连接值 → 一次 `$in` 查询 → 哈希映射匹配,替代嵌套循环(INNER/LEFT JOIN,O(N+M));不适用自动回退
|
||||
- **多标签页同步** — `multiTabSync: true` 配置 + BroadcastChannel:
|
||||
- SQL 写语句(INSERT/UPDATE/DELETE/DDL)自动广播表变更
|
||||
- Table API 写入(insert/insertMany/update/delete/clear/drop)自动广播
|
||||
- 其他标签页收到 `external` 变更事件(订阅者可见)+ Hybrid 内存自动重载
|
||||
- `db.broadcastChange(table)` 手动广播
|
||||
- **IndexedDB schema 持久化** — `__metona_schema` store 保存完整列定义,reopen(页面刷新/重连)后恢复;旧数据回退为"主键 + 索引 + 样例推断"
|
||||
|
||||
### Fixed
|
||||
- **IndexedDB reopen 后 schema 丢失(严重)** — schema 仅存内存缓存,close 后重开连接表结构即丢失(INSERT 列映射截断、UPDATE 全列失效)。v0.3.2 持久化 + 重建
|
||||
- **where-matcher 顶层 $not 不生效** — `NOT (expr)` 解析为顶层 `{ $not }` 但被当作字段匹配,始终返回 true
|
||||
- **CASE 剥离后空 `$not` 恒假** — 引擎层执行 `NOT(true)` 过滤掉所有行
|
||||
|
||||
### Changed
|
||||
- 版本号升至 v0.3.2
|
||||
|
||||
---
|
||||
|
||||
## [0.3.1] - 2026-08-08
|
||||
|
||||
### Added
|
||||
- **CASE WHEN 表达式(SELECT 列)** — `CASE WHEN cond THEN value [WHEN ...] [ELSE value] END [AS alias]`
|
||||
- 多 WHEN 按顺序匹配、ELSE 缺省返回 null
|
||||
- THEN/ELSE 值支持字面量(字符串/数字/布尔/null)与列引用
|
||||
- 条件支持 AND/OR/比较运算符/IS NULL 等完整 WHERE 语法
|
||||
- 引擎层返回原始行供求值(避免投影丢失条件列),与普通列混合投影
|
||||
- **JOIN + 关联子查询** — JOIN 结果的 WHERE 支持 `EXISTS (SELECT ... WHERE o2.x = u.y)` 与 `$col` 引用外层行,逐行绑定求值
|
||||
- **WAL 批量组提交** — `WAL.appendBatch()` 合并多条记录为一次底层写入;引擎 insert/update/delete 批量记录后一次落盘(写放大从 O(N) 降为 O(1))
|
||||
- **`parseWhereCondition()` 导出** — 独立条件表达式解析(CASE WHEN 求值内部使用)
|
||||
|
||||
### Fixed
|
||||
- **LSM pending frozen 可见性** — 异步 flush 链期间,中间冻结的 MemTable 仅存在于闭包中,读取路径不可见导致数据缺失。新增 `frozenMemtables` 列表,get/rangeScan/getAllEntries 遍历所有 pending frozen(新→旧)
|
||||
- **flush 缓存裁剪与预加载竞争** — flush 完成时的 LRU 裁剪会驱逐 prefetch 刚加载的 SSTable,导致扫描静默丢数据。prefetchRange/prefetchKeys 先等待 flush 链完成再加载
|
||||
- **CASE 值解析顺序** — `true`/`false`/`null` 字面量被误判为列引用
|
||||
|
||||
### Changed
|
||||
- 版本号升至 v0.3.1
|
||||
|
||||
---
|
||||
|
||||
## [0.3.0] - 2026-08-08
|
||||
|
||||
### Added
|
||||
- **SQL 多语句支持** — `parseAll()` 解析分号分隔的多条语句,`db.query()` 顺序执行并返回最后一条结果(`parse()` 保持单语句兼容)
|
||||
- **事务语句(TCL)** — `BEGIN` / `COMMIT` / `ROLLBACK`(支持可选 TRANSACTION 关键字),直接驱动引擎层事务,五引擎可用
|
||||
- **INSERT INTO ... SELECT** — 支持 `INSERT INTO t (cols) SELECT ...`(含 WHERE 过滤、列映射)
|
||||
- **UNION / UNION ALL** — 支持去重合并与链式组合(`A UNION B UNION C`),右侧结果按位置投影到左侧列结构
|
||||
- **CREATE INDEX / DROP INDEX** — 动态二级索引:
|
||||
- `CREATE [UNIQUE] INDEX idx ON table (col)` / `DROP INDEX idx ON table (col)`
|
||||
- 五引擎实现:Memory 哈希索引 / IndexedDB 版本升级建 `idx_col` / OPFS 委托 / Hybrid 双写 / Aria 动态 LSM 索引
|
||||
- Aria 主键索引受保护(不可 DROP);CREATE INDEX 对已有数据立即建索引(回填),后续写入自动同步
|
||||
- **EXISTS / NOT EXISTS** — 支持关联子查询(`WHERE EXISTS (SELECT 1 FROM o WHERE o.user_id = u.id)`),逐行绑定外层上下文求值
|
||||
- **别名 WHERE 修复** — `WHERE u.age > 20`(主表别名前缀)此前不工作,v0.3.0 字段名规范化(JOIN 路径不受影响)
|
||||
- **`SELECT 1` 常量列** — 数字字面量可作为 SELECT 列(EXISTS 子查询常见用法)
|
||||
- **benchmark 页面** — `site/benchmark.html` 浏览器内实测 Memory / Aria 引擎 × 1K/10K/50K 行的 INSERT/PK 查询/索引查询/UPDATE/DELETE 吞吐(ops/sec)
|
||||
- **`parseAll` / 新 AST 类型导出** — `SelectUnionStatement` / `CreateIndexStatement` / `DropIndexStatement` / `BeginTransactionStatement` 等
|
||||
|
||||
### Changed
|
||||
- 版本号升至 v0.3.0
|
||||
|
||||
### Fixed
|
||||
- `NOT EXISTS` 解析丢 EXISTS token 导致 parse 失败
|
||||
|
||||
---
|
||||
|
||||
## [0.2.6] - 2026-08-08
|
||||
|
||||
### Fixed
|
||||
- **AriaEngine 二级索引 SSTable 互相覆盖(严重)** — 主 LSM 与二级索引 LSM 此前共享同一 `sstableStore`(id 空间 + meta 列表),`allocateId()` 返回 `Date.now()` 且各 LSM 从同一 meta 恢复 `nextSSTableId`,高频写入时 id 冲突导致索引数据文件覆盖主数据、meta 与数据错配。v0.2.6 按命名空间隔离(文件前缀 + meta key + 独立 id 序列),索引 LSM 各持独立 store
|
||||
- **LSM 多版本读取顺序错误(严重)** — `levels[]` 数组按 `push` 追加(新文件在尾部),但 `get()`/`rangeScan` 从头遍历(旧文件优先),同一 key 跨多次 flush 更新后读到旧值;`MergeIterator` 去重只取"先出堆者",不保证最新来源。v0.2.6 改为"数组头部即最新"(`unshift` + 按 id 降序加载),MergeIterator 显式取 sourceIndex 最小者
|
||||
- **LZ4 往返不一致** — ① 匹配长度超过 19 字节被截断但 `si` 跳过全部匹配,解压丢数据;② matchField=0 的组合 token 与纯字面量 token 格式歧义;③ 字面量累积超过 15 字节后组合 token 永远无法输出;④ 输出缓冲区 `maxOut` 不足导致越界写入;⑤ 压缩失败时返回原样 input,解压端无法区分。v0.2.6 重写压缩器(长匹配分段、纯字面量 token 语义明确、动态上限)
|
||||
- **React/Vue 集成运行时 ReferenceError** — `useDatabase`/`useSqlarkDatabase` 用 `import type` 导入 `MetonaSqlark` 但运行时 `new MetonaSqlark()`,`@ts-nocheck` 掩盖此 bug,实际使用必炸。改为 value import
|
||||
- **sstableCache 无限增长** — SSTable 缓存无内存上限且 `init()` 预加载全部数据,大库 OOM。v0.2.6 引入 LRU 容量上限(`bufferPoolPages` × `pageSize`),查询前异步预加载兜底(修复缓存未命中静默返回 null 丢数据的隐患)
|
||||
- **integrations 子路径缺失** — README 宣称 `metona-sqlark/react`、`metona-sqlark/vue` 可用但 `exports` 未声明,现已补齐(react/vue 为 peer dependency,rollup external)
|
||||
|
||||
### Changed
|
||||
- **Buffer Pool 配置真正生效** — `bufferPoolPages` 从无效配置变为 SSTable 缓存容量上限(默认 256 页 ≈ 1MB 可控内存)
|
||||
- **LZ4 格式变更** — 旧版本压缩数据与新解压器不兼容,使用 `compression: true` 的用户需重新导入数据
|
||||
- **SSTable 持久化串行化** — flush/compaction 改为串行链(`flushChain`),id 分配与持久化顺序一致,消除 fire-and-forget 竞态
|
||||
- 文档数据修正 — 测试 761(41 套件)、覆盖率 81.1%(此前 91.0% 为排除 Aria 模块的陈旧数据)、体积 ~105KB / gzip ~27KB
|
||||
|
||||
### Added
|
||||
- **AriaEngine 缓存内存上限测试** — 9 个测试:LRU 上限约束、驱逐后全表/PK/索引查询完整性、UPDATE/DELETE 全量作用、写路径上限、命名空间隔离回归、多版本回归、tombstone 回归
|
||||
- **LZ4 往返一致性测试** — 6 个往返测试(重复/文本/随机/边界长度/15 字节边界/长匹配)
|
||||
- **CryptoManager 加解密测试** — 7 个测试(往返/错误密码/不同 salt/实例隔离/全局兼容层/4KB 页面)
|
||||
- **React/Vue hooks 集成测试** — 16 个测试(jest.mock 零依赖:mount 执行、错误路径、refresh、注入防护、数据库初始化)
|
||||
- **jest.setup.js WebCrypto polyfill** — jsdom 环境补齐 `crypto.subtle` 支持 AES-GCM
|
||||
|
||||
---
|
||||
|
||||
## [0.2.5] - 2026-07-29
|
||||
|
||||
### Fixed
|
||||
- **版本号统一** — `constants.ts` VERSION 从 `'0.2.0'` 更新为 `'0.2.5'`,修正 `index.ts`/`utils.ts`/`CONTRIBUTING.md` 中过时的版本注释和数据
|
||||
- **AriaEngine OPFS 后端映射** — `core.ts` 中 `mode: 'aria'` + `diskEngine: 'opfs'` 时实际使用 Memory 后端的 bug 已修复
|
||||
- **`_onError` 接入执行路径** — `query()`/`defineTable()`/`dropTable()`/`transaction()`/`importTable()` 的 catch 路径现在调用 `_onError` 全局错误回调
|
||||
- **`maxRowsPerQuery` 生效** — `QueryExecutor` 构造时接收 `maxRowsPerQuery` 参数,SELECT 结果在返回前截断
|
||||
- **WAL full 模式真正同步** — `WAL.append()` 改为 `async`,`full` 模式下 `await this.store.append()` 真正等待写入完成,不再 fire-and-forget
|
||||
- **PluginManager.install 传 db 实例** — `register()` 增加可选 `db` 参数,`core.ts` 初始化时传入 `this`,插件可获取 db 引用
|
||||
|
||||
### Changed
|
||||
- **SSTableReader 二分查找统一** — `locateBlockGE`/`locateBlockLE` 从线性扫描改为二分查找,rangeScan 性能在大型 SSTable 下不再退化
|
||||
- **crypto 实例化** — 全局状态改为 `CryptoManager` 类,每个 AriaEngine 实例可拥有独立加密配置,保留全局函数向后兼容
|
||||
- **compactLevelSync 接口公开化** — LSM 新增 public `compactLevel()` 方法,`vacuum()` 不再使用 `as any` 绕过 private 访问
|
||||
- **WAL 大小阈值接入 checkpoint** — `CheckpointManager` 接收 `walSizeThreshold` 参数,WAL 缓冲超阈值时自动触发 checkpoint
|
||||
|
||||
### Added
|
||||
- **ALTER TABLE 语法** — 支持 `ALTER TABLE ... ADD COLUMN` / `DROP COLUMN`(含可选 COLUMN 关键字)
|
||||
- **TRUNCATE TABLE 语法** — 支持 `TRUNCATE TABLE name` 快速清空表数据
|
||||
- **MVCC 接入读写路径** — 事务内 insert/update/delete 调用 `mvcc.writeVersion`/`mvcc.deleteVersion`,版本链作为 undo log
|
||||
- **IndexedDB 索引利用** — `IndexedDBEngine.find` 等值查询时优先使用 IDB 索引(`idx_col` 命名约定),避免全量 getAll
|
||||
- **SQL 注入防护** — React `useTable` / Vue `useSqlarkTable` 增加表名合法性校验(`/^[a-zA-Z_][a-zA-Z0-9_]*$/`)
|
||||
|
||||
---
|
||||
|
||||
## [0.2.4] - 2026-07-27
|
||||
|
||||
### Added
|
||||
- **二级索引** — 每列可独立维护 LSM Tree 索引,`$eq`/`$in`/`$gt`/`$lt` 走索引 O(log n)
|
||||
- **MVCC 接入引擎** — MVCCManager 正式投产,替换 ad-hoc txnSnapshot
|
||||
- **MVCC 自动 GC** — 每 10 次 checkpoint 自动回收过旧版本(保留最新 100 个)
|
||||
- **Bloom Filter 序列化** — 写入 SSTable footer + 读取时加载 + 查询时 probe 快速否定
|
||||
- **WAL 大小阈值** — `walSizeThreshold` 配置(默认 16MB),超阈值强制 checkpoint
|
||||
- **内存预算** — `maxMemoryMB` 配置(默认 64MB)
|
||||
|
||||
### Changed
|
||||
- **WAL 默认同步模式** — `walSyncMode` 从 `'batch'` 改为 `'full'`,消除 crash 丢数据风险
|
||||
- **查询优化** — `tryIndexLookup` 扩展支持非 PK 列索引查找
|
||||
|
||||
---
|
||||
|
||||
## [0.2.3] - 2026-07-27
|
||||
|
||||
### Fixed
|
||||
- **RB-Tree fixDelete 完整实现** — 补全标准红黑树删除修复,保证 O(log n)
|
||||
- **LSM SSTable 缓存预热** — `init()` 预加载所有 SSTable,消除 cache miss
|
||||
- **OPFS 数据恢复** — `open()` 自动从 OPFS 文件加载已有表数据到内存
|
||||
- **Aria WAL 事务恢复** — 两阶段恢复:仅回放已提交事务,未提交数据不回放
|
||||
- **LZ4 格式修复** — 重写 token 格式,消除中间字面量 token 歧义
|
||||
|
||||
---
|
||||
|
||||
## [0.2.2] - 2026-07-27
|
||||
|
||||
### Added
|
||||
- **OPFS 自研存储后端** — AriaEngine 新增 `OPFSBackend`,纯浏览器文件系统 API,零 IndexedDB 依赖
|
||||
- 每个 key 对应一个二进制文件,存储在 `navigator.storage.getDirectory()` 下
|
||||
- 支持 read/write/delete/list/exists/clear 完整接口
|
||||
- 页面文件(4KB)、WAL 日志、Schema、SSTable 全部存储为独立文件
|
||||
- `{ dbName }/pg_1`, `{ dbName }/__wal_0`, `{ dbName }/__aria_schemas` ...
|
||||
|
||||
### Changed
|
||||
- `AriaEngineConfig.storageBackend` 已支持 `'opfs'`,`AriaEngine.open()` 自动选择 OPFSBackend
|
||||
|
||||
---
|
||||
|
||||
## [0.2.1] - 2026-07-27
|
||||
|
||||
### Fixed
|
||||
- **WAL CRC 校验验证** — 恢复时计算并验证 CRC32,损坏记录自动跳过并告警
|
||||
- **Hybrid 引擎提交顺序** — commit 先写磁盘再写内存,磁盘失败回滚内存,消除数据不一致风险
|
||||
- **RESTRICT 外键行为修正** — 检测到引用行时抛出 `FOREIGN_KEY_VIOLATION`,不再静默保留孤儿
|
||||
- **SSTable rangeScan 边界保护** — 空索引或 startBlockIdx > endBlockIdx 时安全返回
|
||||
|
||||
### Added
|
||||
- **ColumnDef 约束激活** — `maxLength`/`min`/`max` 约束在 `checkFieldType` 中正式生效
|
||||
- **查询结果上限** — `DatabaseConfig.maxRowsPerQuery`(默认 0 不限制),防止超大结果集 OOM
|
||||
- **onError 全局回调** — 配置中的 `onError` 回调实际接入 CRUD 异常路径
|
||||
- **debug 调试模式** — `DatabaseConfig.debug: true` 输出 `[MetonaSqlark:name]` 前缀的结构化日志
|
||||
- **浏览器兼容性声明** — README 增加 Chrome 80+/Firefox 80+/Safari 14+/Edge 80+ 支持矩阵
|
||||
|
||||
### Changed
|
||||
- MemoryEngine RESTRICT 外键行为:从"不级联保留孤儿"改为"禁止删除抛异常"
|
||||
- Hybrid 引擎 commitTransaction 磁盘优先于内存
|
||||
- DB_DEFAULTS 新增 `maxRowsPerQuery: 0` 和 `debug: false`
|
||||
|
||||
---
|
||||
|
||||
## [0.2.0] - 2026-07-27
|
||||
|
||||
### Added
|
||||
- **AriaEngine 自研存储引擎** — 基于 LSM-Tree 的页面式存储引擎,19 个新模块,~3500 行 TypeScript
|
||||
- **页面格式层** (`page/`): 4KB Slotted Page 编解码、Tuple 二进制序列化、CRC32 校验
|
||||
- **Buffer Pool** (`buffer/`): LRU 页面缓存 + 驱逐策略,可控内存占用
|
||||
- **LSM-Tree 索引** (`index/`): MemTable (红黑树) + 多级 SSTable + Leveled Compaction
|
||||
- **Bloom Filter** (`index/bloom.ts`): FNV-1a + Murmur 双哈希,快速键否定判定
|
||||
- **SSTable 构建器/读取器** (`index/sstable_builder.ts`, `sstable.ts`): 二分查找 + 范围扫描
|
||||
- **Merge Iterator** (`index/merge_iterator.ts`): 最小堆多路归并,去重保留最新值
|
||||
- **WAL** (`wal/`): 二进制日志格式 (LSN/type/txnId/table/key/json/CRC) + Checkpoint 管理
|
||||
- **MVCC** (`transaction/mvcc.ts`): 版本链 + 快照隔离 + GC
|
||||
- **存储后端** (`store/`): IndexedDB / Memory 双后端抽象
|
||||
- **LZ4 压缩** (`compression/lz4.ts`): 简易页面级压缩
|
||||
- **`mode: 'aria'`** — 新增存储模式,可通过 `MetonaSqlark.create({ mode: 'aria' })` 激活
|
||||
- **Schema 持久化** — 表结构自动保存到 `__aria_schemas`,重启自动恢复
|
||||
- **SSTable 元数据管理** — SSTable 索引信息持久化,启动时自动扫描加载
|
||||
- **事务感知 CRUD** — insert/update/delete 在事务中缓冲到 snapshot,commit 批量写入 LSM
|
||||
- **244 个 AriaEngine 专项测试** — 覆盖生命周期/表管理/CRUD/事务/持久化/SQL 集成/页面格式/LSM/压缩
|
||||
|
||||
### Changed
|
||||
- `StorageMode` 类型新增 `'aria'`
|
||||
- `STORAGE_MODES` 数组新增 `'aria'`
|
||||
- `createEngine()` 支持 `mode: 'aria'` 分支
|
||||
- 测试从 318 → **526**,套件从 20 → **27**
|
||||
- 新增 7 个模块级测试文件:`aria-page`、`aria-index`、`aria-sstable`、`aria-buffer`、`aria-wal-mvcc`、`aria-compress`、`aria`
|
||||
- LRUList 修复 size 追踪 bug
|
||||
- WAL 存储改为按记录独立 key(避免拼接缓冲区越界)
|
||||
- CheckpointManager 解耦 BufferPool 依赖
|
||||
|
||||
### Fixed
|
||||
- **LZ4 压缩无限循环** — 字面量分支在发现匹配后回退导致 litLen=0 死循环,CI 卡死根因
|
||||
- **SSTableReader.get() 自比较 bug** — 参数 key 被循环变量遮蔽导致永远返回第一条
|
||||
- **CheckpointManager 测试 null 引用** — 改为 Mock 对象避免 TypeError 导致进程无法退出
|
||||
- **IndexedDB 持久化测试** — 替换为 Memory Backend 验证,消除 fake-indexeddb timer 堆积
|
||||
- **LSM.flush() 不必要 setTimeout** — 替换为 Promise.resolve(),消除额外 timer 延迟
|
||||
|
||||
---
|
||||
|
||||
## [0.1.14] - 2026-07-26
|
||||
|
||||
### Fixed
|
||||
- **IndexedDB 事务原子性**: `flushToIDB` 改为单 IDB 事务包裹 clear+insert,消除崩溃丢数据风险
|
||||
- **多标签页冲突**: `open()` 添加 `onversionchange` 监听,其他标签页升级版本时自动关闭过期连接
|
||||
- **Memory 引擎幂等**: `open()` 重复调用安全无副作用
|
||||
- 关闭时清理 `onversionchange` 监听器,防止内存泄漏
|
||||
|
||||
---
|
||||
|
||||
## [0.1.13] - 2026-07-26
|
||||
|
||||
### Added
|
||||
- **事务回滚机制**: `IStorageEngine` 新增 `beginTransaction/commitTransaction/rollbackTransaction` 接口
|
||||
- MemoryEngine: 快照式回滚(深拷贝 tables/schemas/indexes)
|
||||
- IndexedDBEngine: 延迟写入策略(事务中仅写内存,commit 批量刷 IDB)
|
||||
- OPFSEngine: 快照式回滚(commit 批量写文件)
|
||||
- HybridEngine: 同时代理内存+磁盘引擎事务
|
||||
- **子查询支持**: SQL Parser + Executor 支持 `IN (SELECT ...)` 和 `op (SELECT ...)` 子查询
|
||||
- AST 新增 `SubqueryExpression` 类型
|
||||
- Parser 在 IN 和比较运算符后检测子查询
|
||||
- Executor 新增 `resolveSubqueries()` 递归解析,自动执行子查询并替换为具体值
|
||||
- **外键级联操作**: ColumnDef 新增 `onDelete/onUpdate` 选项
|
||||
- 支持 `CASCADE`(递归级联删除)、`SET NULL`、`RESTRICT`
|
||||
- SQL Parser 解析 `REFERENCES table(col) ON DELETE CASCADE ON UPDATE CASCADE`
|
||||
- MemoryEngine 内置 `cascadeDelete()` 递归级联逻辑
|
||||
- **连接池管理**: `MetonaSqlark.connect()` 静态方法
|
||||
- 同名数据库复用已打开实例,引用计数管理
|
||||
- `db.disconnect()` 释放连接,归零自动 close
|
||||
- `MetonaSqlark.disconnectAll()` 强制关闭所有连接
|
||||
|
||||
### Changed
|
||||
- `TransactionManager.execute()` 调用引擎层 begin/commit/rollback 实现真正原子性
|
||||
- IndexedDBEngine CRUD 事务感知:活跃事务中延迟 IDB 写入
|
||||
- ASTColumnDef / astColumnToColumnDef 支持 references/onDelete/onUpdate 透传
|
||||
|
||||
### Fixed
|
||||
- IndexedDBEngine 事务中 find/count 从内存缓存读取(保证读到未提交变更)
|
||||
- SQL Parser parseColumnDef 循环条件扩展,避免 REFERENCES 语法解析中断
|
||||
|
||||
---
|
||||
|
||||
## [0.1.12] - 2026-07-26
|
||||
|
||||
### Added
|
||||
- `MeSqlark` 别名导出,与 `MetonaSqlark` 完全等价
|
||||
- `metona-sqlark.cjs.js` CommonJS 构建产物
|
||||
- 完善的 `where-matcher.ts` 消除 220+ 行重复代码
|
||||
- `$col` 列引用支持 JOIN ON 条件
|
||||
- `$and/$or` 嵌套支持(字段级 + 顶层)
|
||||
- `$not` 逻辑非操作符
|
||||
- `$like` 正则缓存加速
|
||||
- `projectColumns` 列投影支持 `table.column` 格式
|
||||
- `DISTINCT` 去重支持(O(n) 时间,列值拼接优化)
|
||||
- 测试覆盖率提升至 93.46%(264 测试/15 套件)
|
||||
|
||||
### Changed
|
||||
- `where-matcher` 统一 MemoryEngine / IndexedDBEngine / Executor 的 WHERE 逻辑
|
||||
- JOIN ON 匹配支持 `$col` 语法
|
||||
- LIKE 正则改为缓存式编译
|
||||
- Executor DISTINCT 用列值拼接代替 JSON.stringify
|
||||
- JOIN 嵌套循环连接优化:避免 ON 时对象扩散
|
||||
|
||||
### Fixed
|
||||
- IndexedDBEngine `update/delete` 方法正确同步内存缓存
|
||||
- OPFSEngine `getTableNames` 兼容 `entries()` 返回值
|
||||
- SQL Parser 正确处理字符串转义字符
|
||||
- SQL Parser 正确处理表别名(无 AS 关键字)
|
||||
- SQL Parser 解析 `IS NULL` / `IS NOT NULL` / `NOT LIKE`
|
||||
- `peekTokenIs` 方法正确暴露给语法分析
|
||||
- 多处边界条件空值/假值处理
|
||||
|
||||
---
|
||||
|
||||
## [0.1.11] - 2026-07-25
|
||||
|
||||
### Added
|
||||
- React 集成 hooks: `useQuery`, `useTable`, `useDatabase`
|
||||
- Vue 集成 composables: `useSqlarkQuery`, `useSqlarkTable`, `useSqlarkDatabase`
|
||||
- 发布订阅系统: `subscribe()`, `emit()`
|
||||
- 数据迁移系统: `addMigration()`, `migrateTo()`
|
||||
- 导入导出: `exportTable()`, `exportAll()`, `importTable()`
|
||||
- 完整 SQL 解析器: `Lexer` + `Parser`(递归下降)
|
||||
- SQL 支持: SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE
|
||||
- JOIN 支持: INNER, LEFT, RIGHT, CROSS
|
||||
- GROUP BY + HAVING + 聚合函数 (COUNT, SUM, AVG, MIN, MAX)
|
||||
- DISTINCT, ORDER BY, LIMIT, OFFSET
|
||||
- WHERE 条件: AND, OR, NOT, IN, LIKE, IS NULL
|
||||
- Query Builder 链式 API: `select().where().orderBy().limit().execute()`
|
||||
- 插件系统: 14 种生命周期钩子 + PluginManager
|
||||
- Metadata 系统: ColumnDef 完整约束 (type/primaryKey/required/unique/index/default/references/maxLength/min/max)
|
||||
|
||||
### Changed
|
||||
- 架构重构为分层设计:Engine → QueryExecutor → Table/QueryBuilder → SQL Parser → Public API
|
||||
- AST 作为统一中间表示,SQL 和 QueryBuilder 行为完全一致
|
||||
- 测试框架完善:core / edge / groupby / join / query-system / sql / table / engine / transaction / plugin / hybrid 全覆盖
|
||||
|
||||
---
|
||||
|
||||
## [0.0.1] - 2026-07-24
|
||||
|
||||
### Added
|
||||
- 初始项目骨架
|
||||
- TypeScript 配置(严格模式)
|
||||
- Rollup 构建(UMD / ESM / CJS / min / .d.ts)
|
||||
- Jest + jsdom 测试环境
|
||||
- ESLint + @typescript-eslint
|
||||
- Gitea Actions CI 工作流
|
||||
- 示例站点(index / demo / docs)
|
||||
- 构建脚本 build.sh
|
||||
|
||||
Reference in New Issue
Block a user