feat: register context-aware db capabilities to jsmod

This commit is contained in:
AI Engineer 2026-05-30 19:27:02 +08:00
parent f8ede4fdc7
commit 47ab856f3c
12 changed files with 91 additions and 0 deletions

View File

@ -1,5 +1,9 @@
# 变更记录 - @go/db # 变更记录 - @go/db
## [1.3.5] - 2026-05-30
- **新增**: 注册到 `jsmod`
- **安全性**: 引入基于 Context 的细粒度权限控制。在 `SafeMode`仅允许读取操作Query所有写操作Exec/Insert/Update/Delete/Replace将被拦截并返回错误。严禁通过 JS 动态创建连接或同步 Schema。
## [1.0.12] - 2026-05-17 ## [1.0.12] - 2026-05-17
- **SQLite 极致优化 (超高并发支持)**: - **SQLite 极致优化 (超高并发支持)**:
- **读写分离与零锁读取**: 读操作 (`Query`) 实现零锁定,配合 WAL 模式彻底解决读写互斥问题;写操作由应用层 `sync.Mutex` 统一排队,规避 `database is locked` 错误。 - **读写分离与零锁读取**: 读操作 (`Query`) 实现零锁定,配合 WAL 模式彻底解决读写互斥问题;写操作由应用层 `sync.Mutex` 统一排队,规避 `database is locked` 错误。

BIN
auto_detect.db-shm Normal file

Binary file not shown.

BIN
auto_detect.db-wal Normal file

Binary file not shown.

1
go.mod
View File

@ -8,6 +8,7 @@ require (
apigo.cc/go/crypto v1.3.1 apigo.cc/go/crypto v1.3.1
apigo.cc/go/file v1.3.2 apigo.cc/go/file v1.3.2
apigo.cc/go/id v1.3.1 apigo.cc/go/id v1.3.1
apigo.cc/go/jsmod v1.0.1
apigo.cc/go/log v1.3.4 apigo.cc/go/log v1.3.4
apigo.cc/go/redis v1.3.2 apigo.cc/go/redis v1.3.2
apigo.cc/go/safe v1.3.1 apigo.cc/go/safe v1.3.1

2
go.sum
View File

@ -10,6 +10,8 @@ apigo.cc/go/file v1.3.2 h1:pu4oiDyiqgj3/eykfnJf+/6+A9v/Z0b3ClP5XK+lwG4=
apigo.cc/go/file v1.3.2/go.mod h1:vci4h0Pz94mV6dkniQkuyBYERVYeq7/LX4jJVuCg9hs= apigo.cc/go/file v1.3.2/go.mod h1:vci4h0Pz94mV6dkniQkuyBYERVYeq7/LX4jJVuCg9hs=
apigo.cc/go/id v1.3.1 h1:pkqi6VeWyQoHuIu0Zbx/RRxIAdM61Js0j6cY1M9XVCk= apigo.cc/go/id v1.3.1 h1:pkqi6VeWyQoHuIu0Zbx/RRxIAdM61Js0j6cY1M9XVCk=
apigo.cc/go/id v1.3.1/go.mod h1:P2/vl3tyW3US+ayOFSMoPIOCulNLBngNYPhXJC/Z7J4= apigo.cc/go/id v1.3.1/go.mod h1:P2/vl3tyW3US+ayOFSMoPIOCulNLBngNYPhXJC/Z7J4=
apigo.cc/go/jsmod v1.0.1 h1:vaz3cMQi75UVoALLfyV/Trs8iP/Nh28yN57IvBFpPGk=
apigo.cc/go/jsmod v1.0.1/go.mod h1:bmyeZtOAP/j5am+YRnaiM89smysK24K7ebk0koFtsSw=
apigo.cc/go/log v1.3.4 h1:UT8Neb9r4QjjbCFbTzw+ZeTxd+DmdmR5gNExeR4Cj+g= apigo.cc/go/log v1.3.4 h1:UT8Neb9r4QjjbCFbTzw+ZeTxd+DmdmR5gNExeR4Cj+g=
apigo.cc/go/log v1.3.4/go.mod h1:/Q/2r51xWSsrS4QN5U9jLiTw8n6qNC8kG9nuVHweY20= apigo.cc/go/log v1.3.4/go.mod h1:/Q/2r51xWSsrS4QN5U9jLiTw8n6qNC8kG9nuVHweY20=
apigo.cc/go/rand v1.3.1 h1:7FvsI6PtQ5XrWER0dTiLVo0p7GIxRidT/TBKhVy93j8= apigo.cc/go/rand v1.3.1 h1:7FvsI6PtQ5XrWER0dTiLVo0p7GIxRidT/TBKhVy93j8=

BIN
id_test.db-shm Normal file

Binary file not shown.

BIN
id_test.db-wal Normal file

Binary file not shown.

84
js_export.go Normal file
View File

@ -0,0 +1,84 @@
package db
import (
"context"
"errors"
"apigo.cc/go/jsmod"
)
func init() {
jsmod.Register("db", map[string]any{
"get": func(ctx context.Context, name string) (*jsDB, error) {
d := GetDB(name, nil)
if d.Error != nil {
return nil, d.Error
}
return &jsDB{db: d, ctx: ctx}, nil
},
})
}
type jsDB struct {
db *DB
ctx context.Context
}
var errSafeMode = errors.New("database write operation is restricted in safe mode")
func (jd *jsDB) checkSafe() error {
if jsmod.IsSafeMode(jd.ctx) {
return errSafeMode
}
return nil
}
// Read Operations (Always allowed)
func (jd *jsDB) Query(query string, args ...any) *QueryResult {
return jd.db.Query(query, args...)
}
// Write Operations (Restricted in SafeMode)
func (jd *jsDB) Exec(query string, args ...any) *ExecResult {
if jd.checkSafe() != nil {
return &ExecResult{Error: errSafeMode}
}
return jd.db.Exec(query, args...)
}
func (jd *jsDB) Insert(table string, data any) *ExecResult {
if jd.checkSafe() != nil {
return &ExecResult{Error: errSafeMode}
}
return jd.db.Insert(table, data)
}
func (jd *jsDB) Update(table string, data any, conditions string, args ...any) *ExecResult {
if jd.checkSafe() != nil {
return &ExecResult{Error: errSafeMode}
}
return jd.db.Update(table, data, conditions, args...)
}
func (jd *jsDB) Delete(table string, conditions string, args ...any) *ExecResult {
if jd.checkSafe() != nil {
return &ExecResult{Error: errSafeMode}
}
return jd.db.Delete(table, conditions, args...)
}
func (jd *jsDB) Replace(table string, data any) *ExecResult {
if jd.checkSafe() != nil {
return &ExecResult{Error: errSafeMode}
}
return jd.db.Replace(table, data)
}
// Metadata
func (jd *jsDB) InKeys(numArgs int) string {
return jd.db.InKeys(numArgs)
}
func (jd *jsDB) Quote(text string) string {
return jd.db.Quote(text)
}

BIN
test_fts.db-shm Normal file

Binary file not shown.

BIN
test_fts.db-wal Normal file

Binary file not shown.

BIN
test_schema.db-shm Normal file

Binary file not shown.

BIN
test_schema.db-wal Normal file

Binary file not shown.