我们可能会遇到需要运行的某些命令在godis中不存在的情况,这个时候我们可以使用其原生的方式运行命令,为了方便使用,封装了一个方法,用于简化这个过程。需要注意的是,执行命令的返回结果返回的是interface{},需要对其进行解析成可读的实体结构。
传递的参数logger是用来打印日志的:
// RunRedisCmd 运行redis命令
func RunRedisCmd(redis *godis.Redis, logger *log.Logger, cmd string, args ...string) (interface{}, error) {
byteArr := make([][]byte, len(args))
cmdStr := cmd
for i, str := range args {
byteArr[i] = []byte(str)
cmdStr += fmt.Sprint(" ", str)
}
if logger != nil {
logger.Println(cmdStr)
}
err := redis.SendByStr(cmd, byteArr...)
if err != nil {
if logger != nil {
logger.Println(err)
}
return nil, err
}
// 一定要receive
r, err := redis.Receive()
if err != nil {
if logger != nil {
logger.Println(err)
}
return r, err
}
if logger != nil {
if r != nil {
switch r.(type) {
case []byte:
logger.Println(string(r.([]byte)))
case int64:
logger.Println(r.(int64))
case []interface{}:
logger.Println("\n", SprintArrAsRedis(0, r.([]interface{})))
default:
logger.Println(r)
}
} else {
logger.Println(r)
}
}
return r, nil
}
// SprintArrAsRedis 打印redis返回的数组格式的数据,以redis的方式
//
// 127.0.0.1:16379> xrange testStream - +
//
// 1) 1) "1650986325904-0"
// 2) 1) "msg"
// 2) "hello"
func SprintArrAsRedis(spaceSize int, result []interface{}) string {
str := ""
for i, data := range result {
if i != 0 {
for j := 0; j < spaceSize; j++ {
str += " "
}
}
str += fmt.Sprintf("%d) ", i+1)
markArr := false
switch data.(type) {
case []byte:
str += string(data.([]byte))
case []interface{}:
str += SprintArrAsRedis(spaceSize+3, data.([]interface{}))
markArr = true
default:
str += fmt.Sprint(data)
}
if !markArr {
str += "\n"
}
}
return str
}
单元测试:
package test
import (
"github.com/piaohao/godis"
"log"
"momo/utils"
"os"
"testing"
"time"
)
func Test_RunRedisCmd(t *testing.T) {
option := &godis.Option{
Host: "localhost",
Port: 16379,
Db: 0,
ConnectionTimeout: 10 * time.Second,
SoTimeout: 10 * time.Second,
}
pool := godis.NewPool(&godis.PoolConfig{}, option)
redis, _ := pool.GetResource()
logger := log.New(os.Stdout, "redis log ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
rsl, err := utils.RunRedisCmd(redis, logger, "set", "userage", "1")
if err != nil || rsl == nil || string(rsl.([]byte)) != "OK" {
t.Error("fail set", err)
}
rsl, err = utils.RunRedisCmd(redis, logger, "incr", "userage")
if err != nil || rsl == nil || rsl.(int64) != 2 {
t.Error("fail incr", err)
}
rsl, err = utils.RunRedisCmd(redis, logger, "del", "userage")
if err != nil || rsl == nil || rsl.(int64) != 1 {
t.Error("fail del", err)
}
}