redis/js_export.go

123 lines
2.6 KiB
Go
Raw Normal View History

package redis
import (
"context"
"errors"
"strings"
"apigo.cc/go/id"
"apigo.cc/go/jsmod"
"apigo.cc/go/log"
)
func init() {
jsmod.Register("redis", map[string]any{
// 入口:支持别名获取,不传则默认 "default"
"Get": jsGet,
// 默认快捷调用 (面向 "default" 实例)
"Do": jsDo,
"MakeID": jsMakeID,
})
}
func jsGet(ctx context.Context, name *string) (*jsRedis, error) {
target := "default"
if name != nil {
target = *name
}
rd := GetRedis(target, nil)
if rd.Error != nil {
return nil, jsmod.MakeError(rd.Error)
}
return &jsRedis{rd: rd, ctx: ctx}, nil
}
func jsDo(ctx context.Context, cmd string, args ...any) (*Result, error) {
jr := getDefaultRedisForJS(ctx)
if jr.rd.Error != nil {
return nil, jsmod.MakeError(jr.rd.Error)
}
res := jr.Do(cmd, args...)
if res != nil && res.Error != nil {
return res, jsmod.MakeError(res.Error)
}
return res, nil
}
func jsMakeID(ctx context.Context, size int, forDB *string) string {
jr := getDefaultRedisForJS(ctx)
if jr.rd.Error != nil {
return id.MakeID(size)
}
return jr.MakeID(size, forDB)
}
type jsRedis struct {
rd *Redis
ctx context.Context
idMaker *id.IDMaker
}
var defaultRedisForJS *jsRedis
func getDefaultRedisForJS(ctx context.Context) *jsRedis {
if defaultRedisForJS == nil {
var logger *log.Logger
if l := jsmod.Get(ctx, "Logger"); l != nil {
logger = l.(*log.Logger)
}
defaultRedisForJS = &jsRedis{rd: GetRedis("default", logger), ctx: ctx}
}
return defaultRedisForJS
}
var errSafeMode = errors.New("redis operation is restricted in safe mode")
// 危险指令集,安全模式下禁止执行
var dangerousCommands = map[string]bool{
"FLUSHDB": true,
"FLUSHALL": true,
}
func (jr *jsRedis) checkSafe(cmd string) error {
if jsmod.IsSafeMode(jr.ctx) {
if dangerousCommands[strings.ToUpper(cmd)] {
return errSafeMode
}
}
return nil
}
func (jr *jsRedis) Do(cmd string, args ...any) *Result {
if err := jr.checkSafe(cmd); err != nil {
return &Result{Error: jsmod.MakeError(err)}
}
res := jr.rd.Do(cmd, args...)
if res != nil && res.Error != nil {
resCopy := *res
resCopy.Error = jsmod.MakeError(res.Error)
return &resCopy
}
return res
}
// ID Generation
func (jr *jsRedis) MakeID(size int, forDB *string) string {
if jr.idMaker == nil {
jr.idMaker = NewIDMaker(jr.rd)
}
dbType := ""
if forDB != nil {
dbType = strings.ToLower(*forDB)
}
switch dbType {
case "mysql":
return jr.idMaker.GetForMysql(size)
case "postgres", "pg", "pgsql":
return jr.idMaker.GetForPostgreSQL(size)
default:
return jr.idMaker.Get(size)
}
}