feat: register context-aware db capabilities to jsmod
This commit is contained in:
parent
f8ede4fdc7
commit
47ab856f3c
@ -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
BIN
auto_detect.db-shm
Normal file
Binary file not shown.
BIN
auto_detect.db-wal
Normal file
BIN
auto_detect.db-wal
Normal file
Binary file not shown.
1
go.mod
1
go.mod
@ -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
2
go.sum
@ -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
BIN
id_test.db-shm
Normal file
Binary file not shown.
BIN
id_test.db-wal
Normal file
BIN
id_test.db-wal
Normal file
Binary file not shown.
84
js_export.go
Normal file
84
js_export.go
Normal 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
BIN
test_fts.db-shm
Normal file
Binary file not shown.
BIN
test_fts.db-wal
Normal file
BIN
test_fts.db-wal
Normal file
Binary file not shown.
BIN
test_schema.db-shm
Normal file
BIN
test_schema.db-shm
Normal file
Binary file not shown.
BIN
test_schema.db-wal
Normal file
BIN
test_schema.db-wal
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user