feat: v0.7.0 参数化查询 + 事务增量 flush + 复合主键语义硬化 + EXPLAIN 真实索引信息
- 参数化查询 db.query(sql, params):词法层 ? 绑定 + SQL 字面量安全编码 ('' 转义/注入防护);参数计数不匹配 PARAM_ERROR;对象参数显式拒绝 - KVStoreEngine 事务增量 flush:行级变更追踪,commit 仅写改动行 (1000 行表改 1 行:日志 1 条目 vs 整表 1000 条目);级联影响表漏写修复 (txFullTables 同步加入 txDirtyTables);移除每次 commit 全量 checkpoint (阈值自动 checkpoint + close 统一截断) - 复合主键显式拒绝:createSchema 校验期 SCHEMA_ERROR + ALTER ADD 主键列防护 (此前静默取第一个主键,其余标记失效) - EXPLAIN usingIndex 真实命中信息:pk / index:col / none 测试 1126 → 1147(72 套件);行覆盖率 89.8%;版本 0.7.0
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
# MetonaSqlark
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/version-0.6.3-blue?style=flat-square" alt="version">
|
||||
<img src="https://img.shields.io/badge/version-0.7.0-blue?style=flat-square" alt="version">
|
||||
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="license">
|
||||
<img src="https://img.shields.io/badge/coverage-89.7%25-brightgreen?style=flat-square" alt="coverage">
|
||||
<img src="https://img.shields.io/badge/tests-1126%20passed-success?style=flat-square" alt="tests">
|
||||
<img src="https://img.shields.io/badge/coverage-89.8%25-brightgreen?style=flat-square" alt="coverage">
|
||||
<img src="https://img.shields.io/badge/tests-1147%20passed-success?style=flat-square" alt="tests">
|
||||
</p>
|
||||
|
||||
> 基于 TypeScript 的**前端关系型数据库**:完整 SQL + Query Builder 双 API,
|
||||
@@ -116,6 +116,10 @@ await db.defineTable('orders', {
|
||||
await db.query("INSERT INTO users VALUES ('1', 'Alice', 30, 'alice@demo.com')");
|
||||
const rows = await db.query('SELECT * FROM users WHERE age > 18 ORDER BY name');
|
||||
|
||||
// 参数化查询(v0.7.0)— 位置参数 `?`,安全编码杜绝 SQL 注入
|
||||
await db.query("INSERT INTO users VALUES (?, ?, ?, ?)", ['2', "O'Brien", 25, 'ob@demo.com']);
|
||||
const row2 = await db.query('SELECT * FROM users WHERE name = ?', ["O'Brien"]);
|
||||
|
||||
// Query Builder
|
||||
const result = await db.table('users')
|
||||
.select(['name', 'age'])
|
||||
@@ -213,7 +217,7 @@ await db2.disconnect(); // 引用计数 -1
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `db.query(sql)` | 执行 SQL(支持分号多语句) |
|
||||
| `db.query(sql)` / `db.query(sql, params)` | 执行 SQL(支持分号多语句;v0.7.0 位置参数 `?` 绑定) |
|
||||
| `db.queryStream(sql, onRow)` | 流式查询(逐行回调,不物化) |
|
||||
| `db.table(name)` | 获取表操作对象(`insert` / `select` / `update` / `delete` / `count` / `stream` / `clear` / `drop`) |
|
||||
| `db.defineTable(name, cols)` | 定义表结构 |
|
||||
@@ -233,7 +237,7 @@ await db2.disconnect(); // 引用计数 -1
|
||||
|
||||
| 语句 | 说明 | 支持引擎 |
|
||||
|------|------|----------|
|
||||
| `EXPLAIN SELECT ...` | 输出查询计划(type/table/where/estimatedRows/actualTimeMs) | 全部 |
|
||||
| `EXPLAIN SELECT ...` | 输出查询计划(type/table/where/usingIndex/estimatedRows/actualTimeMs) | 全部 |
|
||||
| `ANALYZE [TABLE] name` | 收集表统计信息(行数/行大小/索引深度/列基数) | Aria |
|
||||
| `REINDEX [TABLE] name` | 重建表二级索引 | Aria |
|
||||
| `VACUUM` | 压缩 LSM + 清理 MVCC 碎片 | Aria |
|
||||
@@ -397,7 +401,7 @@ const { data, loading, error, refresh } = useSqlarkQuery(db, 'SELECT * FROM user
|
||||
npm install # 安装依赖
|
||||
npm run dev # 开发模式(localhost:3001)
|
||||
npm run build # 生产构建(生成 dist/)
|
||||
npm test # 运行测试(1126 用例 · 71 套件)
|
||||
npm test # 运行测试(1147 用例 · 72 套件)
|
||||
npm run test:e2e # Playwright e2e(真实 Chromium + OPFS + 崩溃注入,需先 build)
|
||||
npm run lint # 代码检查
|
||||
npm run typecheck # 类型检查
|
||||
@@ -409,9 +413,9 @@ npm run typecheck # 类型检查
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 测试用例 | 1126(+12 Playwright e2e) |
|
||||
| 测试用例 | 1147(+12 Playwright e2e) |
|
||||
| 测试套件 | 70 |
|
||||
| 行覆盖率 | 89.7% |
|
||||
| 行覆盖率 | 89.8% |
|
||||
| SQL 关键字 | 72 |
|
||||
| 存储引擎 | 5(Memory / KVStore / OPFS / Hybrid / Aria) |
|
||||
| 运行时依赖 | 0 |
|
||||
|
||||
Reference in New Issue
Block a user